It looks like $sp32 read by stacksave is replaced with a virtual reg by wasm-replace-phys-regs, but it results in violating the domination principle for virtual registers.
Result of `-stop-before=wasm-replace-phys-regs`
```
bb.0.entry:
successors: %bb.1(0x00000000), %bb.2(0x80000000)
liveins: $arguments
%3:i32 = ARGUMENT_i32 1, implicit $arguments
dead %2:i32 = ARGUMENT_i32 0, implicit $arguments
%4:i32 = CONST_I32 1, implicit-def dead $arguments
%5:i32 = AND_I32 %3, %4, implicit-def dead $arguments
BR_UNLESS %bb.2, %5, implicit-def $arguments
bb.1..thread51:
%10:i32 = COPY_I32 $sp32, implicit-def $arguments
$sp32 = COPY_I32 %10, implicit-def $arguments
UNREACHABLE implicit-def dead $arguments
bb.2..lr.ph.i30:
successors: %bb.3(0x00000000), %bb.2(0x80000000)
BR_UNLESS %bb.2, %5, implicit-def dead $arguments
bb.3:
%10:i32 = CONST_I32 0, implicit-def dead $arguments
$sp32 = COPY_I32 %10, implicit-def $arguments
UNREACHABLE implicit-def dead $arguments
```
I'm not sure the stacksave / stackrestore are supported on WebAssembly target or not 🤷 But it seems that it somehow succeeds with LLVM 14: https://godbolt.org/z/7Mx45GqK6
LLVM version: llvmorg-16.0.0
Minimum reproducible code:
Stack trace
```console PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. Stack dump: 0. Program arguments: /home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc Swift.x.wasm32-unknown-wasi.reduced.ll 1. Running pass 'Function Pass Manager' on module 'Swift.x.wasm32-unknown-wasi.reduced.ll'. 2. Running pass 'Live Interval Analysis' on function '@x' #0 0x0000000001e019d3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x1e019d3) #1 0x0000000001dff6fe llvm::sys::RunSignalHandlers() (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x1dff6fe) #2 0x0000000001e01e9f SignalHandler(int) Signals.cpp:0:0 #3 0x00007f6a7e2c3420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420) #4 0x00007f6a7dd5600b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1 #5 0x00007f6a7dd35859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7 #6 0x0000000001d7e6b0 llvm::report_fatal_error(llvm::Twine const&, bool) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x1d7e6b0) #7 0x000000000127f7a6 (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x127f7a6) #8 0x00000000011004aa llvm::LiveRangeCalc::findReachingDefs(llvm::LiveRange&, llvm::MachineBasicBlock&, llvm::SlotIndex, unsigned int, llvm::ArrayRefIt looks like
$sp32
read bystacksave
is replaced with a virtual reg bywasm-replace-phys-regs
, but it results in violating the domination principle for virtual registers.Result of `-stop-before=wasm-replace-phys-regs`
``` bb.0.entry: successors: %bb.1(0x00000000), %bb.2(0x80000000) liveins: $arguments %3:i32 = ARGUMENT_i32 1, implicit $arguments dead %2:i32 = ARGUMENT_i32 0, implicit $arguments %4:i32 = CONST_I32 1, implicit-def dead $arguments %5:i32 = AND_I32 %3, %4, implicit-def dead $arguments BR_UNLESS %bb.2, %5, implicit-def $arguments bb.1..thread51: %10:i32 = COPY_I32 $sp32, implicit-def $arguments $sp32 = COPY_I32 %10, implicit-def $arguments UNREACHABLE implicit-def dead $arguments bb.2..lr.ph.i30: successors: %bb.3(0x00000000), %bb.2(0x80000000) BR_UNLESS %bb.2, %5, implicit-def dead $arguments bb.3: %10:i32 = CONST_I32 0, implicit-def dead $arguments $sp32 = COPY_I32 %10, implicit-def $arguments UNREACHABLE implicit-def dead $arguments ```I'm not sure the
stacksave
/stackrestore
are supported on WebAssembly target or not 🤷 But it seems that it somehow succeeds with LLVM 14: https://godbolt.org/z/7Mx45GqK6