[PATCH] D124615: [AArch64][SVE] Restore SP from base pointer when it and SVE frame are present

Bradley Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 28 07:14:21 PDT 2022


bsmith created this revision.
bsmith added reviewers: paulwalker-arm, peterwaller-arm, sdesmalen.
Herald added subscribers: ctetreau, psnobl, hiraditya, kristof.beyls, tschuett.
Herald added a reviewer: efriedma.
Herald added a project: All.
bsmith requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Without SVE, after a dynamic stack allocation has modified the SP, it is
presumed that a frame pointer restoration will revert the SP back to
it's correct value prior to any caller stack being restored. However the
SVE frame is restored using the stack pointer directly, as it is located
after the frame pointer. This means that in the presence of a dynamic
stack allocation, any SVE callee state gets corrupted as SP has the
incorrect value when the SVE state is restored.

To address this issue, whenever the base pointer is present as well as
an SVE stack frame, we must restore the stack pointer from the base
pointer prior to restoring the SVE state.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124615

Files:
  llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
  llvm/test/CodeGen/AArch64/framelayout-sve.mir
  llvm/test/CodeGen/AArch64/sve-alloca.ll


Index: llvm/test/CodeGen/AArch64/sve-alloca.ll
===================================================================
--- llvm/test/CodeGen/AArch64/sve-alloca.ll
+++ llvm/test/CodeGen/AArch64/sve-alloca.ll
@@ -66,6 +66,7 @@
 ; CHECK-NEXT:    st1d { z1.d }, p0, [x0, #1, mul vl]
 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
 ; CHECK-NEXT:    bl bar
+; CHECK-NEXT:    mov sp, x19
 ; CHECK-NEXT:    ldr p15, [sp, #4, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    ldr p14, [sp, #5, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    ldr p13, [sp, #6, mul vl] // 2-byte Folded Reload
Index: llvm/test/CodeGen/AArch64/framelayout-sve.mir
===================================================================
--- llvm/test/CodeGen/AArch64/framelayout-sve.mir
+++ llvm/test/CodeGen/AArch64/framelayout-sve.mir
@@ -629,6 +629,7 @@
 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
 # CHECK-NEXT: $x19 = ADDXri $sp, 0, 0
 # CHECK-NEXT: STRXui $xzr, $x19, 0
+# CHECK-NEXT: $sp = ADDXri $x19, 0, 0
 # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 1
 # CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
 # CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa $wsp, 32
Index: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1757,6 +1757,7 @@
   MachineFrameInfo &MFI = MF.getFrameInfo();
   const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+  const AArch64RegisterInfo &RegInfo = *Subtarget.getRegisterInfo();
   DebugLoc DL;
   bool NeedsWinCFI = needsWinCFI(MF);
   bool EmitCFI = MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo();
@@ -1909,7 +1910,6 @@
 
     // When we are about to restore the CSRs, the CFA register is SP again.
     if (EmitCFI && hasFP(MF)) {
-      const AArch64RegisterInfo &RegInfo = *Subtarget.getRegisterInfo();
       unsigned Reg = RegInfo.getDwarfRegNum(AArch64::SP, true);
       unsigned CFIIndex =
           MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, NumBytes));
@@ -1953,6 +1953,13 @@
 
   // Deallocate the SVE area.
   if (SVEStackSize) {
+    // If we have a base pointer we must restore the stack pointer from it, we
+    // need to explicitly deallocate variable length stack allocations when we
+    // have an SVE stack frame.
+    if (!IsFunclet && RegInfo.hasBasePointer(MF))
+      TII->copyPhysReg(MBB, RestoreBegin, DL, AArch64::SP,
+                       RegInfo.getBaseRegister(), false);
+
     if (AFI->isStackRealigned()) {
       if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
         // Set SP to start of SVE callee-save area from which they can


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124615.425771.patch
Type: text/x-patch
Size: 2794 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220428/c51323b9/attachment-0001.bin>


More information about the llvm-commits mailing list