Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAssembly backend assertion failure with unreachable #68770

Closed
majaha opened this issue Oct 11, 2023 · 2 comments · Fixed by #90207 or #90366
Closed

WebAssembly backend assertion failure with unreachable #68770

majaha opened this issue Oct 11, 2023 · 2 comments · Fixed by #90207 or #90366
Labels
backend:WebAssembly crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@majaha
Copy link
Contributor

majaha commented Oct 11, 2023

This code:

target triple = "wasm32-unknown-unknown"

declare void @llvm.trap() cold noreturn nounwind
declare i32 @return_i32()
declare void @take_i32(i32)

define void @assert_fail() {
  %a = call i32 @return_i32()
  call void @llvm.trap()
  call void @take_i32(i32 %a)
  ret void
}

causes an assertion failure:

llc: /root/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp:168: void query(const llvm::MachineInstr&, bool&, bool&, bool&, bool&): Assertion `!MI.isTerminator()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/llc -o /app/output.s -x86-asm-syntax=intel <source>
1.	Running pass 'Function Pass Manager' on module '<source>'.
2.	Running pass 'WebAssembly Register Stackify' on function '@assert_fail'
 #0 0x00000000034145c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x34145c8)
 #1 0x0000000003411cfc SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f9f6cda2420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #3 0x00007f9f6c86500b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #4 0x00007f9f6c844859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #5 0x00007f9f6c844729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #6 0x00007f9f6c855fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #7 0x0000000001ac853e query(llvm::MachineInstr const&, bool&, bool&, bool&, bool&) WebAssemblyRegStackify.cpp:0:0
 #8 0x0000000001ac924f isSafeToMove(llvm::MachineOperand const*, llvm::MachineOperand const*, llvm::MachineInstr const*, llvm::WebAssemblyFunctionInfo const&, llvm::MachineRegisterInfo const&) (.isra.0) WebAssemblyRegStackify.cpp:0:0
 #9 0x0000000001acc728 (anonymous namespace)::WebAssemblyRegStackify::runOnMachineFunction(llvm::MachineFunction&) WebAssemblyRegStackify.cpp:0:0
#10 0x00000000026f1e21 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
#11 0x0000000002c70009 llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2c70009)
#12 0x0000000002c70241 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2c70241)
#13 0x0000000002c70a62 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2c70a62)
#14 0x0000000000760e52 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#15 0x000000000069ec46 main (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x69ec46)
#16 0x00007f9f6c846083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#17 0x00000000007577ee _start (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x7577ee)
Program terminated with signal: SIGSEGV
Compiler returned: 139

Godbolt link

It seems like this line in WebAssemblyRegStackify::runOnMachineFunction calls isSafeToMove()
which calls query() in two places
which has the line assert(!MI.isTerminator());
which trips over the fact that unreachable (what @llvm.trap() is compiled to) is defined as a terminator

@Endilll Endilll added backend:WebAssembly crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Oct 11, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 11, 2023

@llvm/issue-subscribers-backend-webassembly

Author: Matt Harding (majaha)

This code: ```llvm target triple = "wasm32-unknown-unknown"

declare void @llvm.trap() cold noreturn nounwind
declare i32 @return_i32()
declare void @take_i32(i32)

define void @assert_fail() {
%a = call i32 @return_i32()
call void @llvm.trap()
call void @take_i32(i32 %a)
ret void
}

causes an assertion failure:

