diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -630,9 +630,9 @@ // Exception-catching related functions // - // We intentionally excluded __cxa_end_catch here even though it surely cannot - // longjmp, in order to maintain the unwind relationship from all existing - // catchpads (and calls within them) to catch.dispatch.longjmp. + // We intentionally treat __cxa_end_catch longjmpable in Wasm SjLj even though + // it surely cannot longjmp, in order to maintain the unwind relationship from + // all existing catchpads (and calls within them) to catch.dispatch.longjmp. // // In Wasm EH + Wasm SjLj, we // 1. Make all catchswitch and cleanuppad that unwind to caller unwind to @@ -663,6 +663,8 @@ // // The comment block in findWasmUnwindDestinations() in // SelectionDAGBuilder.cpp is addressing a similar problem. + if (CalleeName == "__cxa_end_catch") + return WebAssembly::WasmEnableSjLj; if (CalleeName == "__cxa_begin_catch" || CalleeName == "__cxa_allocate_exception" || CalleeName == "__cxa_throw" || CalleeName == "__clang_call_terminate") diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll --- a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll @@ -33,21 +33,23 @@ ; CHECK-NEXT: %[[CMP:.*]] = icmp eq i32 %__THREW__.val, 1 ; CHECK-NEXT: br i1 %[[CMP]], label %lpad, label %try.cont -; longjmp checking part -; CHECK: if.then1: -; CHECK: call i32 @testSetjmp - +; CHECK: lpad: lpad: ; preds = %entry %0 = landingpad { i8*, i32 } catch i8* null %1 = extractvalue { i8*, i32 } %0, 0 %2 = extractvalue { i8*, i32 } %0, 1 +; CHECK-NOT: call {{.*}} void @__invoke_void(void ()* @__cxa_end_catch) %3 = call i8* @__cxa_begin_catch(i8* %1) #2 call void @__cxa_end_catch() br label %try.cont try.cont: ; preds = %lpad, %entry ret void + +; longjmp checking part +; CHECK: if.then1: +; CHECK: call i32 @testSetjmp } ; @foo can either throw an exception or longjmp. Because this function doesn't