[llvm] r280705 - [PPC] Claim stack frame before storing into it, if no red zone is present

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 6 05:30:03 PDT 2016


Author: kparzysz
Date: Tue Sep  6 07:30:00 2016
New Revision: 280705

URL: http://llvm.org/viewvc/llvm-project?rev=280705&view=rev
Log:
[PPC] Claim stack frame before storing into it, if no red zone is present

Unlike PPC64, PPC32/SVRV4 does not have red zone. In the absence of it 
there is no guarantee that this part of the stack will not be modified 
by any interrupt. To avoid this, make sure to claim the stack frame first
before storing into it.

This fixes https://llvm.org/bugs/show_bug.cgi?id=26519.

Differential Revision: https://reviews.llvm.org/D24093

Modified:
    llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
    llvm/trunk/test/CodeGen/PowerPC/crsave.ll
    llvm/trunk/test/CodeGen/PowerPC/empty-functions.ll
    llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll
    llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll
    llvm/trunk/test/CodeGen/PowerPC/stack-realign.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp?rev=280705&r1=280704&r2=280705&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp Tue Sep  6 07:30:00 2016
@@ -672,8 +672,9 @@ PPCFrameLowering::twoUniqueScratchRegsRe
   bool IsLargeFrame = !isInt<16>(NegFrameSize);
   MachineFrameInfo &MFI = MF.getFrameInfo();
   unsigned MaxAlign = MFI.getMaxAlignment();
+  bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
 
-  return IsLargeFrame && HasBP && MaxAlign > 1;
+  return (IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1;
 }
 
 bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
@@ -742,6 +743,7 @@ void PPCFrameLowering::emitPrologue(Mach
   // Do we have a frame pointer and/or base pointer for this function?
   bool HasFP = hasFP(MF);
   bool HasBP = RegInfo->hasBasePointer(MF);
+  bool HasRedZone = isPPC64 || !isSVR4ABI;
 
   unsigned SPReg       = isPPC64 ? PPC::X1  : PPC::R1;
   unsigned BPReg       = RegInfo->getBaseRegister(MF);
@@ -876,54 +878,57 @@ void PPCFrameLowering::emitPrologue(Mach
       MIB.addReg(MustSaveCRs[i], CrState);
   }
 
-  if (HasFP)
-    // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
-    BuildMI(MBB, MBBI, dl, StoreInst)
-      .addReg(FPReg)
-      .addImm(FPOffset)
-      .addReg(SPReg);
-
-  if (FI->usesPICBase())
-    // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
-    BuildMI(MBB, MBBI, dl, StoreInst)
-      .addReg(PPC::R30)
-      .addImm(PBPOffset)
-      .addReg(SPReg);
-
-  if (HasBP)
-    // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
-    BuildMI(MBB, MBBI, dl, StoreInst)
-      .addReg(BPReg)
-      .addImm(BPOffset)
-      .addReg(SPReg);
+  if (HasRedZone) {
+    if (HasFP)
+      BuildMI(MBB, MBBI, dl, StoreInst)
+        .addReg(FPReg)
+        .addImm(FPOffset)
+        .addReg(SPReg);
+    if (FI->usesPICBase())
+      BuildMI(MBB, MBBI, dl, StoreInst)
+        .addReg(PPC::R30)
+        .addImm(PBPOffset)
+        .addReg(SPReg);
+    if (HasBP)
+      BuildMI(MBB, MBBI, dl, StoreInst)
+        .addReg(BPReg)
+        .addImm(BPOffset)
+        .addReg(SPReg);
+  }
 
   if (MustSaveLR)
-    // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
     BuildMI(MBB, MBBI, dl, StoreInst)
       .addReg(ScratchReg, getKillRegState(true))
       .addImm(LROffset)
       .addReg(SPReg);
 
   if (MustSaveCR &&
-      !(SingleScratchReg && MustSaveLR)) // will only occur for PPC64
+      !(SingleScratchReg && MustSaveLR)) { // will only occur for PPC64
+    assert(HasRedZone && "A red zone is always available on PPC64");
     BuildMI(MBB, MBBI, dl, TII.get(PPC::STW8))
       .addReg(TempReg, getKillRegState(true))
       .addImm(8)
       .addReg(SPReg);
+  }
 
   // Skip the rest if this is a leaf function & all spills fit in the Red Zone.
