[llvm] X86: Respect the exception model module flag in X86LFIRewritePass (PR #227295)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 05:45:53 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/227295

This is preparation for removing the TargetOptions ExceptionModel field.
Currently this doesn't show an observable behavior change because the
codegen pass pipeline is driven by this field. Add the module flag based
check so in the future, if the pass runs on a module not using sjlj, it
will skip the sjlj specific handling.

Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>

>From 10b98e87979ec330cb6d53d6a7f4d326552c883b Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 29 Sep 2026 13:14:22 +0200
Subject: [PATCH] X86: Respect the exception model module flag in
 X86LFIRewritePass

This is preparation for removing the TargetOptions ExceptionModel field.
Currently this doesn't show an observable behavior change because the
codegen pass pipeline is driven by this field. Add the module flag based
check so in the future, if the pass runs on a module not using sjlj, it
will skip the sjlj specific handling.

Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86LFIRewritePass.cpp | 39 ++++++++------
 llvm/test/CodeGen/X86/lfi-align-sjlj.ll   | 66 +++++++++++++++++++++++
 2 files changed, 90 insertions(+), 15 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/lfi-align-sjlj.ll

diff --git a/llvm/lib/Target/X86/X86LFIRewritePass.cpp b/llvm/lib/Target/X86/X86LFIRewritePass.cpp
index 261efa209b253..3a88c40961112 100644
--- a/llvm/lib/Target/X86/X86LFIRewritePass.cpp
+++ b/llvm/lib/Target/X86/X86LFIRewritePass.cpp
@@ -16,6 +16,7 @@
 #include "X86.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Support/Alignment.h"
 #include "llvm/Target/TargetMachine.h"
 
@@ -43,19 +44,20 @@ static void alignToBundle(MachineBasicBlock &MBB) {
 
 // Returns true if MBB may be reached by an indirect branch (does not include
 // jump table targets).
-static bool isIndirectlyReachable(MachineFunction &MF,
-                                  const MachineBasicBlock &MBB) {
-  if (MBB.hasAddressTaken() || MBB.isEHPad())
-    return true;
-
-  // With SJLJ exception handling, the dispatch block jumps indirectly to the
-  // block holding the call site's landing pad label, which is no longer marked
-  // as an EH pad by that point.
-  if (MF.getTarget().Options.ExceptionModel == ExceptionHandling::SjLj)
-    for (const MachineInstr &MI : MBB)
-      if (MI.isEHLabel() &&
-          MF.hasCallSiteLandingPad(MI.getOperand(0).getMCSymbol()))
-        return true;
+static bool isIndirectlyReachable(const MachineBasicBlock &MBB) {
+  return MBB.hasAddressTaken() || MBB.isEHPad();
+}
+
+// Returns true if MBB holds the label of a call site's landing pad. With SJLJ
+// exception handling, the dispatch block jumps indirectly to that block, which
+// is no longer marked as an EH pad by that point.
+static bool holdsCallSiteLandingPadLabel(MachineFunction &MF,
+                                         const MachineBasicBlock &MBB) {
+  for (const MachineInstr &MI : MBB) {
+    if (MI.isEHLabel() &&
+        MF.hasCallSiteLandingPad(MI.getOperand(0).getMCSymbol()))
+      return true;
+  }
 
   return false;
 }
@@ -71,9 +73,16 @@ static void alignIndirectBranchTargets(MachineFunction &MF) {
       for (MachineBasicBlock *MBB : JTE.MBBs)
         alignToBundle(*MBB);
 
-  for (MachineBasicBlock &MBB : MF)
-    if (isIndirectlyReachable(MF, MBB))
+  ExceptionHandling EH = MF.getFunction().getParent()->getExceptionModel();
+  if (EH == ExceptionHandling::Default)
+    EH = MF.getTarget().getExceptionModel();
+  const bool IsSjLj = EH == ExceptionHandling::SjLj;
+
+  for (MachineBasicBlock &MBB : MF) {
+    if (isIndirectlyReachable(MBB) ||
+        (IsSjLj && holdsCallSiteLandingPadLabel(MF, MBB)))
       alignToBundle(MBB);
+  }
 }
 
 bool X86LFIRewriteLegacy::runOnMachineFunction(MachineFunction &MF) {
diff --git a/llvm/test/CodeGen/X86/lfi-align-sjlj.ll b/llvm/test/CodeGen/X86/lfi-align-sjlj.ll
new file mode 100644
index 0000000000000..b1434865cbd7f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/lfi-align-sjlj.ll
@@ -0,0 +1,66 @@
+; RUN: split-file %s %t
+; RUN: llc -mtriple=x86_64_lfi -exception-model=sjlj < %t/sjlj.ll | FileCheck -check-prefix=SJLJ %s
+; RUN: llc -mtriple=x86_64_lfi < %t/dwarf.ll | FileCheck -check-prefix=DWARF %s
+
+; The SJLJ dispatch block jumps indirectly to the landing pad, so the
+; landing pad and the dispatch block both need bundle alignment. Other
+; exception models have no dispatch block, and the landing pad is only
+; aligned because it is an EH pad.
+
+;--- sjlj.ll
+; FIXME: SJLJ lowering still requires -exception-model=sjlj
+
+declare void @may_throw()
+declare i32 @__gxx_personality_sj0(...)
+
+define void @invoke_aligns_landing_pad() personality ptr @__gxx_personality_sj0 {
+; SJLJ-LABEL: invoke_aligns_landing_pad:
+; SJLJ:         callq may_throw at PLT
+; SJLJ:         .p2align 5
+; SJLJ-NEXT:  .LBB0_3:
+; SJLJ:         jmpq *(%rcx,%rax,8)
+; SJLJ-NEXT:    .p2align 5
+; SJLJ-NEXT:  .LBB0_2:
+; SJLJ-NEXT:  .Ltmp2:
+; SJLJ:       .LJTI0_0:
+; SJLJ-NEXT:    .quad .LBB0_2
+entry:
+  invoke void @may_throw() to label %cont unwind label %lpad
+
+cont:
+  ret void
+
+lpad:
+  %l = landingpad { ptr, i32 } catch ptr null
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"exception-model", !"sjlj"}
+
+;--- dwarf.ll
+
+declare void @may_throw()
+declare i32 @__gxx_personality_v0(...)
+
+define void @invoke_aligns_landing_pad() personality ptr @__gxx_personality_v0 {
+; DWARF-LABEL: invoke_aligns_landing_pad:
+; DWARF:         callq may_throw at PLT
+; DWARF:         .p2align 5
+; DWARF-NEXT:  .LBB0_2:
+; DWARF:       .Ltmp2:
+; DWARF-NOT:     jmpq *
+; DWARF-NOT:   .LJTI
+entry:
+  invoke void @may_throw() to label %cont unwind label %lpad
+
+cont:
+  ret void
+
+lpad:
+  %l = landingpad { ptr, i32 } catch ptr null
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"exception-model", !"dwarf"}



More information about the llvm-commits mailing list