llc: /root/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp:168: void query(const llvm::MachineInstr&, bool&, bool&, bool&, bool&): Assertion `!MI.isTerminator()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/llc -o /app/output.s -x86-asm-syntax=intel <source>

  1. Running pass 'Function Pass Manager' on module '<source>'.
  2. Running pass 'WebAssembly Register Stackify' on function '@assert_fail'
    #0 0x00000000034145c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x34145c8)
    #1 0x0000000003411cfc SignalHandler(int) Signals.cpp:0:0
    #2 0x00007f9f6cda2420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
    #3 0x00007f9f6c86500b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
    #4 0x00007f9f6c844859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
    #5 0x00007f9f6c844729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
    #6 0x00007f9f6c855fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
    #7 0x0000000001ac853e query(llvm::MachineInstr const&, bool&, bool&, bool&, bool&) WebAssemblyRegStackify.cpp:0:0
    #8 0x0000000001ac924f isSafeToMove(llvm::MachineOperand const*, llvm::MachineOperand const*, llvm::MachineInstr const*, llvm::WebAssemblyFunctionInfo const&, llvm::MachineRegisterInfo const&) (.isra.0) WebAssemblyRegStackify.cpp:0:0
    #9 0x0000000001acc728 (anonymous namespace)::WebAssemblyRegStackify::runOnMachineFunction(llvm::MachineFunction&) WebAssemblyRegStackify.cpp:0:0
    #10 0x00000000026f1e21 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
    #11 0x0000000002c70009 llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2c70009)
    #12 0x0000000002c70241 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2c70241)
    #13 0x0000000002c70a62 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2c70a62)
    #14 0x0000000000760e52 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
    #15 0x000000000069ec46 main (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x69ec46)
    #16 0x00007f9f6c846083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
    #17 0x00000000007577ee _start (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x7577ee)
    Program terminated with signal: SIGSEGV
    Compiler returned: 139
[Godbolt link](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:llvm,selection:(endColumn:25,endLineNumber:7,positionColumn:25,positionLineNumber:7,selectionStartColumn:25,selectionStartLineNumber:7,startColumn:25,startLineNumber:7),source:'target+triple+%3D+%22wasm32-unknown-unknown%22%0A%0Adeclare+void+@<!-- -->llvm.trap()+cold+noreturn+nounwind%0Adeclare+i32+@<!-- -->return_i32()%0Adeclare+void+@<!-- -->take_i32(i32)%0A%0Adefine+void+@<!-- -->assert_fail()+%7B%0A++%25a+%3D+call+i32+@<!-- -->return_i32()%0A++call+void+@<!-- -->llvm.trap()%0A++call+void+@<!-- -->take_i32(i32+%25a)%0A++ret+void%0A%7D'),l:'5',n:'0',o:'LLVM+IR+source+%231',t:'0')),k:28.102455380752453,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:llc-assertions-trunk,deviceViewOpen:'1',filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:llvm,libs:!(),options:'___+',overrides:!(),paneName:'+llc+wasm',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+llc+wasm',t:'0')),k:24.857851593775443,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'llc+(assertions+trunk)',editorid:1,fontScale:14,fontUsePx:'0',j:2,wrap:'1'),l:'5',n:'0',o:'Output+of+llc+(assertions+trunk)+(Compiler+%232)',t:'0')),k:47.03969302547212,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

It seems like [this line in WebAssemblyRegStackify::runOnMachineFunction calls isSafeToMove()](https://github.com/llvm/llvm-project/blob/bccf2c8468e2f364f8c364d613ffb78d61b67ceb/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L878C44-L878C44)
which [calls query() in two places](https://github.com/llvm/llvm-project/blob/bccf2c8468e2f364f8c364d613ffb78d61b67ceb/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L399C3-L399C8)
which has the line [`assert(!MI.isTerminator());`](https://github.com/llvm/llvm-project/blob/bccf2c8468e2f364f8c364d613ffb78d61b67ceb/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L168C25-L168C25)
which trips over the fact that unreachable (what `@<!-- -->llvm.trap()` is compiled to) [is defined as a terminator](https://github.com/llvm/llvm-project/blob/bccf2c8468e2f364f8c364d613ffb78d61b67ceb/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td#L109C9-L109C9)
</details>

@majaha
Copy link
Contributor Author

majaha commented Nov 3, 2023

Possibly the solution is to have two kinds of UNREACHABLE instruction, one which is a terminator for llvm's unreachable, and one which isn't for @llvm.trap().

HerrCai0907 added a commit to HerrCai0907/llvm-project that referenced this issue Apr 26, 2024
`llvm.trap` will be convert as `unreachable` which is termiantor. But we cannot append any instruction after terminator wihch will casue llir's validation failed.
This PR introduces a pass to clean instruction after terminator.
Fixes: llvm#68770
HerrCai0907 added a commit to HerrCai0907/llvm-project that referenced this issue Apr 26, 2024
`llvm.trap` will be convert as `unreachable` which is termiantor. But we cannot append any instruction after terminator wihch will casue llir's validation failed.
This PR introduces a pass to clean instruction after terminator.
Fixes: llvm#68770
HerrCai0907 added a commit that referenced this issue Apr 27, 2024
`llvm.trap` will be convert as `unreachable` which is terminator.
Instruction after terminator will cause validation failed.
This PR introduces a pass to clean instruction after terminator.
Fixes: #68770.
HerrCai0907 added a commit that referenced this issue Apr 28, 2024
…90354)" (#90366)

`llvm.trap` will be convert as unreachable which is terminator.
Instruction after terminator will cause validation failed.
This PR introduces a pass to clean instruction after terminator.
Fixes: #68770
Reapply: #90207
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:WebAssembly crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
3 participants