[llvm] AArch64: Mark status flag clobbers dead in SME ABI pass (PR #228042)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 06:27:35 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/228042
>From 7a44bc927d31bce451d323ed19edb2a3c53be947 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 29 Sep 2026 02:57:45 +0200
Subject: [PATCH] AArch64: Mark status flag clobbers dead in SME ABI pass
Co-authored-by: Claude Opus 5 <noreply at anthropic.com>
---
llvm/lib/Target/AArch64/MachineSMEABIPass.cpp | 9 ++++++---
.../AArch64/machine-sme-abi-dead-nzcv.ll | 20 +++++++++++++++++++
2 files changed, 26 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/machine-sme-abi-dead-nzcv.ll
diff --git a/llvm/lib/Target/AArch64/MachineSMEABIPass.cpp b/llvm/lib/Target/AArch64/MachineSMEABIPass.cpp
index 5dd62d1d66278..a09a9db6a3ad4 100644
--- a/llvm/lib/Target/AArch64/MachineSMEABIPass.cpp
+++ b/llvm/lib/Target/AArch64/MachineSMEABIPass.cpp
@@ -767,7 +767,8 @@ PhysRegSave MachineSMEABI::createPhysRegSave(LiveRegs PhysLiveRegs,
RegSave.StatusFlags = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
BuildMI(MBB, MBBI, DL, TII->get(AArch64::MRS), RegSave.StatusFlags)
.addImm(AArch64SysReg::NZCV)
- .addReg(AArch64::NZCV, RegState::Implicit);
+ .addReg(AArch64::NZCV, RegState::Implicit)
+ .setOperandDead(2); // implicit-def $nzcv
}
// Note: Preserving X0 is "free" as this is before register allocation, so
// the register allocator is still able to optimize these copies.
@@ -828,7 +829,8 @@ void MachineSMEABI::emitRestoreLazySave(EmitContext &Context,
.addImm(1);
// Get current TPIDR2_EL0.
BuildMI(MBB, MBBI, DL, TII->get(AArch64::MRS), TPIDR2EL0)
- .addImm(AArch64SysReg::TPIDR2_EL0);
+ .addImm(AArch64SysReg::TPIDR2_EL0)
+ .setOperandDead(2); // implicit-def $nzcv
// Get pointer to TPIDR2 block.
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri), TPIDR2)
.addFrameIndex(Context.getTPIDR2Block(*MF))
@@ -933,7 +935,8 @@ void MachineSMEABI::emitSMEPrologue(MachineBasicBlock &MBB,
Register TPIDR2EL0 = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
BuildMI(MBB, MBBI, DL, TII->get(AArch64::MRS))
.addReg(TPIDR2EL0, RegState::Define)
- .addImm(AArch64SysReg::TPIDR2_EL0);
+ .addImm(AArch64SysReg::TPIDR2_EL0)
+ .setOperandDead(2); // implicit-def $nzcv
// If TPIDR2_EL0 is non-zero, commit the lazy save.
// NOTE: Functions that only use ZT0 don't need to zero ZA.
auto CommitZASave =
diff --git a/llvm/test/CodeGen/AArch64/machine-sme-abi-dead-nzcv.ll b/llvm/test/CodeGen/AArch64/machine-sme-abi-dead-nzcv.ll
new file mode 100644
index 0000000000000..2f4553eae1eac
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/machine-sme-abi-dead-nzcv.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64 -mattr=+sme -stop-after=aarch64-machine-sme-abi < %s | FileCheck %s
+
+declare void @shared_za_callee() "aarch64_inout_za"
+
+define void @private_za() "aarch64_new_za" {
+ ; CHECK-LABEL: name: private_za
+ ; CHECK: bb.0 (%ir-block.0):
+ ; CHECK-NEXT: [[MRS:%[0-9]+]]:gpr64 = MRS 56965, implicit-def dead $nzcv
+ ; CHECK-NEXT: CommitZASavePseudo [[MRS]], 1, 0, &__arm_tpidr2_save, csr_aarch64_sme_abi_support_routines_preservemost_from_x0, implicit-def $zab0
+ ; CHECK-NEXT: MSRpstatesvcrImm1 2, 1, implicit-def dead $nzcv
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
+ ; CHECK-NEXT: InOutZAUsePseudo
+ ; CHECK-NEXT: BL @shared_za_callee, 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: MSRpstatesvcrImm1 2, 0, implicit-def dead $nzcv
+ ; CHECK-NEXT: RET_ReallyLR
+ call void @shared_za_callee()
+ ret void
+}
More information about the llvm-commits
mailing list