aheejin created this revision. aheejin added a reviewer: dschuff. Herald added subscribers: cfe-commits, sunfish, jgravelle-google, sbc100. Herald added a project: clang.
Because in wasm we merge all catch clauses into one big catchpad, in case none of the types in catch handlers matches after we test against each of them, we should unwind to the next EH enclosing scope. For this, we should NOT use a call to `__cxa_rethrow` but rather a call to our own rethrow intrinsic, because what we're trying to do here is just to transfer the control flow into the next enclosing EH pad (or the caller). Calls to `__cxa_rethrow` should only be used after a call to `__cxa_begin_catch`. Repository: rC Clang https://reviews.llvm.org/D59353 Files: include/clang/Basic/BuiltinsWebAssembly.def lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CGException.cpp test/CodeGen/builtins-wasm.c test/CodeGenCXX/wasm-eh.cpp
Index: test/CodeGenCXX/wasm-eh.cpp =================================================================== --- test/CodeGenCXX/wasm-eh.cpp +++ test/CodeGenCXX/wasm-eh.cpp @@ -62,7 +62,7 @@ // CHECK-NEXT: br label %[[TRY_CONT_BB]] // CHECK: [[RETHROW_BB]]: -// CHECK-NEXT: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +// CHECK-NEXT: call void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] // CHECK-NEXT: unreachable // Single catch-all @@ -232,7 +232,7 @@ // CHECK: catchret from %[[CATCHPAD]] to label %{{.*}} // CHECK: [[RETHROW_BB]]: -// CHECK-NEXT: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +// CHECK-NEXT: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] // CHECK-NEXT: to label %[[UNREACHABLE_BB:.*]] unwind label %[[EHCLEANUP_BB1:.*]] // CHECK: [[EHCLEANUP_BB2]]: @@ -296,7 +296,7 @@ // CHECK: catchret from %[[CATCHPAD0]] to label -// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ] +// CHECK: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ] // CHECK: %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CATCHPAD0]] [] // CHECK: cleanupret from %[[CLEANUPPAD1]] unwind label @@ -368,11 +368,11 @@ // CHECK: catchret from %[[CATCHPAD1]] to label -// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ] +// CHECK: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ] // CHECK: catchret from %[[CATCHPAD0]] to label -// CHECK: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ] +// CHECK: call void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ] // CHECK: unreachable // CHECK: %[[CLEANUPPAD0:.*]] = cleanuppad within %[[CATCHPAD1]] [] Index: test/CodeGen/builtins-wasm.c =================================================================== --- test/CodeGen/builtins-wasm.c +++ test/CodeGen/builtins-wasm.c @@ -44,10 +44,10 @@ // WEBASSEMBLY64: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}}) } -void rethrow(void) { - return __builtin_wasm_rethrow(); - // WEBASSEMBLY32: call void @llvm.wasm.rethrow() - // WEBASSEMBLY64: call void @llvm.wasm.rethrow() +void rethrow_in_catch(void) { + return __builtin_wasm_rethrow_in_catch(); + // WEBASSEMBLY32: call void @llvm.wasm.rethrow.in.catch() + // WEBASSEMBLY64: call void @llvm.wasm.rethrow.in.catch() } int atomic_wait_i32(int *addr, int expected, long long timeout) { Index: lib/CodeGen/CGException.cpp =================================================================== --- lib/CodeGen/CGException.cpp +++ lib/CodeGen/CGException.cpp @@ -1259,7 +1259,9 @@ } assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty()); Builder.SetInsertPoint(RethrowBlock); - CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true); + llvm::Function *RethrowInCatchFn = + CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow_in_catch); + EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {}); } EmitBlock(ContBB); Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -13513,8 +13513,8 @@ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw); return Builder.CreateCall(Callee, {Tag, Obj}); } - case WebAssembly::BI__builtin_wasm_rethrow: { - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow); + case WebAssembly::BI__builtin_wasm_rethrow_in_catch: { + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow_in_catch); return Builder.CreateCall(Callee); } case WebAssembly::BI__builtin_wasm_atomic_wait_i32: { Index: include/clang/Basic/BuiltinsWebAssembly.def =================================================================== --- include/clang/Basic/BuiltinsWebAssembly.def +++ include/clang/Basic/BuiltinsWebAssembly.def @@ -37,7 +37,7 @@ // Exception handling builtins. TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling") -TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling") +TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling") // Atomic wait and notify. BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits