summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-03-16 05:39:12 +0000
committerHeejin Ahn <aheejin@gmail.com>2019-03-16 05:39:12 +0000
commitff8d63d7891082c24b8a8bce0016bf43623405f4 (patch)
tree4f440df604933d7f741b71ff9174e4483d477593
parenta8c64ce548393310c065c7dfe08fb676e3f25370 (diff)
[WebAssembly] Use rethrow intrinsic in the rethrow block
Summary: 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`. Reviewers: dschuff Subscribers: sbc100, jgravelle-google, sunfish, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59353 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356317 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/BuiltinsWebAssembly.def2
-rw-r--r--lib/CodeGen/CGBuiltin.cpp4
-rw-r--r--lib/CodeGen/CGException.cpp4
-rw-r--r--test/CodeGen/builtins-wasm.c8
-rw-r--r--test/CodeGenCXX/wasm-eh.cpp10
5 files changed, 15 insertions, 13 deletions
diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
index 0241436b5b..e109ee620b 100644
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/include/clang/Basic/BuiltinsWebAssembly.def
@@ -37,7 +37,7 @@ BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
// 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")
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 96289720ab..4d9c76ae7f 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -13513,8 +13513,8 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
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: {
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 8335c9f687..748029b860 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -1259,7 +1259,9 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
}
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);
diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c
index bba615d3a2..3c5db7268d 100644
--- a/test/CodeGen/builtins-wasm.c
+++ b/test/CodeGen/builtins-wasm.c
@@ -44,10 +44,10 @@ void throw(unsigned int tag, void *obj) {
// 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) {
diff --git a/test/CodeGenCXX/wasm-eh.cpp b/test/CodeGenCXX/wasm-eh.cpp
index ea77fec820..fbbf4dd3fd 100644
--- a/test/CodeGenCXX/wasm-eh.cpp
+++ b/test/CodeGenCXX/wasm-eh.cpp
@@ -62,7 +62,7 @@ void test0() {
// 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 @@ void test6() {
// 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 @@ void test7() {
// 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 @@ void test8() {
// 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]] []