[clang] [llvm] [ARM] Add support for Windows SEH (PR #184953)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 5 21:56:55 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: Trung Nguyen (trungnt2910)
<details>
<summary>Changes</summary>
This commit implements Windows Structured Exception Handling (SEH) support for ARM `clang` in MSVC mode.
This includes enabling the relevant language constructs in the Clang frontend and adding new ARM-specific code lowering logic.
---
Full diff: https://github.com/llvm/llvm-project/pull/184953.diff
6 Files Affected:
- (modified) clang/include/clang/Basic/TargetInfo.h (+2-1)
- (modified) llvm/lib/CodeGen/AsmPrinter/WinException.cpp (+4-3)
- (modified) llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp (+10)
- (modified) llvm/lib/Target/ARM/ARMFrameLowering.cpp (+6)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+17)
- (modified) llvm/lib/Target/ARM/ARMInstrInfo.td (+6)
``````````diff
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index ec6cd2be7c3c5..05c8615deb3ce 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1664,7 +1664,8 @@ class TargetInfo : public TransferrableTargetInfo,
bool isSEHTrySupported() const {
return getTriple().isOSWindows() &&
(getTriple().isX86() ||
- getTriple().getArch() == llvm::Triple::aarch64);
+ getTriple().getArch() == llvm::Triple::aarch64 ||
+ getTriple().isThumb());
}
/// Return true if {|} are normal characters in the asm string.
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 90d8196ffb82a..ca579c22f66be 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -33,9 +33,10 @@
using namespace llvm;
WinException::WinException(AsmPrinter *A) : EHStreamer(A) {
- // MSVC's EH tables are always composed of 32-bit words. All known 64-bit
- // platforms use an imagerel32 relocation to refer to symbols.
- useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
+ // MSVC's EH tables are always composed of 32-bit words. All known
+ // architectures use an imagerel32 relocation to refer to symbols, except
+ // 32-bit x86.
+ useImageRel32 = A->TM.getTargetTriple().getArch() != Triple::x86;
isAArch64 = Asm->TM.getTargetTriple().isAArch64();
isThumb = Asm->TM.getTargetTriple().isThumb();
}
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index 14e4c19a8ac1a..69154fd6e749a 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -2242,6 +2242,16 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
return true;
}
+ case ARM::CLEANUPRET:
+ case ARM::CATCHRET: {
+ bool isThumb = STI->isThumb();
+ unsigned RetOpc = isThumb ? ARM::tBX_RET : ARM::BX_RET;
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(RetOpc))
+ .add(predOps(ARMCC::AL));
+ MI.eraseFromParent();
+ return true;
+ }
+
case ARM::TCRETURNdi:
case ARM::TCRETURNri:
case ARM::TCRETURNrinotr12: {
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 7d6be065d208a..940ae6006777c 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -443,6 +443,9 @@ static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI,
default:
report_fatal_error("No SEH Opcode for instruction " + TII.getName(Opc));
break;
+ case ARM::CLEANUPRET:
+ case ARM::CATCHRET:
+ break;
case ARM::t2ADDri: // add.w r11, sp, #xx
case ARM::t2ADDri12: // add.w r11, sp, #xx
case ARM::t2MOVTi16: // movt r4, #xx
@@ -2369,6 +2372,9 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
if (!MI.getOperand(i).isFI())
continue;
+ if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE)
+ break;
+
// When using ADDri to get the address of a stack object, 255 is the
// largest offset guaranteed to fit in the immediate offset.
if (MI.getOpcode() == ARM::ADDri) {
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index eb757df6a9f28..c1b5879e10276 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -3838,6 +3838,23 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
SDLoc dl(Op);
switch (IntNo) {
default: return SDValue(); // Don't custom lower most intrinsics.
+ case Intrinsic::localaddress: {
+ const MachineFunction &MF = DAG.getMachineFunction();
+ const TargetRegisterInfo *RegInfo = Subtarget->getRegisterInfo();
+ unsigned Reg = RegInfo->getFrameRegister(MF);
+ return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
+ Op.getSimpleValueType());
+ }
+ case Intrinsic::eh_recoverfp: {
+ SDValue FnOp = Op.getOperand(1);
+ SDValue IncomingFPOp = Op.getOperand(2);
+ GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
+ auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
+ if (!Fn)
+ report_fatal_error(
+ "llvm.eh.recoverfp must take a function as the first argument");
+ return IncomingFPOp;
+ }
case Intrinsic::thread_pointer: {
EVT PtrVT = getPointerTy(DAG.getDataLayout());
return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index b72aa4b28736e..b2c7337041800 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -6725,3 +6725,9 @@ let isPseudo = 1 in {
let isTerminator = 1 in
def SEH_EpilogEnd : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
}
+
+// C++ Exception / SEH Pseudo Instructions
+let isTerminator = 1, isReturn = 1, isBarrier = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
+ def CLEANUPRET : PseudoInst<(outs), (ins), NoItinerary, [(cleanupret bb)]>, Sched<[]>;
+ def CATCHRET : PseudoInst<(outs), (ins arm_br_target:$dst, arm_br_target:$src), NoItinerary, [(catchret bb:$dst, bb:$src)]>, Sched<[]>;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/184953
More information about the cfe-commits
mailing list