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().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); 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: 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: