Skip to content

Commit

Permalink
[WebAssembly] Treat __cxa_end_catch not longjmpable in Emscripten SjLj
Browse files Browse the repository at this point in the history
In D117610 we treated `__cxa_end_catch` longjmpable even though it was
not to make unwind destination relationships correct. But we only need
to do this in Wasm SjLj, and doing this in Emscripten SjLj does not make
the code incorrect but add unnecessary invokes. This CL treats
`__cxa_end_catch` longjmpable only in Wasm SjLj.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D117943
  • Loading branch information
aheejin committed Jan 28, 2022
1 parent a4aaa59 commit d9517ef
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
Expand Up @@ -630,9 +630,9 @@ static bool canLongjmp(const Value *Callee) {

// 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
Expand Down Expand Up @@ -663,6 +663,8 @@ static bool canLongjmp(const Value *Callee) {
//
// 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")
Expand Down
10 changes: 6 additions & 4 deletions llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll
Expand Up @@ -33,21 +33,23 @@ entry:
; 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
Expand Down

0 comments on commit d9517ef

Please sign in to comment.