swiftwasm/swift

Compiler > 5.3.1 crashes when building Tokamak

Closed this issue · 7 comments

Using snapshot toolchains newer than 5.3.1 result in a compiler crash when building:

  • A new empty package with swift package init
  • Adding Tokamak as a dendency.
  • /Library/Developer/Toolchains/swift-wasm-DEVELOPMENT-SNAPSHOT-2021-03-10-a.xctoolchain/usr/bin/swift build --triple wasm32-unknown-wasi -c release

Results in crash:

Incorrect number of arguments passed to called function!
  call swiftcc void @"$s11TokamakCore17EnvironmentValuesV15foregroundColorAA0F0VSgvplACTK"(%T11TokamakCore5ColorVSg* noalias nocapture sret(%T11TokamakCore5ColorVSg) %0, %T11TokamakCore17EnvironmentValuesV* noalias nocapture dereferenceable(4) %1, i8* %2), !dbg !825
in function keypath_get
<unknown>:0: error: fatal error encountered during compilation; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project
<unknown>:0: note: Broken function found, compilation aborted!
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project and the crash backtrace.
Stack dump:
0.	Running pass 'Module Verifier' on function '@keypath_get'
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):
Incorrect number of arguments passed to called function!
  call swiftcc void @"$s11TokamakCore17EnvironmentValuesV18_defaultAppStorageAA01_G8Provider_pSgvplACTK"(%T11TokamakCore16_StorageProvider_pSg* noalias nocapture sret(%T11TokamakCore16_StorageProvider_pSg) %0, %T11TokamakCore17EnvironmentValuesV* noalias nocapture dereferenceable(4) %1, i8* %2), !dbg !1727
in function keypath_get
LLVM ERROR: Broken function found, compilation aborted!
  • Similar results with older snapshot swift-wasm-DEVELOPMENT-SNAPSHOT-2021-02-22-a
  • Works with swift-wasm-5.3.1-RELEASE toolchain
  • Works if instead of Tokamak importing only JavaScriptKit for example

I could not get llvm-symbolizer (from built toolchain) to work...

j-f1 commented

Demangled version of the symbol: key path getter for TokamakCore.EnvironmentValues._defaultAppStorage : TokamakCore._StorageProvider? : <A>TokamakCore.EnvironmentValues

Swift 5.4 and later introduce additional codegen verification passes. It's either there's a bug in codegen, which verifier uncovered, or there's something with the verifier...

Building for macOS with swift-5.4-DEVELOPMENT-SNAPSHOT-2021-03-10-a.xctoolchain does work.

Does anyone know by any chance if this is still an issue with the latest 5.4 snapshots?

Unfortunately still is.

Clone latest Tokamak.

$ /Library/Developer/Toolchains/swift-wasm-5.4-SNAPSHOT-2021-04-25-a.xctoolchain/usr/bin/swift build -c release --product TokamakDemo --triple wasm32-unknown-wasi
[...]
Incorrect number of arguments passed to called function!
  call swiftcc void @"$s11TokamakCore17EnvironmentValuesV15foregroundColorAA0F0VSgvplACTK"(%T11TokamakCore5ColorVSg* noalias nocapture sret %0, %T11TokamakCore17EnvironmentValuesV* noalias nocapture dereferenceable(4) %1, i8* %2), !dbg !836
in function keypath_get
<unknown>:0: error: fatal error encountered during compilation; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project
<unknown>:0: note: Broken function found, compilation aborted!
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project and the crash backtrace.
Stack dump:
0.	Running pass 'Module Verifier' on function '@keypath_get'
Incorrect number of arguments passed to called function!
  call swiftcc void @"$s11TokamakCore17EnvironmentValuesV18_defaultAppStorageAA01_G8Provider_pSgvplACTK"(%T11TokamakCore16_StorageProvider_pSg* noalias nocapture sret %0, %T11TokamakCore17EnvironmentValuesV* noalias nocapture dereferenceable(4) %1, i8* %2), !dbg !1861
in function keypath_get
LLVM ERROR: Broken function found, compilation aborted!

I tried different optimization levels + WMO on or off, with no success. There's also a --disable-llvm-verify that Swift frontend is supposed to honor but I wasn't successful in passing it to the frontend.

Builiding for macOS /Library/Developer/Toolchains/swift-wasm-5.4-SNAPSHOT-2021-04-25-a.xctoolchain/usr/bin/swift build -c release --product TokamakDemo works.

ahti commented

I've just played around with this issue a little. As far as I can tell the issue is with EnvironmentValues keypaths referenced in property wrapper parameters, specifically @Environment(...). Commenting those out allows the compiler to move on and throw similar errors in other files/other errors resulting from having commented something out. Commenting out "normal" uses of the same keypaths (not in arguments to property wrappers) was not necessary.

Replacing uses of @Environment with a duplicate with changed name still reproduces the issue. If I, however, duplicate EnvironmentValues as well (just copy pasting the implementation), then use that in my duplicate @Environment, the issue no longer happens. Creating another environment key and accessor (all inside the TokamakCore target, either for a new struct or one of the existing ones found in the environment) and dropping that in somewhere also didn't seem to trigger the issue 🤔

I remember vaguely that SwiftWASM always passes error pointers no matter whether something throws, which sounds like it could be related (I don't yet know whether the incorrect number mentioned in the error message means the last i8* %2 is superfluous, or whether a parameter is missing, but could that be an error pointer?). I don't suppose SE-0310 would have any relevance since it's only in 5.5 and above?

For reference these tests were done one the wasm-5.4-SNAPSHOT-2021-07-25-a snapshot.

ahti commented

I don't yet know whether the incorrect number mentioned in the error message means the last i8* %2 is superfluous, or whether a parameter is missing

I added some debug logging, and found that the functions expect four arguments, while only three are given. So whatever is producing the IR to call them is failing to pass a fourth parameter. The type of the missing parameter seems to be a %swift.type*.