[llvm] r246042 - [SPARC] Fix stupid oversight in stack realignment support.

James Y Knight via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 10:57:52 PDT 2015


Author: jyknight
Date: Wed Aug 26 12:57:51 2015
New Revision: 246042

URL: http://llvm.org/viewvc/llvm-project?rev=246042&view=rev
Log:
[SPARC] Fix stupid oversight in stack realignment support.

If you're going to realign %sp to get object alignment properly (which
the code does), and stack offsets and alignments are calculated going
down from %fp (which they are), then the total stack size had better
be a multiple of the alignment. LLVM did indeed ensure that.

And then, after aligning, the sparc frame code added 96 (for sparcv8)
to the frame size, making any requested alignment of 64-bytes or
higher *guaranteed* to be misaligned. The test case added with r245668
even tests this exact scenario, and asserted the incorrect behavior,
which I somehow failed to notice. D'oh.

This change fixes the frame lowering code to align the stack size
*after* adding the spill area, instead.

Differential Revision: http://reviews.llvm.org/D12349

Modified:
    llvm/trunk/lib/Target/Sparc/SparcFrameLowering.cpp
    llvm/trunk/lib/Target/Sparc/SparcFrameLowering.h
    llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp
    llvm/trunk/test/CodeGen/SPARC/stack-align.ll

Modified: llvm/trunk/lib/Target/Sparc/SparcFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcFrameLowering.cpp?rev=246042&r1=246041&r2=246042&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcFrameLowering.cpp Wed Aug 26 12:57:51 2015
@@ -118,8 +118,37 @@ void SparcFrameLowering::emitPrologue(Ma
     SAVErr = SP::ADDrr;
   }
 
+  // The SPARC ABI is a bit odd in that it requires a reserved 92-byte
+  // (128 in v9) area in the user's stack, starting at %sp. Thus, the
+  // first part of the stack that can actually be used is located at
+  // %sp + 92.
+  //
+  // We therefore need to add that offset to the total stack size
+  // after all the stack objects are placed by
+  // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack needs to be
+  // aligned *after* the extra size is added, we need to disable
+  // calculateFrameObjectOffsets's built-in stack alignment, by having
+  // targetHandlesStackFrameRounding return true.
+
+
+  // Add the extra call frame stack size, if needed. (This is the same
+  // code as in PrologEpilogInserter, but also gets disabled by
+  // targetHandlesStackFrameRounding)
+  if (MFI->adjustsStack() && hasReservedCallFrame(MF))
+    NumBytes += MFI->getMaxCallFrameSize();
+
+  // Adds the SPARC subtarget-specific spill area to the stack
+  // size. Also ensures target-required alignment.
   NumBytes = MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes);
-  MFI->setStackSize(NumBytes); // Update stack size with corrected value.
+
+  // Finally, ensure that the size is sufficiently aligned for the
+  // data on the stack.
+  if (MFI->getMaxAlignment() > 0) {
+    NumBytes = RoundUpToAlignment(NumBytes, MFI->getMaxAlignment());
+  }
+
+  // Update stack size with corrected value.
+  MFI->setStackSize(NumBytes);
 
   emitSPAdjustment(MF, MBB, MBBI, -NumBytes, SAVErr, SAVEri);
 

Modified: llvm/trunk/lib/Target/Sparc/SparcFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcFrameLowering.h?rev=246042&r1=246041&r2=246042&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcFrameLowering.h (original)
+++ llvm/trunk/lib/Target/Sparc/SparcFrameLowering.h Wed Aug 26 12:57:51 2015
@@ -41,6 +41,12 @@ public:
 
   int getFrameIndexReference(const MachineFunction &MF, int FI,
                              unsigned &FrameReg) const override;
+
+  /// targetHandlesStackFrameRounding - Returns true if the target is
+  /// responsible for rounding up the stack frame (probably at emitPrologue
+  /// time).
+  bool targetHandlesStackFrameRounding() const override { return true; }
+
 private:
   // Remap input registers to output registers for leaf procedure.
   void remapRegsForLeafProc(MachineFunction &MF) const;

Modified: llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp?rev=246042&r1=246041&r2=246042&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp Wed Aug 26 12:57:51 2015
@@ -64,7 +64,7 @@ int SparcSubtarget::getAdjustedFrameSize
     frameSize += 128;
     // Frames with calls must also reserve space for 6 outgoing arguments
     // whether they are used or not. LowerCall_64 takes care of that.
-    assert(frameSize % 16 == 0 && "Stack size not 16-byte aligned");
+    frameSize = RoundUpToAlignment(frameSize, 16);
   } else {
     // Emit the correct save instruction based on the number of bytes in
     // the frame. Minimum stack frame size according to V8 ABI is:

Modified: llvm/trunk/test/CodeGen/SPARC/stack-align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/stack-align.ll?rev=246042&r1=246041&r2=246042&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/stack-align.ll (original)
+++ llvm/trunk/test/CodeGen/SPARC/stack-align.ll Wed Aug 26 12:57:51 2015
@@ -12,7 +12,7 @@ declare void @stack_realign_helper(i32 %
 ;; CHECK:      andn %sp, 63, %sp
 ;; CHECK-NEXT: ld [%fp+92], %o0
 ;; CHECK-NEXT: call stack_realign_helper
-;; CHECK-NEXT: add %sp, 96, %o1
+;; CHECK-NEXT: add %sp, 128, %o1
 
 define void @stack_realign(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g) {
 entry:




More information about the llvm-commits mailing list