-  if (!FrameSize) return;
+  if (!FrameSize)
+    return;
 
   // Adjust stack pointer: r1 += NegFrameSize.
   // If there is a preferred stack alignment, align R1 now
 
-  if (HasBP) {
+  if (HasBP && HasRedZone) {
     // Save a copy of r1 as the base pointer.
     BuildMI(MBB, MBBI, dl, OrInst, BPReg)
       .addReg(SPReg)
       .addReg(SPReg);
   }
 
+  // Have we generated a STUX instruction to claim stack frame? If so,
+  // the frame size will be placed in ScratchReg.
+  bool HasSTUX = false;
+
   // This condition must be kept in sync with canUseAsPrologue.
   if (HasBP && MaxAlign > 1) {
     if (isPPC64)
@@ -952,10 +957,12 @@ void PPCFrameLowering::emitPrologue(Mach
         .addReg(ScratchReg, RegState::Kill)
         .addReg(TempReg, RegState::Kill);
     }
+
     BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
       .addReg(SPReg, RegState::Kill)
       .addReg(SPReg)
       .addReg(ScratchReg);
+    HasSTUX = true;
 
   } else if (!isLargeFrame) {
     BuildMI(MBB, MBBI, dl, StoreUpdtInst, SPReg)
@@ -973,6 +980,65 @@ void PPCFrameLowering::emitPrologue(Mach
       .addReg(SPReg, RegState::Kill)
       .addReg(SPReg)
       .addReg(ScratchReg);
+    HasSTUX = true;
+  }
+
+  if (!HasRedZone) {
+    assert(!isPPC64 && "A red zone is always available on PPC64");
+    if (HasSTUX) {
+      // The frame size is in ScratchReg, and the SPReg has been advanced
+      // (downwards) by the frame size: SPReg = old SPReg + ScratchReg.
+      // Set ScratchReg to the original SPReg: ScratchReg = SPReg - ScratchReg.
+      BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
+        .addReg(ScratchReg, RegState::Kill)
+        .addReg(SPReg);
+
+      // Now that the stack frame has been allocated, save all the necessary
+      // registers using ScratchReg as the base address.
+      if (HasFP)
+        BuildMI(MBB, MBBI, dl, StoreInst)
+          .addReg(FPReg)
+          .addImm(FPOffset)
+          .addReg(ScratchReg);
+      if (FI->usesPICBase())
+        BuildMI(MBB, MBBI, dl, StoreInst)
+          .addReg(PPC::R30)
+          .addImm(PBPOffset)
+          .addReg(ScratchReg);
+      if (HasBP) {
+        BuildMI(MBB, MBBI, dl, StoreInst)
+          .addReg(BPReg)
+          .addImm(BPOffset)
+          .addReg(ScratchReg);
+        BuildMI(MBB, MBBI, dl, OrInst, BPReg)
+          .addReg(ScratchReg, RegState::Kill)
+          .addReg(ScratchReg);
+      }
+    } else {
+      // The frame size is a known 16-bit constant (fitting in the immediate
+      // field of STWU). To be here we have to be compiling for PPC32.
+      // Since the SPReg has been decreased by FrameSize, add it back to each
+      // offset.
+      if (HasFP)
+        BuildMI(MBB, MBBI, dl, StoreInst)
+          .addReg(FPReg)
+          .addImm(FrameSize + FPOffset)
+          .addReg(SPReg);
+      if (FI->usesPICBase())
+        BuildMI(MBB, MBBI, dl, StoreInst)
+          .addReg(PPC::R30)
+          .addImm(FrameSize + PBPOffset)
+          .addReg(SPReg);
+      if (HasBP) {
+        BuildMI(MBB, MBBI, dl, StoreInst)
+          .addReg(BPReg)
+          .addImm(FrameSize + BPOffset)
+          .addReg(SPReg);
+        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), BPReg)
+          .addReg(SPReg)
+          .addImm(FrameSize);
+      }
+    }
   }
 
   // Add Call Frame Information for the instructions we generated above.

