[PATCH] D12349: [SPARC] Fix stupid oversight in stack realignment support.

James Y Knight via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 18:41:33 PDT 2015


jyknight created this revision.
jyknight added a reviewer: chandlerc.
jyknight added a subscriber: llvm-commits.

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.

http://reviews.llvm.org/D12349

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

Index: test/CodeGen/SPARC/stack-align.ll
===================================================================
--- test/CodeGen/SPARC/stack-align.ll
+++ test/CodeGen/SPARC/stack-align.ll
@@ -12,7 +12,7 @@
 ;; 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:
Index: lib/Target/Sparc/SparcSubtarget.cpp
===================================================================
--- lib/Target/Sparc/SparcSubtarget.cpp
+++ lib/Target/Sparc/SparcSubtarget.cpp
@@ -64,7 +64,7 @@
     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:
Index: lib/Target/Sparc/SparcFrameLowering.h
===================================================================
--- lib/Target/Sparc/SparcFrameLowering.h
+++ lib/Target/Sparc/SparcFrameLowering.h
@@ -41,6 +41,12 @@
 
   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;
Index: lib/Target/Sparc/SparcFrameLowering.cpp
===================================================================
--- lib/Target/Sparc/SparcFrameLowering.cpp
+++ lib/Target/Sparc/SparcFrameLowering.cpp
@@ -118,8 +118,21 @@
     SAVErr = SP::ADDrr;
   }
 
+  // Add the extra call frame stack size, if needed (this would've
+  // been done by PrologEpilogInserter.cpp, except that we have
+  // targetHandlesStackFrameRounding returning true.)
+  if (MFI->adjustsStack() && hasReservedCallFrame(MF))
+    NumBytes += MFI->getMaxCallFrameSize();
+
+  // Adds the 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.
+  // Ensure that the size is also 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);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12349.33163.patch
Type: text/x-patch
Size: 3005 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150826/367842c6/attachment.bin>


More information about the llvm-commits mailing list