[llvm] [AArch64] Remove copy in SVE/SME predicate spill (PR #81716)
Sam Tebbs via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 14 01:18:09 PST 2024
https://github.com/SamTebbs33 created https://github.com/llvm/llvm-project/pull/81716
7dc20ab introduced an extra COPY when spilling a PNR register, which can't be elided as the input (PNR predicate) and output (PPR predicate) register classes differ. This patch emits a new ConvertPNRtoPPR pseudo instruction instead. When this is expanded, it gets erased if the PNR is a subregister of the PPR, since the conversion is implicit, otherwise it is lowered to an ORR.
>From fb0a7681df70fb8a40bf8bcbda2e165da685ef18 Mon Sep 17 00:00:00 2001
From: Samuel Tebbs <samuel.tebbs at arm.com>
Date: Tue, 13 Feb 2024 11:23:34 +0000
Subject: [PATCH] [AArch64] Remove copy in SVE/SME predicate spill
7dc20ab introduced an extra COPY when spilling a PNR register, which
can't be elided as the input (PNR predicate) and output (PPR predicate)
register classes differ. This patch emits a new ConvertPNRtoPPR
pseudo instruction instead. When this is expanded, it gets erased if the
PNR is a subregister of the PPR, since the conversion is implicit,
otherwise it is lowered to an ORR.
---
.../AArch64/AArch64ExpandPseudoInsts.cpp | 17 +++++++++++
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 6 ++--
.../lib/Target/AArch64/AArch64SVEInstrInfo.td | 2 ++
.../spillfill-sve-different-predicate.mir | 30 +++++++++++++++++++
llvm/test/CodeGen/AArch64/spillfill-sve.mir | 3 +-
5 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 352c61d48e2fff..7dfd4ed5b38cff 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -1119,6 +1119,23 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
default:
break;
+ case AArch64::ConvertPNRtoPPR: {
+ auto TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
+ MachineOperand DstMO = MI.getOperand(0);
+ MachineOperand SrcMO = MI.getOperand(1);
+ unsigned SrcReg = SrcMO.getReg();
+ if (!TRI->isSubRegister(DstMO.getReg(), SrcReg)) {
+ unsigned SrcSuperReg = TRI->getMatchingSuperReg(SrcReg, AArch64::psub,
+ &AArch64::PPRRegClass);
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORR_PPzPP))
+ .add(DstMO)
+ .addReg(SrcSuperReg)
+ .addReg(SrcSuperReg)
+ .addReg(SrcSuperReg);
+ }
+ MI.eraseFromParent();
+ return true;
+ }
case AArch64::BSPv8i8:
case AArch64::BSPv16i8: {
Register DstReg = MI.getOperand(0).getReg();
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 656259727c124f..01c3a1c92d07d7 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -4789,6 +4789,7 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
bool Offset = true;
MCRegister PNRReg = MCRegister::NoRegister;
unsigned StackID = TargetStackID::Default;
+ const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();
switch (TRI->getSpillSize(*RC)) {
case 1:
if (AArch64::FPR8RegClass.hasSubClassEq(RC))
@@ -4807,8 +4808,9 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
"Unexpected register store without SVE2p1 or SME2");
if (SrcReg.isVirtual()) {
auto NewSrcReg =
- MF.getRegInfo().createVirtualRegister(&AArch64::PPRRegClass);
- BuildMI(MBB, MBBI, DebugLoc(), get(TargetOpcode::COPY), NewSrcReg)
+ MF.getRegInfo().createVirtualRegister(&AArch64::PPR_p8to15RegClass);
+ BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ConvertPNRtoPPR),
+ NewSrcReg)
.addReg(SrcReg);
SrcReg = NewSrcReg;
} else
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index c4d69232c9e30e..92d4c3774908e2 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -2308,6 +2308,8 @@ let Predicates = [HasBF16, HasSVEorSME] in {
defm BFCVTNT_ZPmZ : sve_bfloat_convert<0b0, "bfcvtnt", int_aarch64_sve_fcvtnt_bf16f32>;
} // End HasBF16, HasSVEorSME
+def ConvertPNRtoPPR : Pseudo<(outs PPRAny:$Pd), (ins PNRAny:$Pm), []>, Sched<[]>;
+
let Predicates = [HasSVEorSME] in {
// InstAliases
def : InstAlias<"mov $Zd, $Zn",
diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir b/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir
new file mode 100644
index 00000000000000..abbc1d615b66f7
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir
@@ -0,0 +1,30 @@
+# RUN: llc -mtriple=aarch64-linux-gnu -start-after=virtregrewriter -stop-after=aarch64-expand-pseudo -mattr=+sme2 -verify-machineinstrs -o - %s \
+# RUN: | FileCheck %s
+
+--- |
+ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64-unknown-linux-gnu"
+
+ define void @test_convert_different_reg() #0 { entry: unreachable }
+
+ attributes #0 = { "target-features"="+sme2" }
+
+---
+name: test_convert_different_reg
+tracksRegLiveness: true
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_convert_different_reg
+ ; CHECK: renamable $pn8 = WHILEGE_CXX_B undef $x0, undef $x0, 0, implicit-def dead $nzcv
+ ; CHECK-NEXT: renamable $p9 = ORR_PPzPP $p8, $p8, $p8
+ ; CHECK-NEXT: STR_PXI killed renamable $p9, $sp, 7
+ ; CHECK-NEXT: renamable $p0 = LDR_PXI $sp, 7
+ early-clobber $sp = frame-setup STRXpre killed $fp, $sp, -16
+ frame-setup CFI_INSTRUCTION escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22
+ frame-setup CFI_INSTRUCTION offset $w29, -16
+ renamable $pn8 = WHILEGE_CXX_B undef $x0, undef $x0, 0, implicit-def dead $nzcv
+ renamable $p9 = ConvertPNRtoPPR killed renamable $pn8
+ STR_PXI killed renamable $p9, $sp, 7
+ renamable $p0 = LDR_PXI $sp, 7
+ early-clobber $sp, $fp = frame-destroy LDRXpost $sp, 16
+ RET undef $lr
diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve.mir b/llvm/test/CodeGen/AArch64/spillfill-sve.mir
index ef7d55a1c2395f..af062d33c5642f 100644
--- a/llvm/test/CodeGen/AArch64/spillfill-sve.mir
+++ b/llvm/test/CodeGen/AArch64/spillfill-sve.mir
@@ -213,8 +213,7 @@ body: |
; EXPAND-LABEL: name: spills_fills_stack_id_virtreg_pnr
; EXPAND: renamable $pn8 = WHILEGE_CXX_B
- ; EXPAND: $p0 = ORR_PPzPP $p8, $p8, killed $p8
- ; EXPAND: STR_PXI killed renamable $p0, $sp, 7
+ ; EXPAND: STR_PXI killed renamable $p8, $sp, 7
;
; EXPAND: renamable $p0 = LDR_PXI $sp, 7
; EXPAND: $p8 = ORR_PPzPP $p0, $p0, killed $p0, implicit-def $pn8
More information about the llvm-commits
mailing list