[llvm] [AArch64] Enable quad variant st1b/ld1b for callee-saved spills (PR #225100)
Kieran B via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 02:13:48 PDT 2026
================
@@ -2238,49 +2353,69 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters(
// ldp x22, x21, [sp, #0] // addImm(+0)
// Note: see comment in spillCalleeSavedRegisters()
unsigned LdrOpc;
- unsigned Size = TRI->getSpillSize(*RPI.RC);
- Align Alignment = TRI->getSpillAlign(*RPI.RC);
- switch (RPI.Type) {
- case RegPairInfo::GPR:
- LdrOpc = RPI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
+ unsigned Size = TRI->getSpillSize(*RGI.RC);
+ Align Alignment = TRI->getSpillAlign(*RGI.RC);
+ switch (RGI.Type) {
+ case RegGroupInfo::GPR:
+ LdrOpc = RGI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
break;
- case RegPairInfo::FPR64:
- LdrOpc = RPI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
+ case RegGroupInfo::FPR64:
+ LdrOpc = RGI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
break;
- case RegPairInfo::FPR128:
- LdrOpc = RPI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
+ case RegGroupInfo::FPR128:
+ LdrOpc = RGI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
break;
- case RegPairInfo::ZPR:
- LdrOpc = RPI.isPaired() ? AArch64::LD1B_2Z_IMM : AArch64::LDR_ZXI;
+ case RegGroupInfo::ZPR:
+ LdrOpc = RGI.isQuad()
+ ? AArch64::LD1B_4Z_IMM
+ : (RGI.isPaired() ? AArch64::LD1B_2Z_IMM : AArch64::LDR_ZXI);
break;
- case RegPairInfo::PPR:
+ case RegGroupInfo::PPR:
LdrOpc = AArch64::LDR_PXI;
break;
- case RegPairInfo::VG:
+ case RegGroupInfo::VG:
continue;
}
LLVM_DEBUG({
dbgs() << "CSR restore: (" << printReg(Reg1, TRI);
- if (RPI.isPaired())
+ if (RGI.isPaired() || RGI.isQuad())
dbgs() << ", " << printReg(Reg2, TRI);
- dbgs() << ") -> fi#(" << RPI.FrameIdx;
- if (RPI.isPaired())
- dbgs() << ", " << RPI.FrameIdx + 1;
+ if (RGI.isQuad()) {
+ dbgs() << ", " << printReg(Reg3, TRI);
+ dbgs() << ", " << printReg(Reg4, TRI);
+ }
+ dbgs() << ") -> fi#(" << RGI.FrameIdx;
+ if (RGI.isPaired() || RGI.isQuad())
+ dbgs() << ", " << RGI.FrameIdx + 1;
+ if (RGI.isQuad()) {
+ dbgs() << ", " << RGI.FrameIdx + 2;
+ dbgs() << ", " << RGI.FrameIdx + 3;
+ }
dbgs() << ")\n";
});
// Windows unwind codes require consecutive registers if registers are
// paired. Make the switch here, so that the code below will save (x,x+1)
// and not (x+1,x).
- unsigned FrameIdxReg1 = RPI.FrameIdx;
- unsigned FrameIdxReg2 = RPI.FrameIdx + 1;
- if (isTargetWindows(MF) && RPI.isPaired()) {
- std::swap(Reg1, Reg2);
- std::swap(FrameIdxReg1, FrameIdxReg2);
+ unsigned FrameIdxReg1 = RGI.FrameIdx;
+ unsigned FrameIdxReg2 = RGI.FrameIdx + 1;
+ unsigned FrameIdxReg3 = RGI.FrameIdx + 2;
+ unsigned FrameIdxReg4 = RGI.FrameIdx + 3;
+
+ if (isTargetWindows(MF)) {
+ if (RGI.isPaired()) {
+ std::swap(Reg1, Reg2);
+ std::swap(FrameIdxReg1, FrameIdxReg2);
+ } else if (RGI.isQuad()) {
+ std::swap(Reg1, Reg4);
+ std::swap(Reg2, Reg3);
+ std::swap(FrameIdxReg1, FrameIdxReg4);
+ std::swap(FrameIdxReg2, FrameIdxReg3);
+ }
----------------
kieroxide wrote:
Yes, I had a look at this and this swapping only needs to be done for non-scalable pairs.
The scalable branch below doesn't use the swapped local register variables and swaps frame indexes incorrectly.
We can have ZPR groups when we have Windows but not WinCFI.
Only WinCFI is unsupported for ZPR groups.
I have moved this swapping into the non-ZPR branch. I have added a test for Windows without WinCFI too.
https://github.com/llvm/llvm-project/pull/225100
More information about the llvm-commits
mailing list