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

Wasm EH cannot handle unwind backedges #63182

Open
aheejin opened this issue Jun 8, 2023 · 1 comment
Open

Wasm EH cannot handle unwind backedges #63182

aheejin opened this issue Jun 8, 2023 · 1 comment
Labels
backend:WebAssembly confirmed Verified by a second party

Comments

@aheejin
Copy link
Member

aheejin commented Jun 8, 2023

test.ll:

target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-emscripten"

declare i32 @__gxx_wasm_personality_v0(...)

; Function Attrs: nocallback nofree nosync nounwind willreturn
declare ptr @llvm.wasm.get.exception(token) #0

; Function Attrs: nocallback nofree nosync nounwind willreturn
declare i32 @llvm.wasm.get.ehselector(token) #0

declare void @foo()

define void @test() personality ptr @__gxx_wasm_personality_v0 {
bb0:
  invoke void @foo()
          to label %bb1 unwind label %bb2

bb1:                                              ; preds = %bb4, %bb0
  unreachable

bb2:                                              ; preds = %bb4, %bb0
  %catchswitch = catchswitch within none [label %bb3] unwind to caller

bb3:                                              ; preds = %bb2
  %catchpad = catchpad within %catchswitch [ptr null]
  %t0 = call ptr @llvm.wasm.get.exception(token %catchpad)
  %t1 = call i32 @llvm.wasm.get.ehselector(token %catchpad)
  catchret from %catchpad to label %bb4

bb4:                                              ; preds = %bb3
  invoke void @foo()
          to label %bb1 unwind label %bb2
}

attributes #0 = { nocallback nofree nosync nounwind willreturn }

image

$ llc -mattr=+exception-handling -wasm-enable-eh -exception-model=wasm -verify-machineinstrs test.ll

llc: /usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/ADT/SmallVector.h:312: llvm::SmallVectorTemplateCommon::reference llvm::SmallVectorTemplateCommon<const llvm::MachineBasicBlock *>::back() [T = const llvm::MachineBasicBlock *]: Assertion `!empty()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: /usr/local/google/home/aheejin/llvm-git/install.release/bin/llc -mattr=+exception-handling -wasm-enable-eh -exception-model=wasm -verify-machineinstrs t.ll
1.      Running pass 'Function Pass Manager' on module 't.ll'.
2.      Running pass 'WebAssembly CFG Stackify' on function '@test'
 #0 0x00007f669b1e29b3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/local/google/home/aheejin/llvm-git/install.release/bin/../lib/libLLVMSupport.so.17git+0x1e29b3)
 #1 0x00007f669b1e06ae llvm::sys::RunSignalHandlers() (/usr/local/google/home/aheejin/llvm-git/install.release/bin/../lib/libLLVMSupport.so.17git+0x1e06ae)
 #2 0x00007f669b1e2d4a SignalHandler(int) Signals.cpp:0:0
 #3 0x00007f669ae5af90 (/lib/x86_64-linux-gnu/libc.so.6+0x3bf90)
 #4 0x00007f669aea9ccc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007f669ae5aef2 raise ./signal/../sysdeps/posix/raise.c:27:6
 #6 0x00007f669ae45472 abort ./stdlib/abort.c:81:7
 #7 0x00007f669ae45395 _nl_load_domain ./intl/loadmsgcat.c:1177:9
 #8 0x00007f669ae53df2 (/lib/x86_64-linux-gnu/libc.so.6+0x34df2)
 #9 0x00007f669e36b882 (anonymous namespace)::WebAssemblyCFGStackify::placeMarkers(llvm::MachineFunction&) WebAssemblyCFGStackify.cpp:0:0
#10 0x00007f669e3636c2 (anonymous namespace)::WebAssemblyCFGStackify::runOnMachineFunction(llvm::MachineFunction&) WebAssemblyCFGStackify.cpp:0:0
#11 0x00007f669d1af92d llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/usr/local/google/home/aheejin/llvm-git/install.release/bin/../lib/libLLVMCodeGen.so.17git+0x5af92d)
#12 0x00007f669b8448ab llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/local/google/home/aheejin/llvm-git/install.release/bin/../lib/libLLVMCore.so.17git+0x4448ab)
#13 0x00007f669b84cb81 llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/local/google/home/aheejin/llvm-git/install.release/bin/../lib/libLLVMCore.so.17git+0x44cb81)
#14 0x00007f669b845365 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/local/google/home/aheejin/llvm-git/install.release/bin/../lib/libLLVMCore.so.17git+0x445365)
#15 0x00005589ee6ef3f6 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#16 0x00005589ee6ed01d main (/usr/local/google/home/aheejin/llvm-git/install.release/bin/llc+0x1201d)
#17 0x00007f669ae4618a __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#18 0x00007f669ae46245 call_init ./csu/../csu/libc-start.c:128:20
#19 0x00007f669ae46245 __libc_start_main ./csu/../csu/libc-start.c:368:5
#20 0x00005589ee6e99c1 _start (/usr/local/google/home/aheejin/llvm-git/install.release/bin/llc+0xe9c1)
Aborted

It looks the backedge formed by the unwind edge from bb4 to bb2 is causing the problem.

This can be solved if we duplicate the BBs in the loop:

target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-emscripten"

declare i32 @__gxx_wasm_personality_v0(...)

; Function Attrs: nocallback nofree nosync nounwind willreturn
declare ptr @llvm.wasm.get.exception(token) #0

; Function Attrs: nocallback nofree nosync nounwind willreturn
declare i32 @llvm.wasm.get.ehselector(token) #0

declare void @foo()

define void @test() personality ptr @__gxx_wasm_personality_v0 {
bb0:
  invoke void @foo()
          to label %bb1 unwind label %bb2

bb1:                                              ; preds = %bb4, %bb0
  unreachable

bb2:                                              ; preds = %bb0
  %catchswitch = catchswitch within none [label %bb3] unwind to caller

bb3:                                              ; preds = %bb2
  %catchpad = catchpad within %catchswitch [ptr null]
  %t0 = call ptr @llvm.wasm.get.exception(token %catchpad)
  %t1 = call i32 @llvm.wasm.get.ehselector(token %catchpad)
  catchret from %catchpad to label %bb4

bb4:                                              ; preds = %bb3.copy, %bb3
  invoke void @foo()
          to label %bb1 unwind label %bb2.copy

bb2.copy:                                         ; preds = %bb4
  %catchswitch.copy = catchswitch within none [label %bb3.copy] unwind to caller

bb3.copy:                                         ; preds = %bb2.copy
  %catchpad.copy = catchpad within %catchswitch.copy [ptr null]
  %t0.copy = call ptr @llvm.wasm.get.exception(token %catchpad.copy)
  %t1.copy = call i32 @llvm.wasm.get.ehselector(token %catchpad.copy)
  catchret from %catchpad.copy to label %bb4
}

attributes #0 = { nocallback nofree nosync nounwind willreturn }

image

@llvmbot
Copy link
Member

llvmbot commented Jun 8, 2023

@llvm/issue-subscribers-backend-webassembly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:WebAssembly confirmed Verified by a second party
Projects
None yet
Development

No branches or pull requests

2 participants