MaskRay updated this revision to Diff 557798.
MaskRay retitled this revision from "[ItaniumCXXABI] Make __cxa_end_catch calls 
unconditionally nounwind" to "[ItaniumCXXABI] Add 
-fassume-nothrow-exception-dtor to assume that an exception object' destructor 
is nothrow".
MaskRay edited the summary of this revision.
MaskRay added a comment.
This revision is now accepted and ready to land.

Switch to opt-in

Add -fassume-nothrow-exception-dtor


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108905/new/

https://reviews.llvm.org/D108905

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/CodeGenCXX/eh.cpp
  clang/test/CodeGenCXX/exceptions.cpp
  clang/test/CodeGenCoroutines/coro-cleanup.cpp
  clang/test/Driver/clang-exception-flags.cpp

Index: clang/test/Driver/clang-exception-flags.cpp
===================================================================
--- clang/test/Driver/clang-exception-flags.cpp
+++ clang/test/Driver/clang-exception-flags.cpp
@@ -27,3 +27,6 @@
 // RUN: %clang -### -target x86_64-scei-ps4 %s 2>&1 | FileCheck %s -check-prefix=PS-OFF
 // RUN: %clang -### -target x86_64-sie-ps5 %s 2>&1 | FileCheck %s -check-prefix=PS-OFF
 // PS-OFF-NOT: "-cc1" {{.*}} "-f{{(cxx-)?}}exceptions"
+
+// RUN: %clang -### -fexceptions -fno-assume-nothrow-exception-dtor -fassume-nothrow-exception-dtor %s 2>&1 | FileCheck %s --check-prefix=NOTHROW-DTOR
+// NOTHROW-DTOR: "-cc1"{{.*}} "-fcxx-exceptions" "-fassume-nothrow-exception-dtor"
Index: clang/test/CodeGenCoroutines/coro-cleanup.cpp
===================================================================
--- clang/test/CodeGenCoroutines/coro-cleanup.cpp
+++ clang/test/CodeGenCoroutines/coro-cleanup.cpp
@@ -1,5 +1,6 @@
 // Verify that coroutine promise and allocated memory are freed up on exception.
-// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,THROWEND
+// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -fassume-nothrow-exception-dtor -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,NOTHROWEND
 
 namespace std {
 template <typename... T> struct coroutine_traits;
@@ -49,7 +50,9 @@
   // CHECK: [[DeallocPad]]:
   // CHECK-NEXT: landingpad
   // CHECK-NEXT:   cleanup
-  // CHECK: br label %[[Dealloc:.+]]
+  // THROWEND:        br label %[[Dealloc:.+]]
+  // NOTHROWEND:      icmp ne ptr %[[#]], null
+  // NOTHROWEND-NEXT: br i1 %[[#]], label %[[Dealloc:.+]], label
 
   Cleanup cleanup;
   may_throw();
@@ -64,17 +67,18 @@
   // CHECK-NEXT:       catch ptr null
   // CHECK:  call void @_ZN7CleanupD1Ev(
   // CHECK:  br label %[[Catch:.+]]
-
   // CHECK: [[Catch]]:
   // CHECK:    call ptr @__cxa_begin_catch(
   // CHECK:    call void @_ZNSt16coroutine_traitsIJvEE12promise_type19unhandled_exceptionEv(
-  // CHECK:    invoke void @__cxa_end_catch()
-  // CHECK-NEXT:    to label %[[Cont:.+]] unwind
+  // THROWEND:        invoke void @__cxa_end_catch()
+  // THROWEND-NEXT:     to label %[[Cont:.+]] unwind
+  // NOTHROWEND:      call void @__cxa_end_catch()
+  // NOTHROWEND-NEXT:   br label %[[Cont2:.+]]
 
-  // CHECK: [[Cont]]:
-  // CHECK-NEXT: br label %[[Cont2:.+]]
-  // CHECK: [[Cont2]]:
-  // CHECK-NEXT: br label %[[Cleanup:.+]]
+  // THROWEND: [[Cont]]:
+  // THROWEND-NEXT:   br label %[[Cont2:.+]]
+  // CHECK:        [[Cont2]]:
+  // CHECK-NEXT:        br label %[[Cleanup:.+]]
 
   // CHECK: [[Cleanup]]:
   // CHECK: call void @_ZNSt16coroutine_traitsIJvEE12promise_typeD1Ev(
@@ -82,8 +86,8 @@
   // CHECK: call void @_ZdlPv(ptr noundef %[[Mem0]]
 
   // CHECK: [[Dealloc]]:
-  // CHECK:   %[[Mem:.+]] = call ptr @llvm.coro.free(
-  // CHECK:   call void @_ZdlPv(ptr noundef %[[Mem]])
+  // THROWEND:   %[[Mem:.+]] = call ptr @llvm.coro.free(
+  // THROWEND:   call void @_ZdlPv(ptr noundef %[[Mem]])
 
   co_return;
 }
Index: clang/test/CodeGenCXX/exceptions.cpp
===================================================================
--- clang/test/CodeGenCXX/exceptions.cpp
+++ clang/test/CodeGenCXX/exceptions.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++98 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck --check-prefixes=CHECK,CHECK11,THROWEND11 %s
+// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fassume-nothrow-exception-dtor | FileCheck --check-prefixes=CHECK,CHECK11,NOTHROWEND11 %s
 
 // CHECK: %[[STRUCT_TEST13_A:.*]] = type { i32, i32 }
 