Modified: llvm/trunk/test/CodeGen/PowerPC/crsave.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/crsave.ll?rev=280705&r1=280704&r2=280705&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/crsave.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/crsave.ll Tue Sep  6 07:30:00 2016
@@ -14,8 +14,9 @@ entry:
   ret i32 %1
 }
 
-; PPC32: stw 31, -4(1)
+; PPC32-LABEL: test_cr2:
 ; PPC32: stwu 1, -32(1)
+; PPC32: stw 31, 28(1)
 ; PPC32: mfcr 12
 ; PPC32-NEXT: stw 12, 24(31)
 ; PPC32: lwz 12, 24(31)
@@ -43,8 +44,9 @@ entry:
   ret i32 %1
 }
 
-; PPC32: stw 31, -4(1)
+; PPC32-LABEL: test_cr234:
 ; PPC32: stwu 1, -32(1)
+; PPC32: stw 31, 28(1)
 ; PPC32: mfcr 12
 ; PPC32-NEXT: stw 12, 24(31)
 ; PPC32: lwz 12, 24(31)

Modified: llvm/trunk/test/CodeGen/PowerPC/empty-functions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/empty-functions.ll?rev=280705&r1=280704&r2=280705&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/empty-functions.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/empty-functions.ll Tue Sep  6 07:30:00 2016
@@ -31,8 +31,8 @@ entry:
 ; LINUX-FP-NEXT: {{^}}.L[[BEGIN:.*]]:{{$}}
 ; LINUX-FP-NEXT: .cfi_startproc
 ; LINUX-FP-NEXT: {{^}}#
-; LINUX-FP-NEXT: stw 31, -4(1)
 ; LINUX-FP-NEXT: stwu 1, -16(1)
+; LINUX-FP-NEXT: stw 31, 12(1)
 ; LINUX-FP-NEXT: {{^}}.L{{.*}}:{{$}}
 ; LINUX-FP-NEXT:  .cfi_def_cfa_offset 16
 ; LINUX-FP-NEXT: {{^}}.L{{.*}}:{{$}}

Modified: llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll?rev=280705&r1=280704&r2=280705&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/ppc32-pic-large.ll Tue Sep  6 07:30:00 2016
@@ -15,7 +15,8 @@ entry:
 ; LARGE-BSS:       [[POFF:\.L[0-9]+\$poff]]:
 ; LARGE-BSS-NEXT:    .long .LTOC-[[PB:\.L[0-9]+\$pb]]
 ; LARGE-BSS-NEXT:  foo:
-; LARGE-BSS:         stw 30, -8(1)
+; LARGE-BSS:         stwu 1, -32(1)
+; LARGE-BSS:         stw 30, 24(1)
 ; LARGE-BSS:         bl [[PB]]
 ; LARGE-BSS-NEXT:  [[PB]]:
 ; LARGE-BSS:         mflr 30

Modified: llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll?rev=280705&r1=280704&r2=280705&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/ppc32-pic.ll Tue Sep  6 07:30:00 2016
@@ -13,8 +13,8 @@ entry:
 !llvm.module.flags = !{!0}
 !0 = !{i32 1, !"PIC Level", i32 1}
 ; SMALL-BSS-LABEL:foo:
-; SMALL-BSS:         stw 30, -8(1)
 ; SMALL-BSS:         stwu 1, -32(1)
+; SMALL-BSS:         stw 30, 24(1)
 ; SMALL-BSS:         bl _GLOBAL_OFFSET_TABLE_ at local-4
 ; SMALL-BSS:         mflr 30
 ; SMALL-BSS-DAG:     stw {{[0-9]+}}, 8(1)

