[PATCH] D108905: [ItaniumCXXABI] Set nounwind on __cxa_begin_catch/__cxa_end_catch nounwind

Fangrui Song via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 29 23:36:27 PDT 2021


MaskRay created this revision.
MaskRay added reviewers: ChuanqiXu, rjmccall.
MaskRay requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

See https://lists.llvm.org/pipermail/cfe-dev/2021-August/068740.html

A catch clause calls __cxa_begin_catch/__cxa_end_catch.
This allows a function with all non-nounwind callees surrounded by catch
(...) can infer the nounwind attribute, e.g.
`void test() { try { can_throw(); } catch (...) {}}`

This can avoid unneeded call site records whose action record offset is 0
(cleanup). In addition, a `__clang_call_terminate` define may be avoided.

Note: libcxxrt `__cxa_end_catch` doesn't call external functions.  libsupc++/libc++abi
`__cxa_end_catch` calls `_Unwind_DeleteException` for a foreign exception.
We can except `_Unwind_DeleteException` does not throw (the behavior would be unclear
if it throws).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108905

Files:
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/exceptions.cpp
  clang/test/CodeGenCXX/stack-reuse-exceptions.cpp


Index: clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
===================================================================
--- clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
+++ clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
@@ -86,8 +86,8 @@
 //
 // CHECK: [[CATCH]]:
 // CHECK-NOT: call void @llvm.lifetime
-// CHECK: invoke void
-// CHECK-NEXT: to label %[[TRY_CONT]] unwind label %[[OUTER_LPAD:.+]]
+// CHECK: call void @__cxa_end_catch
+// CHECK-NEXT: br label %[[TRY_CONT]]
 //
 // CHECK: [[TRY_CONT]]:
 // CHECK: %[[T_OUTER:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
@@ -100,15 +100,7 @@
 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
 // CHECK: ret void
 //
-// CHECK: [[OUTER_LPAD]]:
-// CHECK-NOT: call void @llvm.lifetime
-// CHECK: br label %[[EHCLEANUP:.+]]
-//
-// CHECK: [[OUTER_LPAD2]]:
-// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]])
-// CHECK: br label %[[EHCLEANUP]]
-//
-// CHECK: [[EHCLEANUP]]:
+// CHECK: lpad[[#]]:
 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
 
   NontrivialDtor clean;
Index: clang/test/CodeGenCXX/exceptions.cpp
===================================================================
--- clang/test/CodeGenCXX/exceptions.cpp
+++ clang/test/CodeGenCXX/exceptions.cpp
@@ -326,9 +326,12 @@
   }
 }
 
+// CHECK11-LABEL:    declare{{.*}} i8* @__cxa_begin_catch(i8*) #[[#NOUNWIND:]]
+
 // PR9303: invalid assert on this
 namespace test6 {
   bool cond();
+  // CHECK11-LABEL:    define{{.*}} void @_ZN5test64testEv() #[[#TEST6:]]
   void test() {
     try {
     lbl:
@@ -634,3 +637,6 @@
 }
 
 // CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }
+
+// CHECK11: attributes #[[#NOUNWIND]] = { nounwind }
+// CHECK11: attributes #[[#TEST6]] = {{.*}} nounwind
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4393,7 +4393,12 @@
   llvm::FunctionType *FTy = llvm::FunctionType::get(
       CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);
 
-  return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
+  // Set nounwind so that a function with all non-nounwind callees surrounded by
+  // catch (...) can infer nounwind, which can avoid unneded call site records.
+  llvm::FunctionCallee Ret =
+      CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
+  cast<llvm::Function>(Ret.getCallee())->addFnAttr(llvm::Attribute::NoUnwind);
+  return Ret;
 }
 
 static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {
@@ -4401,7 +4406,9 @@
   llvm::FunctionType *FTy =
       llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
 
-  return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
+  llvm::FunctionCallee Ret = CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
+  cast<llvm::Function>(Ret.getCallee())->addFnAttr(llvm::Attribute::NoUnwind);
+  return Ret;
 }
 
 static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108905.369379.patch
Type: text/x-patch
Size: 3061 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210830/5639d97f/attachment.bin>


More information about the cfe-commits mailing list