[llvm] [AArch64][SME] Fix restoring callee-saves from FP with hazard padding (PR #143371)

Sander de Smalen via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 13 00:46:12 PDT 2025


================
@@ -2539,13 +2554,35 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
     // restore the stack pointer from the frame pointer prior to SVE CSR
     // restoration.
     if (AFI->isStackRealigned() || MFI.hasVarSizedObjects()) {
-      if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
+      if (int64_t SVECalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
         // Set SP to start of SVE callee-save area from which they can
-        // be reloaded. The code below will deallocate the stack space
-        // space by moving FP -> SP.
-        emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::FP,
-                        StackOffset::getScalable(-CalleeSavedSize), TII,
-                        MachineInstr::FrameDestroy);
+        // be reloaded.
+        const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
+        if (!AFI->isStackRealigned() && RegInfo->hasBasePointer(MF)) {
+          // If the stack is not realigned we can use the base pointer to find
+          // the start of the SVE callee-saves (and deallocate locals).
+          emitFrameOffset(
+              MBB, RestoreBegin, DL, AArch64::SP, RegInfo->getBaseRegister(),
+              StackOffset::getFixed(NumBytes), TII, MachineInstr::FrameDestroy);
+        } else {
+          Register CalleeSaveBase = AArch64::FP;
+          if (int64_t CalleeSaveBaseOffset =
+                  AFI->getCalleeSaveBaseToFrameRecordOffset()) {
+            // This will find a GPR that is about to be restored -- so safe
+            // to clobber. SVE functions have a "big stack" so always spill at
+            // least one GPR (as a scratch register).
+            CalleeSaveBase = findRestoredCalleeSaveGPR(MF);
----------------
sdesmalen-arm wrote:

Can you use RegisterScavenger and do something like this:
```
RS->enterBasicBlockEnd(MBB);
RS->backward(MBBI); 
Register DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
```
?

https://github.com/llvm/llvm-project/pull/143371


More information about the llvm-commits mailing list