Author: Arseniy Obolenskiy
Date: 2026-11-03T18:52:48+01:00
New Revision: 9ecf4a24ed4b4c2a5e276f3fdc5c4c127c3f80bf

URL: 
https://github.com/llvm/llvm-project/commit/9ecf4a24ed4b4c2a5e276f3fdc5c4c127c3f80bf
DIFF: 
https://github.com/llvm/llvm-project/commit/9ecf4a24ed4b4c2a5e276f3fdc5c4c127c3f80bf.diff

LOG: [CIR][EH] Drop personality from functions without landing pads (#236322)

Match classic codegen, which sets a personality only where it emits
landing pad and erase the personality declaration once it is unused

Added: 
    clang/test/CIR/Transforms/eh-abi-lowering-personality.cir

Modified: 
    clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
    clang/test/CIR/CodeGen/ehspec-noexcept.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp 
b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
index 4215f84319e48..93102e9f91bf4 100644
--- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
@@ -25,7 +25,8 @@
 //                                  catch-copy thunk body, or a store of the
 //                                  exception object address for
 //                                  reference_to_pointer
-//   - personality function set on functions requiring EH
+//   - personality function set on functions requiring EH and removed from
+//     functions without landing pads
 //
 
//===----------------------------------------------------------------------===//
 
@@ -137,6 +138,8 @@ class ItaniumEHLowering : public EHABILowering {
 
   DenseMap<mlir::StringAttr, cir::FuncOp> catchCopyThunks;
 
+  llvm::SmallSetVector<mlir::StringAttr, 1> droppedPersonalities;
+
   constexpr const static ::llvm::StringLiteral kGxxPersonality =
       "__gxx_personality_v0";
 
@@ -176,6 +179,13 @@ mlir::LogicalResult ItaniumEHLowering::run() {
     if (mlir::failed(lowerFunc(funcOp)))
       return mlir::failure();
   }
+
+  for (mlir::StringAttr name : droppedPersonalities) {
+    auto personalityDecl = mod.lookupSymbol<cir::FuncOp>(name);
+    if (personalityDecl && personalityDecl.isDeclaration() &&
+        mlir::SymbolTable::symbolKnownUseEmpty(personalityDecl, mod))
+      personalityDecl.erase();
+  }
   return mlir::success();
 }
 
@@ -380,9 +390,22 @@ mlir::LogicalResult 
ItaniumEHLowering::lowerFunc(cir::FuncOp funcOp) {
   // (begin/end_cleanup, eh.dispatch, begin/end_catch, resume) through the
   // token graph. A single walk to collect initiates is therefore sufficient.
   SmallVector<cir::EhInitiateOp> initiateOps;
-  funcOp.walk([&](cir::EhInitiateOp op) { initiateOps.push_back(op); });
-  if (initiateOps.empty())
+  bool hasLandingPad = false;
+  funcOp.walk([&](mlir::Operation *op) {
+    if (auto initiateOp = mlir::dyn_cast<cir::EhInitiateOp>(op))
+      initiateOps.push_back(initiateOp);
+    else if (mlir::isa<cir::EhInflightOp>(op))
+      hasLandingPad = true;
+  });
+  if (initiateOps.empty()) {
+    // Without a landing pad the personality is dead, as in classic codegen.
+    mlir::FlatSymbolRefAttr personality = funcOp.getPersonalityAttr();
+    if (personality && !hasLandingPad) {
+      droppedPersonalities.insert(personality.getAttr());
+      funcOp.removePersonalityAttr();
+    }
     return mlir::success();
+  }
 
   ensureRuntimeDecls(funcOp.getLoc());
 

diff  --git a/clang/test/CIR/CodeGen/ehspec-noexcept.cpp 
b/clang/test/CIR/CodeGen/ehspec-noexcept.cpp
index 4f86d2ee52963..8bbd67d2dbd50 100644
--- a/clang/test/CIR/CodeGen/ehspec-noexcept.cpp
+++ b/clang/test/CIR/CodeGen/ehspec-noexcept.cpp
@@ -82,14 +82,8 @@ void permissive() noexcept {
 // CIR:         } catch all (%[[TOK:.*]]: !cir.eh_token
 // CIR:           cir.eh.terminate %[[TOK]] : !cir.eh_token
 
-// So it leaves no landing pad behind. It does leave the personality function
-// that CIRGen set for the wrapper, which classic codegen omits because it only
-// sets one where it emits a landing pad. The same 
diff erence shows up for a
-// try statement whose body cannot throw, so it is not specific to exception
-// specifications.
 // LLVM-LABEL: define{{.*}} void @_Z10permissivev()
-// LLVMCIR-SAME: personality ptr @__gxx_personality_v0
-// OGCG-NOT:   personality
+// LLVM-NOT:     personality
 // LLVM:         call void @_Z8harmlessv()
 // LLVM-NOT:     landingpad
 // LLVM-NOT:     __clang_call_terminate

diff  --git a/clang/test/CIR/Transforms/eh-abi-lowering-personality.cir 
b/clang/test/CIR/Transforms/eh-abi-lowering-personality.cir
new file mode 100644
index 0000000000000..dbc9003f01815
--- /dev/null
+++ b/clang/test/CIR/Transforms/eh-abi-lowering-personality.cir
@@ -0,0 +1,46 @@
+// RUN: cir-opt %s -cir-eh-abi-lowering -split-input-file -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+!s32i = !cir.int<s, 32>
+
+module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
+
+cir.func private @__gxx_personality_v0(...) -> !s32i
+
+cir.func @no_landing_pad() personality(@__gxx_personality_v0) {
+  cir.return
+}
+
+}
+
+// CHECK-NOT:   @__gxx_personality_v0
+// CHECK-LABEL: cir.func @no_landing_pad() {
+// CHECK-NOT:   @__gxx_personality_v0
+
+// -----
+
+!s32i = !cir.int<s, 32>
+
+module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
+
+cir.func private @_Z8externalv()
+cir.func private @__gxx_personality_v0(...) -> !s32i
+
+cir.func @no_landing_pad() personality(@__gxx_personality_v0) {
+  cir.return
+}
+
+cir.func @landing_pad() personality(@__gxx_personality_v0) {
+  cir.try_call @_Z8externalv() ^bb1, ^bb2 : () -> ()
+^bb1:
+  cir.return
+^bb2:
+  %0 = cir.eh.initiate cleanup : !cir.eh_token
+  cir.resume %0 : !cir.eh_token
+}
+
+}
+
+// CHECK:       cir.func private @__gxx_personality_v0(...)
+// CHECK-LABEL: cir.func @no_landing_pad() {
+// CHECK-LABEL: cir.func @landing_pad() personality(@__gxx_personality_v0)


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to