Skip to content

Wasm EH cannot handle unwind backedges #63182

New issue

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

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

Already on GitHub? # to your account

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

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

No branches or pull requests

2 participants