Modified: llvm/trunk/test/CodeGen/PowerPC/stack-realign.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/stack-realign.ll?rev=280705&r1=280704&r2=280705&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/stack-realign.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/stack-realign.ll Tue Sep  6 07:30:00 2016
@@ -77,22 +77,24 @@ entry:
 ; CHECK-FP: blr
 
 ; CHECK-32-LABEL: @goo
-; CHECK-32-DAG: mflr {{[0-9]+}}
+; CHECK-32-DAG: mflr [[LR:[0-9]+]]
 ; CHECK-32-DAG: clrlwi [[REG:[0-9]+]], 1, 27
-; CHECK-32-DAG: stw 30, -8(1)
-; CHECK-32-DAG: mr 30, 1
-; CHECK-32-DAG: stw 0, 4(1)
+; CHECK-32-DAG: stw [[LR]], 4(1)
 ; CHECK-32-DAG: subfic 0, [[REG]], -64
 ; CHECK-32: stwux 1, 1, 0
+; CHECK-32: subf 0, 0, 1
+; CHECK-32: stw 30, -8(0)
+; CHECK-32: mr 30, 0
 
 ; CHECK-32-PIC-LABEL: @goo
-; CHECK-32-PIC-DAG: mflr {{[0-9]+}}
+; CHECK-32-PIC-DAG: mflr [[LR:[0-9]+]]
 ; CHECK-32-PIC-DAG: clrlwi [[REG:[0-9]+]], 1, 27
-; CHECK-32-PIC-DAG: stw 29, -12(1)
-; CHECK-32-PIC-DAG: mr 29, 1
-; CHECK-32-PIC-DAG: stw 0, 4(1)
+; CHECK-32-PIC-DAG: stw [[LR]], 4(1)
 ; CHECK-32-PIC-DAG: subfic 0, [[REG]], -64
 ; CHECK-32-PIC: stwux 1, 1, 0
+; CHECK-32-PIC: subf 0, 0, 1
+; CHECK-32-PIC: stw 29, -12(0)
+; CHECK-32-PIC-DAG: mr 29, 0
 
 ; The large-frame-size case.
 define void @hoo(%struct.s* byval nocapture readonly %a) {
@@ -130,13 +132,15 @@ entry:
 
 ; CHECK-32-DAG: lis [[REG1:[0-9]+]], -13
 ; CHECK-32-DAG: clrlwi [[REG3:[0-9]+]], 1, 27
-; CHECK-32-DAG: mflr {{[0-9]+}}
+; CHECK-32-DAG: mflr [[LR:[0-9]+]]
 ; CHECK-32-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
-; CHECK-32-DAG: stw 30, -8(1)
-; CHECK-32-DAG: mr 30, 1
-; CHECK-32-DAG: stw 0, 4(1)
+; CHECK-32-DAG: stw [[LR]], 4(1)
 ; CHECK-32-DAG: subfc 0, [[REG3]], [[REG2]]
-; CHECK-32: stwux 1, 1, 0
+; CHECK-32:     stwux 1, 1, 0
+; CHECK-32:     subf 0, 0, 1
+; CHECK-32-DAG: stw 31, -4(0)
+; CHECK-32-DAG: stw 30, -8(0)
+; CHECK-32: mr 30, 0
 
 ; CHECK-32: blr
 
@@ -146,11 +150,12 @@ entry:
 ; CHECK-32-PIC-DAG: clrlwi [[REG3:[0-9]+]], 1, 27
 ; CHECK-32-PIC-DAG: mflr {{[0-9]+}}
 ; CHECK-32-PIC-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
-; CHECK-32-PIC-DAG: stw 29, -12(1)
-; CHECK-32-PIC-DAG: mr 29, 1
 ; CHECK-32-PIC-DAG: stw 0, 4(1)
 ; CHECK-32-PIC-DAG: subfc 0, [[REG3]], [[REG2]]
-; CHECK-32: stwux 1, 1, 0
+; CHECK-32-PIC: stwux 1, 1, 0
+; CHECK-32-PIC: stw 29, -12(0)
+; CHECK-32-PIC: subf 0, 0, 1
+; CHECK-32-PIC: mr 29, 0
 
 ; CHECK-32: blr
 




More information about the llvm-commits mailing list