I created a freshly built compiler with the current trunk (55189bae8e
) and tried to compile IR with a stub file a.swift
, with the contents...
import Swift
// nothing yet
Then I tried to compile it using much the same command line as the test test/embedded/avr/testStdlibFunctioning.swift
but changing the parameter -typecheck
to -emit-ir
so that IRGen is activated. It traps in IRGen due to LLVM trapping on an invalid cast assertion...
carl@LT1152 bin % ./swiftc -emit-ir -target avr-none-none-elf -enable-experimental-feature Embedded -wmo a.swift
<unknown>:0: warning: no target microcontroller specified on command line, cannot link standard libraries, please pass -mmcu=<mcu name>
Assertion failed: (castIsValid(op, S, Ty) && "Invalid cast!"), function Create, file Instructions.cpp, line 2974.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0. Program arguments: /Users/carl/Documents/Code/swift/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/bin/swift-frontend -frontend -emit-ir a.swift -target avr-none-none-elf -disable-objc-interop -color-diagnostics -enable-experimental-feature Embedded -empty-abi-descriptor -resource-dir /Users/carl/Documents/Code/swift/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/lib/swift -module-name a -in-process-plugin-server-path /Users/carl/Documents/Code/swift/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/lib/swift/host/libSwiftInProcPluginServer.dylib -plugin-path /Users/carl/Documents/Code/swift/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/lib/swift/host/plugins -plugin-path /Users/carl/Documents/Code/swift/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/local/lib/swift/host/plugins -o -
1. Swift version 6.2-dev (LLVM 9f6c3d784782c34, Swift 55189bae8e55169)
2. Compiling with effective version 5.10
3. While evaluating request IRGenRequest(IR Generation for module a)
4. While emitting IR SIL function "@swift_once".
for <<debugloc at "<compiler-generated>":0:0>>Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 swift-frontend 0x0000000106932f90 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1 swift-frontend 0x00000001069314b4 llvm::sys::RunSignalHandlers() + 112
2 swift-frontend 0x0000000106933608 SignalHandler(int) + 332
3 libsystem_platform.dylib 0x000000019e0db584 _sigtramp + 56
4 libsystem_pthread.dylib 0x000000019e0aac20 pthread_kill + 288
5 libsystem_c.dylib 0x000000019dfb7a20 abort + 180
6 libsystem_c.dylib 0x000000019dfb6d10 err + 0
7 swift-frontend 0x000000010850701c llvm::CastInst::CreateZExtOrBitCast(llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::InsertPosition) (.cold.1) + 0
8 swift-frontend 0x0000000106760edc llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::InsertPosition) + 772
9 swift-frontend 0x0000000100ae3474 llvm::IRBuilderBase::CreateBitCast(llvm::Value*, llvm::Type*, llvm::Twine const&) + 124
10 swift-frontend 0x0000000100affc2c swift::irgen::IRGenFunction::coerceValue(llvm::Value*, llvm::Type*, llvm::DataLayout const&) + 180
11 swift-frontend 0x0000000100b0898c swift::irgen::emitForeignParameter(swift::irgen::IRGenFunction&, swift::irgen::Explosion&, swift::irgen::ForeignFunctionInfo, unsigned int, swift::SILType, swift::irgen::LoadableTypeInfo const&, swift::irgen::Explosion&, bool) + 764
12 swift-frontend 0x0000000100ce2890 (anonymous namespace)::IRGenSILFunction::emitSILFunction() + 4072
13 swift-frontend 0x0000000100ce1324 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 1816
14 swift-frontend 0x0000000100b61a5c swift::irgen::IRGenerator::emitGlobalTopLevel(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>> const&) + 752
15 swift-frontend 0x0000000100c786b0 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 2212
16 swift-frontend 0x0000000100ce0784 swift::GeneratedModule swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)17>::callDerived<0ul>(swift::Evaluator&, std::__1::integer_sequence<unsigned long, 0ul>) const + 176
17 swift-frontend 0x0000000100c818fc swift::IRGenRequest::OutputType swift::Evaluator::getResultUncached<swift::IRGenRequest, swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(swift::Evaluator&, swift::IRGenRequest)::'lambda'()>(swift::IRGenRequest const&, swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(swift::Evaluator&, swift::IRGenRequest)::'lambda'()) + 196
18 swift-frontend 0x0000000100c79768 swift::performIRGeneration(swift::ModuleDecl*, swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, llvm::GlobalVariable**) + 1420
19 swift-frontend 0x00000001007254d0 generateIR(swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, llvm::GlobalVariable*&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>) + 272
20 swift-frontend 0x0000000100721b04 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 1336
21 swift-frontend 0x00000001007212b8 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 768
22 swift-frontend 0x000000010072db3c withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
23 swift-frontend 0x0000000100722c08 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 700
24 swift-frontend 0x0000000100722464 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2180
25 swift-frontend 0x00000001004d7384 swift::mainEntry(int, char const**) + 3104
26 dyld 0x000000019dd220e0 start + 2360
I expected errors like this to occur when we started to emit IR because I had a lot of similar issues over the years with my own forks. It's always issues related to address space on AVR.
Running in a debug build of swift, I found the assertions occurs in this IRGen...
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = hit program assert
frame #0: 0x000000019e072a60 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x000000019e0aac20 libsystem_pthread.dylib`pthread_kill + 288
frame #2: 0x000000019dfb7a20 libsystem_c.dylib`abort + 180
frame #3: 0x000000019dfb6d10 libsystem_c.dylib`__assert_rtn + 284
frame #4: 0x000000010a3f0db0 swift-frontend`llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::InsertPosition) (.cold.1) at Instructions.cpp:2974:3 [opt]
frame #5: 0x0000000108d5ac70 swift-frontend`llvm::CastInst::Create(op=BitCast, S=0x000060000283bb28, Ty=0x00000001261a4800, Name=0x000000016fdf2630, InsertBefore=<unavailable>) at Instructions.cpp:2974:3 [opt]
frame #6: 0x0000000100a85adc swift-frontend`llvm::IRBuilderBase::CreateCast(this=0x000000016fdf3c10, Op=BitCast, V=0x000060000283bb28, DestTy=0x00000001261a4800, Name=0x000000016fdf2a28) at IRBuilder.h:2172:19
frame #7: 0x0000000100a85988 swift-frontend`llvm::IRBuilderBase::CreateBitCast(this=0x000000016fdf3c10, V=0x000060000283bb28, DestTy=0x00000001261a4800, Name=0x000000016fdf2a28) at IRBuilder.h:2134:12
* frame #8: 0x0000000100ace8fc swift-frontend`swift::irgen::IRGenFunction::coerceValue(this=0x000000016fdf3c08, value=0x000060000283bb28, toTy=0x00000001261a4800, DL=0x000000016fdf4c90) at GenCall.cpp:5447:22
frame #9: 0x0000000100adb010 swift-frontend`emitDirectForeignParameter(IGF=0x000000016fdf3c08, in=0x000000016fdf39c0, AI=0x000000016fdf3070, out=0x000000016fdf3438, paramType=SILType @ 0x000000016fdf2f90, paramTI=0x0000000122971bb0) at GenCall.cpp:4705:21
frame #10: 0x0000000100adac38 swift-frontend`swift::irgen::emitForeignParameter(IGF=0x000000016fdf3c08, params=0x000000016fdf39c0, foreignInfo=ForeignFunctionInfo @ 0x000000016fdf30d0, foreignParamIndex=1, paramTy=SILType @ 0x000000016fdf3110, paramTI=0x0000000122971bb0, paramExplosion=0x000000016fdf3438, isOutlined=false) at GenCall.cpp:4772:5
frame #11: 0x000000010102656c swift-frontend`emitEntryPointArgumentsCOrObjC(IGF=0x000000016fdf3c08, entry=0x00000001261a1670, params=0x000000016fdf39c0, funcTy=swift::CanSILFunctionType @ 0x000000016fdf3428) at IRGenSIL.cpp:2444:5
frame #12: 0x000000010101ae1c swift-frontend`(anonymous namespace)::IRGenSILFunction::emitSILFunction(this=0x000000016fdf3c08) at IRGenSIL.cpp:2676:5
frame #13: 0x000000010101a308 swift-frontend`swift::irgen::IRGenModule::emitSILFunction(this=0x000000016fdf4c68, f=0x00000001261a1420) at IRGenSIL.cpp:2573:30
frame #14: 0x0000000100c83cd0 swift-frontend`swift::irgen::IRGenerator::emitGlobalTopLevel(this=0x000000016fdf7078, linkerDirectives=size=0) at GenDecl.cpp:1222:10
frame #15: 0x0000000100f187d8 swift-frontend`swift::IRGenRequest::evaluate(this=0x000000016fdf7c50, evaluator=0x0000000126008880, desc=IRGenDescriptor @ 0x000000016fdf78c0) const at IRGen.cpp:1259:11
frame #16: 0x0000000101018e54 swift-frontend`swift::GeneratedModule swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)17>::callDerived<0ul>(this=0x000000016fdf7c50, evaluator=0x0000000126008880, (null)=std::__1::index_sequence<0UL> @ 0x000000016fdf78b7) const at SimpleRequest.h:287:24
frame #17: 0x0000000101018d60 swift-frontend`swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)17>::evaluateRequest(request=0x000000016fdf7c50, evaluator=0x0000000126008880) at SimpleRequest.h:311:20
frame #18: 0x0000000100f45c80 swift-frontend`swift::IRGenRequest::OutputType swift::Evaluator::getResultUncached<swift::IRGenRequest, swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(swift::Evaluator&, swift::IRGenRequest)::'lambda'()>(this=0x0000000126008880, request=0x000000016fdf7c50, defaultValueFn=(unnamed class) @ 0x000000016fdf7a6f) at Evaluator.h:347:19
frame #19: 0x0000000100f45b7c swift-frontend`swift::IRGenRequest::OutputType swift::Evaluator::operator()<swift::IRGenRequest, swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(swift::Evaluator&, swift::IRGenRequest)::'lambda'(), (void*)0>(this=0x0000000126008880, request=0x000000016fdf7c50, defaultValueFn=(unnamed class) @ 0x000000016fdf7ac7) at Evaluator.h:235:12
frame #20: 0x0000000100f1a808 swift-frontend`swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(eval=0x0000000126008880, req=IRGenRequest @ 0x000000016fdf7c50) at Evaluator.h:448:10
frame #21: 0x0000000100f19c48 swift-frontend`swift::performIRGeneration(M=0x00000001260cea00, Opts=0x00000001248376e0, TBDOpts=0x0000000124837bc8, SILMod=nullptr, ModuleName=(Data = "-", Length = 1), PSPs=0x000000016fdf8950, parallelOutputFilenames=(Data = "-", Length = 1), outModuleHash=0x000000016fdf8158) at IRGen.cpp:1673:10
frame #22: 0x00000001003d28c4 swift-frontend`generateIR(IRGenOpts=0x00000001248376e0, TBDOpts=0x0000000124837bc8, SM=nullptr, PSPs=0x000000016fdf8950, OutputFilename=(Data = "-", Length = 1), MSF=swift::ModuleOrSourceFile @ 0x000000016fdf7fd0, HashGlobal=0x000000016fdf8158, parallelOutputFilenames=(Data = "-", Length = 1)) at FrontendTool.cpp:1426:12
frame #23: 0x00000001003cd540 swift-frontend`performCompileStepsPostSILGen(Instance=0x0000000124836400, SM=nullptr, MSF=swift::ModuleOrSourceFile @ 0x000000016fdf82b0, PSPs=0x000000016fdf8950, ReturnValue=0x000000016fdf9cfc, observer=0x0000000000000000) at FrontendTool.cpp:1782:7
frame #24: 0x00000001003cc73c swift-frontend`swift::performCompileStepsPostSema(Instance=0x0000000124836400, ReturnValue=0x000000016fdf9cfc, observer=0x0000000000000000) at FrontendTool.cpp:732:12
frame #25: 0x00000001003eefac swift-frontend`performAction(swift::CompilerInstance&, int&, swift::FrontendObserver*)::$_27::operator()(this=0x000000016fdf9760, Instance=0x0000000124836400) const at FrontendTool.cpp:1296:18
frame #26: 0x00000001003eef10 swift-frontend`bool llvm::function_ref<bool (swift::CompilerInstance&)>::callback_fn<performAction(swift::CompilerInstance&, int&, swift::FrontendObserver*)::$_27>(callable=6171891552, params=0x0000000124836400) at STLFunctionalExtras.h:45:12
frame #27: 0x00000001003ee2a8 swift-frontend`llvm::function_ref<bool (swift::CompilerInstance&)>::operator()(this=0x000000016fdf9698, params=0x0000000124836400) const at STLFunctionalExtras.h:68:12
frame #28: 0x00000001003ed180 swift-frontend`withSemanticAnalysis(Instance=0x0000000124836400, observer=0x0000000000000000, cont=function_ref<bool (swift::CompilerInstance &)> @ 0x000000016fdf9698, runDespiteErrors=false) at FrontendTool.cpp:1155:10
frame #29: 0x00000001003e7888 swift-frontend`performAction(Instance=0x0000000124836400, ReturnValue=0x000000016fdf9cfc, observer=0x0000000000000000) at FrontendTool.cpp:1292:12
frame #30: 0x00000001003cebac swift-frontend`performCompile(Instance=0x0000000124836400, ReturnValue=0x000000016fdf9cfc, observer=0x0000000000000000) at FrontendTool.cpp:1368:19
frame #31: 0x00000001003cdfe4 swift-frontend`swift::performFrontend(Args=ArrayRef<const char *> @ 0x000000016fdf9ef0, Argv0="/Users/carl/Documents/Code/swift/build/Ninja-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-arm64/bin/swift-frontend", MainAddr=0x000000010003720c, observer=0x0000000000000000) at FrontendTool.cpp:2078:19
frame #32: 0x0000000100038830 swift-frontend`run_driver(ExecName=(Data = "swift-frontend", Length = 14), argv=ArrayRef<const char *> @ 0x000000016fdfc720, originalArgv=const llvm::ArrayRef<const char *> @ 0x000000016fdfc710) at driver.cpp:296:14
frame #33: 0x00000001000376d0 swift-frontend`swift::mainEntry(argc_=8, argv_=0x000000016fdff388) at driver.cpp:530:10
frame #34: 0x0000000100036e54 swift-frontend`main(argc_=8, argv_=0x000000016fdff388) at driver.cpp:20:10
frame #35: 0x000000019dd220e0 dyld`start + 2360
The failing cast is in IRGenFunction::coerceValue
...
(lldb) fr s 8
frame #8: 0x0000000100ace8fc swift-frontend`swift::irgen::IRGenFunction::coerceValue(this=0x000000016fdf3c08, value=0x000060000283bb28, toTy=0x00000001261a4800, DL=0x000000016fdf4c90) at GenCall.cpp:5447:22
5444 // Use the pointer/pointer and pointer/int casts if we can.
5445 if (toTy->isPointerTy()) {
5446 if (fromTy->isPointerTy())
-> 5447 return Builder.CreateBitCast(value, toTy);
5448 if (fromTy == IGM.IntPtrTy)
5449 return Builder.CreateIntToPtr(value, toTy);
5450 } else if (fromTy->isPointerTy()) {
(lldb) e toTy->dump()
ptr
(lldb) e value->dump()
ptr addrspace(1) %1
LLVM refuses to coerce a ptr addrspace(1) %1
Value to ptr
type.
Moving up to frame 13 emitSILFunction
to get a bit of context, the code being called is...
frame #13: 0x000000010101a308 swift-frontend`swift::irgen::IRGenModule::emitSILFunction(this=0x000000016fdf4c68, f=0x00000001261a1420) at IRGenSIL.cpp:2573:30
2570 noteUseOfMetadataByCXXInterop(IRGen, f, TypeExpansionContext(*f));
2571
2572 PrettyStackTraceSILFunction stackTrace("emitting IR", f);
-> 2573 IRGenSILFunction(*this, f).emitSILFunction();
2574 }
2575
2576 void IRGenSILFunction::emitSILFunction() {
And the SIL function in question is something like a thunk related to swift_once
...
(lldb) e f->dump()
// swift_once
sil [thunk] @swift_once : $@convention(c) (UnsafeMutablePointer<Int>, @convention(c) (UnsafeMutableRawPointer) -> (), UnsafeMutableRawPointer) -> () {
[%0: read v**.c*.v**, write v**.c*.v**, copy v**.c*.v**, destroy v**.c*.v**]
[%2: read v**.c*.v**, write v**.c*.v**, copy v**.c*.v**, destroy v**.c*.v**]
[global: read,write,copy,destroy,allocate,deinit_barrier]
// %0 // user: %4
// %1 // user: %4
// %2 // user: %4
bb0(%0 : $UnsafeMutablePointer<Int>, %1 : $@convention(c) (UnsafeMutableRawPointer) -> (), %2 : $UnsafeMutableRawPointer):
// function_ref swift_once(predicate:fn:context:)
%3 = function_ref @$es10swift_once9predicate2fn7contextySpySiG_ySvXCSvtF : $@convention(thin) (UnsafeMutablePointer<Int>, @convention(c) (UnsafeMutableRawPointer) -> (), UnsafeMutableRawPointer) -> () // user: %4
%4 = apply %3(%0, %1, %2) : $@convention(thin) (UnsafeMutablePointer<Int>, @convention(c) (UnsafeMutableRawPointer) -> (), UnsafeMutableRawPointer) -> () // user: %5
return %4 // id: %5
} // end sil function 'swift_once'
For reference, I assume (although I haven't made 100% sure) that this comes from this swift in the embedded swift runtime (in stdlib/public/core/EmbeddedRuntime.swift
)...
// Once
@_cdecl("swift_once")
public func swift_once(predicate: UnsafeMutablePointer<Int>, fn: (@convention(c) (UnsafeMutableRawPointer)->()), context: UnsafeMutableRawPointer) {
let checkedLoadAcquire = { predicate in
let value = loadAcquire(predicate)
assert(value == -1 || value == 0 || value == 1)
return value
}
if checkedLoadAcquire(predicate) < 0 { return }
let won = compareExchangeRelaxed(predicate, expectedOldValue: 0, desiredNewValue: 1)
if won {
fn(context)
storeRelease(predicate, newValue: -1)
return
}
// TODO: This should really use an OS provided lock
while checkedLoadAcquire(predicate) >= 0 {
// spin
}
}
I feel like this is going to need me to write a compiler patch happy to do so... if people can give me some pointers what's the best approach, what's most likely to get PR approval, what's the nicest/most friendly way to do this? If no one has input I'll just poke through the code then "hit something with a hammer until it works".
All help gratefully received!
Carl