[llvm] [AArch64][SME] Resume streaming-mode on entry to exception handlers (PR #156638)
Benjamin Maxwell via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 4 01:49:52 PDT 2025
https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/156638
>From 824f655376ff1675acbad964d31a0f8ca1635762 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 28 Aug 2025 13:14:37 +0000
Subject: [PATCH 1/4] [AArch64][SME] Resume streaming-mode on entry to
exception handlers
This patch adds a new `TargetLowering` hook `lowerEHPadEntry()` that is
called at the start of lowering EH pads in SelectionDAG. This allows
the insertion of target-specific actions on entry to exception handlers.
This is used on AArch64 to insert SME streaming-mode switches at landing
pads. This is needed as exception handlers are always entered with
PSTATE.SM off, and the function needs to resume the streaming mode of
the function body.
---
llvm/include/llvm/CodeGen/TargetLowering.h | 7 +
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 11 +-
.../Target/AArch64/AArch64ISelLowering.cpp | 33 +++
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 3 +
.../AArch64/sme-streaming-mode-landingpads.ll | 198 ++++++++++++++++++
5 files changed, 251 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AArch64/sme-streaming-mode-landingpads.ll
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 438b6ff55c85f..385ee96bfe0b5 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4686,6 +4686,13 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
llvm_unreachable("Not Implemented");
}
+ /// Optional target hook at add target-specific actions when entering EH pad
+ /// blocks. The implementation should return the resulting token chain value.
+ virtual SDValue lowerEHPadEntry(SDValue Chain, const SDLoc &DL,
+ SelectionDAG &DAG) const {
+ return SDValue();
+ }
+
virtual void markLibCallAttributes(MachineFunction *MF, unsigned CC,
ArgListTy &Args) const {}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index ece50ed95fc49..edcc390ba7c12 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1729,10 +1729,19 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Setup an EH landing-pad block.
FuncInfo->ExceptionPointerVirtReg = Register();
FuncInfo->ExceptionSelectorVirtReg = Register();
- if (LLVMBB->isEHPad())
+ if (LLVMBB->isEHPad()) {
if (!PrepareEHLandingPad())
continue;
+ if (!FastIS) {
+ if (SDValue NewRoot = TLI->lowerEHPadEntry(CurDAG->getRoot(),
+ SDB->getCurSDLoc(), *CurDAG);
+ NewRoot && NewRoot != CurDAG->getRoot()) {
+ CurDAG->setRoot(NewRoot);
+ }
+ }
+ }
+
// Before doing SelectionDAG ISel, see if FastISel has been requested.
if (FastIS) {
if (LLVMBB != &Fn.getEntryBlock())
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 23328ed57fb36..ef7fd6dea297e 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7908,6 +7908,39 @@ static bool isPassedInFPR(EVT VT) {
(VT.isFloatingPoint() && !VT.isScalableVector());
}
+SDValue AArch64TargetLowering::lowerEHPadEntry(SDValue Chain, SDLoc const &DL,
+ SelectionDAG &DAG) const {
+ assert(Chain.getOpcode() == ISD::EntryToken && "Unexpected Chain value");
+ SDValue Glue = Chain.getValue(1);
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ SMEAttrs SMEFnAttrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
+
+ // Exception handlers are entered with:
+ // - PSTATE.SM is 0.
+ // - PSTATE.ZA is 0.
+ // - TPIDR2_EL0 is null.
+ // See:
+ // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions
+ //
+ // Therefore, if the function that this exception handler is a
+ // streaming[-compatible] function, we must re-enable streaming mode.
+ //
+ // These mode changes are usually optimized away in catch blocks (as they)
+ // occur before the __cxa_begin_catch (which is a non-streaming function),
+ // but are necessary in some cases (such as for cleanups).
+
+ if (SMEFnAttrs.hasStreamingInterfaceOrBody())
+ return changeStreamingMode(DAG, DL, /*Enable=*/true, Chain,
+ /*Glue*/ Glue, AArch64SME::Always);
+
+ if (SMEFnAttrs.hasStreamingCompatibleInterface())
+ return changeStreamingMode(DAG, DL, /*Enable=*/true, Chain, Glue,
+ AArch64SME::IfCallerIsStreaming);
+
+ return Chain;
+}
+
SDValue AArch64TargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 46738365080f9..77f2a98c8d53f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -575,6 +575,9 @@ class AArch64TargetLowering : public TargetLowering {
bool shouldExpandBuildVectorWithShuffles(EVT, unsigned) const override;
+ SDValue lowerEHPadEntry(SDValue Chain, SDLoc const &DL,
+ SelectionDAG &DAG) const override;
+
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
diff --git a/llvm/test/CodeGen/AArch64/sme-streaming-mode-landingpads.ll b/llvm/test/CodeGen/AArch64/sme-streaming-mode-landingpads.ll
new file mode 100644
index 0000000000000..b583479b21e4b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sme-streaming-mode-landingpads.ll
@@ -0,0 +1,198 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64 -aarch64-streaming-hazard-size=0 -mattr=+sme,+sve -stop-before=finalize-isel -verify-machineinstrs < %s | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnu"
+
+declare void @"StreamingCleanup::~StreamingCleanup"(ptr %this) nounwind "aarch64_pstate_sm_enabled"
+declare void @"StreamingCompatCleanup::~StreamingCompatCleanup"(ptr %this) nounwind "aarch64_pstate_sm_compatible"
+
+declare void @may_throw() "aarch64_pstate_sm_compatible"
+
+; This test models the kind of IR clang would emit for the following C++:
+;
+; struct StreamingCleanup {
+; ~StreamingCleanup() __arm_streaming
+; };
+;
+; void may_throw() __arm_streaming_compatible;
+;
+; void streaming_with_cleanup() __arm_streaming {
+; StreamingCleanup cleanup;
+; may_throw();
+; }
+;
+; This is a streaming function and all callees of this function are streaming[-compatible]
+; functions (including the StreamingCleanup destructor). This means call lowering will not
+; insert any streaming mode switches. However, if "may_throw" throws an exception, the
+; unwinder can re-enter this function (in %unwind_cleanup) to run the "StreamingCleanup"
+; destructor. The unwinder will always re-enter functions with streaming-mode disabled, so
+; we must ensure streaming-mode is enabled on entry to exception handlers.
+define void @streaming_with_cleanup() "aarch64_pstate_sm_enabled" personality ptr @__gxx_personality_v0 {
+ ; CHECK-LABEL: name: streaming_with_cleanup
+ ; CHECK: bb.0 (%ir-block.0):
+ ; CHECK-NEXT: successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: BL @may_throw, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: B %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.normal_return:
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri]]
+ ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.unwind_cleanup (landing-pad):
+ ; CHECK-NEXT: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY killed $x1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY killed $x0
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri1]]
+ ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 0, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit-def $sp, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: $x0 = COPY [[COPY1]]
+ ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ %cleanup = alloca i8, align 1
+ invoke void @may_throw()
+ to label %normal_return unwind label %unwind_cleanup
+
+normal_return:
+ call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)
+ ret void
+
+unwind_cleanup:
+ %eh_info = landingpad { ptr, i32 }
+ cleanup
+ call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)
+ resume { ptr, i32 } %eh_info
+}
+
+; This test is the same as "streaming_with_cleanup", but now the function and destructor
+; are streaming-compatible functions. In this case, when we enter the exception handler,
+; we must switch to streaming-mode "streaming_compatible_with_cleanup" was entered with
+; during normal execution (i.e., EntryPStateSM).
+define void @streaming_compatible_with_cleanup() "aarch64_pstate_sm_compatible" personality ptr @__gxx_personality_v0 {
+ ; CHECK-LABEL: name: streaming_compatible_with_cleanup
+ ; CHECK: bb.0 (%ir-block.0):
+ ; CHECK-NEXT: successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[EntryPStateSM:%[0-9]+]]:gpr64 = EntryPStateSM
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: BL @may_throw, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: B %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.normal_return:
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri]]
+ ; CHECK-NEXT: BL @"StreamingCompatCleanup::~StreamingCompatCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.unwind_cleanup (landing-pad):
+ ; CHECK-NEXT: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY killed $x1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY killed $x0
+ ; CHECK-NEXT: MSRpstatePseudo 1, 1, 1, [[EntryPStateSM]], csr_aarch64_smstartstop, implicit-def dead $vg, implicit $vg, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri1]]
+ ; CHECK-NEXT: BL @"StreamingCompatCleanup::~StreamingCompatCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatePseudo 1, 0, 1, [[EntryPStateSM]], csr_aarch64_smstartstop, implicit-def $vg, implicit $vg, implicit-def $sp, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: $x0 = COPY [[COPY1]]
+ ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp, implicit-def $vg
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatePseudo 1, 1, 1, [[EntryPStateSM]], csr_aarch64_smstartstop, implicit-def dead $vg, implicit $vg, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ %cleanup = alloca i8, align 1
+ invoke void @may_throw()
+ to label %normal_return unwind label %unwind_cleanup
+
+normal_return:
+ call void @"StreamingCompatCleanup::~StreamingCompatCleanup"(ptr %cleanup)
+ ret void
+
+unwind_cleanup:
+ %eh_info = landingpad { ptr, i32 }
+ cleanup
+ call void @"StreamingCompatCleanup::~StreamingCompatCleanup"(ptr %cleanup)
+ resume { ptr, i32 } %eh_info
+}
+
+; This is the same as "streaming_with_cleanup" but for a locally streaming function.
+; The lowering of "unwind_cleanup" is expected to match "streaming_with_cleanup".
+define void @locally_streaming_with_cleanup() "aarch64_pstate_sm_body" personality ptr @__gxx_personality_v0 {
+ ; CHECK-LABEL: name: locally_streaming_with_cleanup
+ ; CHECK: bb.0 (%ir-block.0):
+ ; CHECK-NEXT: successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: BL @may_throw, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: B %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.normal_return:
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri]]
+ ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 0, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.unwind_cleanup (landing-pad):
+ ; CHECK-NEXT: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: EH_LABEL <mcsymbol >
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY killed $x1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY killed $x0
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri1]]
+ ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 0, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit-def $sp, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ ; CHECK-NEXT: $x0 = COPY [[COPY1]]
+ ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr
+ %cleanup = alloca i8, align 1
+ invoke void @may_throw()
+ to label %normal_return unwind label %unwind_cleanup
+
+normal_return:
+ call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)
+ ret void
+
+unwind_cleanup:
+ %eh_info = landingpad { ptr, i32 }
+ cleanup
+ call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)
+ resume { ptr, i32 } %eh_info
+}
+
+declare i32 @__gxx_personality_v0(...)
>From ecec3ae53a7c31af49553e4cb47ecc56ae03dff3 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Wed, 3 Sep 2025 10:25:57 +0000
Subject: [PATCH 2/4] Fix typo
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ef7fd6dea297e..753d617f22f2a 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7923,7 +7923,7 @@ SDValue AArch64TargetLowering::lowerEHPadEntry(SDValue Chain, SDLoc const &DL,
// See:
// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions
//
- // Therefore, if the function that this exception handler is a
+ // Therefore, if the function that contains this exception handler is a
// streaming[-compatible] function, we must re-enable streaming mode.
//
// These mode changes are usually optimized away in catch blocks (as they)
>From ac22ed1a05bd85a53d59407869dc766b1de4b4a6 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Wed, 3 Sep 2025 16:26:08 +0000
Subject: [PATCH 3/4] Fixups
---
llvm/include/llvm/CodeGen/TargetLowering.h | 2 +-
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 7 +++----
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 385ee96bfe0b5..1072d8847452b 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4686,7 +4686,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
llvm_unreachable("Not Implemented");
}
- /// Optional target hook at add target-specific actions when entering EH pad
+ /// Optional target hook to add target-specific actions when entering EH pad
/// blocks. The implementation should return the resulting token chain value.
virtual SDValue lowerEHPadEntry(SDValue Chain, const SDLoc &DL,
SelectionDAG &DAG) const {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index edcc390ba7c12..e61558c59bf0d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1734,11 +1734,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
continue;
if (!FastIS) {
- if (SDValue NewRoot = TLI->lowerEHPadEntry(CurDAG->getRoot(),
- SDB->getCurSDLoc(), *CurDAG);
- NewRoot && NewRoot != CurDAG->getRoot()) {
+ SDValue NewRoot = TLI->lowerEHPadEntry(CurDAG->getRoot(),
+ SDB->getCurSDLoc(), *CurDAG);
+ if (NewRoot && NewRoot != CurDAG->getRoot())
CurDAG->setRoot(NewRoot);
- }
}
}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 753d617f22f2a..4464354aa3517 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7926,7 +7926,7 @@ SDValue AArch64TargetLowering::lowerEHPadEntry(SDValue Chain, SDLoc const &DL,
// Therefore, if the function that contains this exception handler is a
// streaming[-compatible] function, we must re-enable streaming mode.
//
- // These mode changes are usually optimized away in catch blocks (as they)
+ // These mode changes are usually optimized away in catch blocks as they
// occur before the __cxa_begin_catch (which is a non-streaming function),
// but are necessary in some cases (such as for cleanups).
>From 2189653b3e2e6f2decadefd62ad4b15a9ff97293 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 4 Sep 2025 08:48:00 +0000
Subject: [PATCH 4/4] Reword
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 4464354aa3517..0473e16b6afe9 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7916,7 +7916,7 @@ SDValue AArch64TargetLowering::lowerEHPadEntry(SDValue Chain, SDLoc const &DL,
MachineFunction &MF = DAG.getMachineFunction();
SMEAttrs SMEFnAttrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
- // Exception handlers are entered with:
+ // The following conditions are true on entry to an exception handler:
// - PSTATE.SM is 0.
// - PSTATE.ZA is 0.
// - TPIDR2_EL0 is null.
More information about the llvm-commits
mailing list