<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62235>62235</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
WebAssembly: `stacksave` leads machine code verification failure after `wasm-replace-phys-regs`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:WebAssembly,
llvm:codegen
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
kateinoigakukun
</td>
</tr>
</table>
<pre>
LLVM version: [llvmorg-16.0.0](https://github.com/llvm/llvm-project/releases/tag/llvmorg-16.0.0)
Minimum reproducible code:
```llvm
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
target triple = "wasm32-unknown-wasi"
define weak_odr swiftcc { i32, i8 } @x(i1 %0) {
entry:
br i1 %0, label %.thread51, label %.lr.ph.i30
.thread51: ; preds = %entry
%spsave253 = tail call i8* @llvm.stacksave()
br label %.loopexit
.lr.ph.i30: ; preds = %.lr.ph.i30, %entry
br i1 %0, label %.loopexit, label %.lr.ph.i30
.loopexit: ; preds = %.lr.ph.i30, %.thread51
%spsave254.ph = phi i8* [ %spsave253, %.thread51 ], [ null, %.lr.ph.i30 ]
tail call void @llvm.stackrestore(i8* %spsave254.ph)
unreachable
}
; Function Attrs: nocallback nofree nosync nounwind willreturn
declare i8* @llvm.stacksave() #0
; Function Attrs: nocallback nofree nosync nounwind willreturn
declare void @llvm.stackrestore(i8*) #0
attributes #0 = { nocallback nofree nosync nounwind willreturn }
```
```
llc test.ll -stop-after wasm-replace-phys-regs -o - -verify-machineinstrs
# Machine code for function x: NoPHIs, TracksLiveness, TiedOpsRewritten
Function Live Ins: $arguments
bb.0.entry:
successors: %bb.1(0x00000000), %bb.2(0x80000000); %bb.1(0.00%), %bb.2(100.00%)
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:i32, %4:i32, implicit-def dead $arguments
BR_UNLESS %bb.2, %5:i32, implicit-def $arguments
bb.1..thread51:
; predecessors: %bb.0
%10:i32 = COPY_I32 %11:i32, implicit-def $arguments
%11:i32 = COPY_I32 %10:i32, implicit-def $arguments
UNREACHABLE implicit-def dead $arguments
bb.2..lr.ph.i30:
; predecessors: %bb.2, %bb.0
successors: %bb.3(0x00000000), %bb.2(0x80000000); %bb.3(0.00%), %bb.2(100.00%)
BR_UNLESS %bb.2, %5:i32, implicit-def dead $arguments
bb.3:
; predecessors: %bb.2
%10:i32 = CONST_I32 0, implicit-def dead $arguments
%11:i32 = COPY_I32 %10:i32, implicit-def $arguments
UNREACHABLE implicit-def dead $arguments
# End machine code for function x.
*** Bad machine code: Virtual register defs don't dominate all uses. ***
- function: x
- v. register: %11
LLVM ERROR: Found 1 machine code errors.
```
<details>
<summary>Stack trace</summary>
```
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::ArrayRef<llvm::SlotIndex>) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x11004aa)
#9 0x00000000010ff7f7 llvm::LiveRangeCalc::extend(llvm::LiveRange&, llvm::SlotIndex, unsigned int, llvm::ArrayRef<llvm::SlotIndex>) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x10ff7f7)
#10 0x000000000110321a llvm::LiveIntervalCalc::extendToUses(llvm::LiveRange&, llvm::Register, llvm::LaneBitmask, llvm::LiveInterval*) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x110321a)
#11 0x0000000001102ec0 llvm::LiveIntervalCalc::calculate(llvm::LiveInterval&, bool) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x1102ec0)
#12 0x00000000010ead22 llvm::LiveIntervals::computeVirtRegInterval(llvm::LiveInterval&) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x10ead22)
#13 0x00000000010e9824 llvm::LiveIntervals::computeVirtRegs() (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x10e9824)
#14 0x00000000010e95f2 llvm::LiveIntervals::runOnMachineFunction(llvm::MachineFunction&) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x10e95f2)
#15 0x00000000011a4641 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x11a4641)
#16 0x000000000165c868 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x165c868)
#17 0x0000000001664f41 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x1664f41)
#18 0x000000000165d034 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x165d034)
#19 0x00000000006e3a7d compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#20 0x00000000006e144d main (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x6e144d)
#21 0x00007f6a7dd37083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#22 0x00000000006e07ae _start (/home/katei/ghq/work.katei.dev/swiftwasm-source/host-build/Ninja-ReleaseAssert/llvm-linux-x86_64/bin/llc+0x6e07ae)
```
</details>
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.
<details>
<summary>Result of `-stop-before=wasm-replace-phys-regs`</summary>
```
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
```
</details>
I'm not sure the `stacksave` / `stackrestore` are supported on WebAssembly target or not 🤷
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcWltz4rqT_zTKiwqXLdlAHvIAJOxJVSaTIjNna58o2W6DToTkleRczqffkmywDSQhc6bqsP-phAm6dPfv17p0u82M4SsJcIWSKUquL1hl10pfPTELXCq-Yk_VUyUvUpW_Xd3d_fkNP4M2XElEJxglUyGeN0qvBtEwCIMQJdeIjNfWlgbRCSJzROYrbtdVGmRqg8jcDW_-G5Ra_QWZRWSuQQAzYBCZW7Zq-jtSySUKr1E4qT-_cck31QZrKLXKq4ynAnCmcnAqO-PQMKx_vFLfZJlegcU5s0ywN1VZjOg1RoTAYIPoBAYlohNK_MegjEJEJ2P3OyhJ-zcfxohOhvFA-pHDePAYkfFAckQnkft1Q0mICOkptZqXArYKX5jZUDKo5JNUL3LwwgzfTag_cyi4BPwC7Gmpco3NCy9slmE0mmJOCSIzzMcYja4xisNXRMY8wogkji03phYC0uq3HS8Ypxrvhs2wYCkI9y2waw0sT6J-q9BBuQ44Dbt2tWPpBJ_4D9EpLjXkpoGf1HY1RiGSmNKwZyAJ9QMs4wJnTAjMx4hMHEDnw8BYlj25gYiMd4vCg-rYrFQJr9z2TG6BnGzzgckdIWR2gOE9YnfmnEDsbuw_IPbAytZdh2zHQbn2E8s131KdTHv-2JeC_Raf-XGyEmLbv1PrBzSqWj8-K5733ajBWKWdJxvFfbM67q2kBpatWSqgoWt03dvndIrnlcwsVxJPrNXu7MFSOcUpy56wVIUGwFKZN5lhqSr5wmWOX7gQGmyl5XbDZYJp-HjNYUT6Xvvd2j9l6pgRzFrN08qC8V31YhhNv2QGbmndHpxHT9P6qxAZtmBsIAQeGKvKASssaOzOtYGGUrAMBuX6zQw0rAweKDzAg2fQvHgbbFi25hK4NI6trg5C8be60x_ouFAaF1tyXx2x9-rhj1vjVt0P7Rxzx59BgqlbOOTfS7OAF82thYbYnXPcUHwrvX8QiZleVRuQtmdBmgZhsH9omirLwBilm6lJmgYRIuPwNWz-udVab4Q0DYjvGne66LQ7K3CNycGUKOz0NJoFf3Y0HbfYb2WK6IRT4j0-WfzXz2839z-WrsEf5XxTCp5xe3R2Dix3Ish7IsJPRSCSxJ3Zs-_3jz-Wt_vaBzkUW21HZSRdC-6vvYQWW0NT3H47TfB0sfx5f3fz-NiSPOtoOxD0wZqIgu6t1258d_TCwdro7RsP0IcELUsP_7OFGEUnG4O74w8FhV8Q9PN-cTOZ_TGZ3t2cxOWOBxL0rtLPiCDtCg8_2kz0lzYT_dJm-tVV8Rkl9CQePlkQ220Tfmnb_JuLwR3VNzLHm_eP66A_vvnBU9af5Wj6k2tbMYE1rLhx10gOhcG5koiMLM7VhktmAbtIojJgArwTV0sf7NQ2sdPrtv052Alt_BE1kZBPZm4Wi-8L1zFXlcxx1McDWittgo9uRTrLwYU5BtGbXZOpNhvmrpCbR3eBY6tZBojOEJm3XR9crg93N5PHG2yqdMMtZjitVi7bUdpiq_CX0ytuTOWTK8xkjrnMRJUDtmvAmWZmjV184E1skNZG59Wm3K3tMKjjzQetVpptcLsmPKnztdoAInOfNTqj1v-LyPxF6afANwU5PDvwLoXxEYJRlc7ATzR2kFZc5IjM77n8iw0WdTY4MQa03aIRXFavg9fxcDmMEZmnXPqeDD86mcFrcCShCjTkVQZ5IESNImpQLCopuVzhkhkXMI12IcKDa_jGJFuBRmSElcQblVcubSOjEzWRUUMjeUdbE4dY0M9M4Ilk4s1w06jbbR9ERnVeN2o2qg_s2lMyjCCMLnOKvc_pBNGJeTP1Hw-aS-u9-MOvPDJuB2n2slTGamAbRIb-hJC2jinH_6YjEZmGrw2mNgJChEY90HlRDAs4BnpRyUe-kkz8wWQuQJtdwH4GuGqze7jIvjPhssA9BC7ir31TN5sgK92WDP3vThBtBI2KIRsByWhMQrxcNmnDUtuGAsFTROa1hY25K1nVHWUd3gRGBWFtcRyTsGdv3FWT58kwDFOsGTduc8y3DK0ET7PB49-3f4-mu68koJFj16NAZB4E7tubyaF0x1Il-Wvd8OytkZX76kUHGaITH3RFrSVJ3xKajJNLzFLlkZ5mic1rNvwsr2TslHT22rC_7EYwTMPOsquP42XBLBNLf0_0dtmPl_oSkcY2uyxVSpzPcvRweu4d9fCSUTFiw_MwtralZ-y4Z2wUhjFjHee4E3bB5ApmTGR1U8FlvgB_ua-uoTA9b-3GN75qe5psdMoMz6ZCZU8HIx6Fsrcyh1fXXEn_MDWvz9TusInW7G0BBaKzY3PpzdmsjZrNHt2XPbrDohgVo4_phlcLMj-R5P84CmuG2tSD0CjcW7GURPsrdhsS7LP4Q_30z8ZP4nKxDXZ7rXdMwpTbDTNPex0dvbtnS2fAYE1Qj8Foj0ECWfgpgxkTWSWYhQP6WtTndzzX4Hro-9FCCCwn5B30TTyUqU1ZWXCp1QJWLdyPeDgT_DW8Hn66h_9yTOKv4D-raLA2v4cv3seXFJ_4V1fyu2zup20C0_PuQd85Odjh6xGQ9Lc3i4dxdHgRb8G4RK1Dw1H85wi8xtUD3g80h0k2Ho47wOcPDus2J_1_CLlG1IPcjzWHw7jo-fo9yN98Kt5f403TGcH1aHpwx3sezkPaPbsErFj21mTuLfDbTSl24M8dtMfUA92LGcMhUDbKsTuTuYCdI7M109tHeb2w5O7PbzMlLbzaBqYQ2WH267LocE9PFMc53jAuz4KZ2p4uMSTay15H4Zji5dKlp0tjmbbLxvqTMtnMVNuEuv7Td3o5Pq2lsX-boVVP9vgKRwxwrfhMGHMWtYy989QVkfnBg9fO563FQqkngwV_Auymk9iUlKBhiDWwHKdvrrUt7g5DzA1uCpc5fuF2jRl-bp9LNzOO1ze9ghlOK4u5xRpMJazBXOJnrgSzXK7849bmQTZXEpeay8y_EFIo3dXjo3cTfOUh88Lrw6pwBtbF2BQKpQHR6_ft_ehx9DHqMT5aHP0N5dGdpA_Lne2wf1b2_C2Fz99T-vy4-Lkte35B3PvFrVOLnd7Lx8qdjbXvVTLr3XVKvQlvRx8rW50m4NdKVh7a0Qrme6v4S3XJvUV6uis-N5p-4oVfKB_-G1746lF-i8hog6Wy2FS6Lljtn9mIzHdt2_dkhiFmGrCpylJpCzlWEv83pO4O2qTiDTfv4yntRaN5iC7naBKj6Qhf5Fc0v6SX7AKuouE4ugyT8JJerK_ilBVhErOMjHMKERkWl1GRjPM8TeJiNIwv-BUJCQ3j6DKKkohGQZKNIMwIHZM0Z-E4QnEIG8ZF4F_sUXp14ctyV0NCaHLhXw0z_h1MQlKWPYHMEZ10zEYuIZ4hQpooKVM5rEC65uT6Ql_5mzWtVgbFoeDGmlaR5VbAVVeWW-F7TApguemXP_3rOjyrL6yCceG8UL_m89FNeFFpcfXrRUpPyP8FAAD__6ZDsGg">