@@ -479,11 +480,16 @@
 
   // CHECK98:      call void @__cxa_end_catch()
   // CHECK98-NEXT: br label
-  // CHECK11:      invoke void @__cxa_end_catch()
-  // CHECK11-NEXT: to label
+  // THROWEND11:        invoke void @__cxa_end_catch()
+  // THROWEND11-NEXT:   to label %invoke.cont[[#]] unwind label %terminate.lpad
+  // NOTHROWEND11:      call void @__cxa_end_catch()
+  // NOTHROWEND11-NEXT: br label
 
   // CHECK:      invoke void @__cxa_rethrow()
   // CHECK:      unreachable
+
+  // THROWEND11:        terminate.lpad:
+  // THROWEND11:          call void @__clang_call_terminate(
 }
 
 // Ensure that an exception in a constructor destroys
Index: clang/test/CodeGenCXX/eh.cpp
===================================================================
--- clang/test/CodeGenCXX/eh.cpp
+++ clang/test/CodeGenCXX/eh.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.13.99 -std=c++11 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=UNALIGNED %s
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.14 -std=c++11 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ALIGNED %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.13.99 -std=c++11 -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,UNALIGNED,THROWEND %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.14 -std=c++11 -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,ALIGNED,THROWEND %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.14 -std=c++11 -emit-llvm -o - %s -fassume-nothrow-exception-dtor | FileCheck --check-prefixes=CHECK,ALIGNED,NOTHROWEND %s
 
 struct test1_D {
   double d;
@@ -218,13 +219,16 @@
     } catch (B a) {
     // CHECK:      call ptr @__cxa_begin_catch
     // CHECK-NEXT: call void @llvm.memcpy
-    // CHECK-NEXT: invoke void @__cxa_end_catch()
+    // THROWEND-NEXT:   invoke void @__cxa_end_catch()
+    // NOTHROWEND-NEXT: call void @__cxa_end_catch() [[NUW]]
     } catch (...) {
     // CHECK:      call ptr @__cxa_begin_catch
-    // CHECK-NEXT: invoke void @__cxa_end_catch()
+    // THROWEND-NEXT:   invoke void @__cxa_end_catch()
+    // NOTHROWEND-NEXT: call void @__cxa_end_catch() [[NUW]]
     }
 
-    // CHECK: call void @_ZN6test101AD1Ev(
+    // THROWEND:       call void @_ZN6test101AD1Ev(
+    // NOTHROWEND-NOT: call void @_ZN6test101AD1Ev(
   }
 }
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -385,6 +385,9 @@
   // So we do not set EH to false.
   Args.AddLastArg(CmdArgs, options::OPT_fignore_exceptions);
 
+  Args.addOptInFlag(CmdArgs, options::OPT_fassume_nothrow_exception_dtor,
+                    options::OPT_fno_assume_nothrow_exception_dtor);
+
   if (EH)
     CmdArgs.push_back("-fexceptions");
   return EH;
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4508,7 +4508,9 @@
 }
 
 /// Emits a call to __cxa_begin_catch and enters a cleanup to call
-/// __cxa_end_catch.
+/// __cxa_end_catch. If -fassume-nothrow-exception-dtor is specified, we assume
+/// that the exception object's dtor is nothrow, therefore the __cxa_end_catch
+/// call can be marked as nounwind even if EndMightThrow is true.
 ///
 /// \param EndMightThrow - true if __cxa_end_catch might throw
 static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
@@ -4517,7 +4519,9 @@
   llvm::CallInst *call =
     CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn);
 
-  CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);
+  CGF.EHStack.pushCleanup<CallEndCatch>(
+      NormalAndEHCleanup,
+      EndMightThrow && !CGF.CGM.getCodeGenOpts().AssumeNothrowExceptionDtor);
 
   return call;
 }
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1988,6 +1988,10 @@
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Enable support for ignoring exception handling constructs">,
   MarshallingInfoFlag<LangOpts<"IgnoreExceptions">>;
+defm assume_nothrow_exception_dtor: BoolFOption<"assume-nothrow-exception-dtor",
+  CodeGenOpts<"AssumeNothrowExceptionDtor">, DefaultFalse,
+  PosFlag<SetTrue, [], [ClangOption, CC1Option], "Assume that exception objects' destructors are nothrow">,
+  NegFlag<SetFalse>>;
 def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group<f_Group>,
   Visibility<[ClangOption, CLOption]>,
   HelpText<"Allows control over excess precision on targets where native "
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -37,6 +37,7 @@
 CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
 CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
 CODEGENOPT(AssumeUniqueVTables , 1, 1) ///< Assume a class has only one vtable.
+CODEGENOPT(AssumeNothrowExceptionDtor , 1, 0) ///< Assume __cxa_end_catch is nothrow.
 CODEGENOPT(Autolink          , 1, 1) ///< -fno-autolink
 CODEGENOPT(AutoImport        , 1, 1) ///< -fno-auto-import
 CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to