[Sparc] Account for bias in stack readjustment

Summary: This was broken long ago in D12208, which failed to account for
the fact that 64-bit SPARC uses a stack bias of 2047, and it is the
*unbiased* value which should be aligned, not the biased one. This was
seen to be an issue with Rust.

Patch by: jrtc27 (James Clarke)

Reviewers: jyknight, venkatra

Reviewed By: jyknight

Subscribers: jacob_hansen, JDevlieghere, fhahn, fedor.sergeev, llvm-commits

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

llvm-svn: 323643
This commit is contained in:
Jonas Devlieghere 2018-01-29 12:10:32 +00:00
parent c48df10be9
commit 96096cd4c5
2 changed files with 35 additions and 10 deletions

View File

@ -88,10 +88,11 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF,
assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
MachineFrameInfo &MFI = MF.getFrameInfo();
const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();
const SparcInstrInfo &TII =
*static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
*static_cast<const SparcInstrInfo *>(Subtarget.getInstrInfo());
const SparcRegisterInfo &RegInfo =
*static_cast<const SparcRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
*static_cast<const SparcRegisterInfo *>(Subtarget.getRegisterInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
// Debug location must be unknown since the first debug location is used
// to determine the end of the prologue.
@ -141,7 +142,7 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF,
// Adds the SPARC subtarget-specific spill area to the stack
// size. Also ensures target-required alignment.
NumBytes = MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes);
NumBytes = Subtarget.getAdjustedFrameSize(NumBytes);
// Finally, ensure that the size is sufficiently aligned for the
// data on the stack.
@ -176,9 +177,27 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF,
.addCFIIndex(CFIIndex);
if (NeedsStackRealignment) {
// andn %o6, MaxAlign-1, %o6
int64_t Bias = Subtarget.getStackPointerBias();
unsigned regUnbiased;
if (Bias) {
// This clobbers G1 which we always know is available here.
regUnbiased = SP::G1;
// add %o6, BIAS, %g1
BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), regUnbiased)
.addReg(SP::O6).addImm(Bias);
} else
regUnbiased = SP::O6;
// andn %regUnbiased, MaxAlign-1, %regUnbiased
int MaxAlign = MFI.getMaxAlignment();
BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), SP::O6).addReg(SP::O6).addImm(MaxAlign - 1);
BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), regUnbiased)
.addReg(regUnbiased).addImm(MaxAlign - 1);
if (Bias) {
// add %g1, -BIAS, %o6
BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), SP::O6)
.addReg(regUnbiased).addImm(-Bias);
}
}
}

View File

@ -1,4 +1,5 @@
; RUN: llc -march=sparc < %s | FileCheck %s
; RUN: llc -march=sparc < %s | FileCheck %s --check-prefixes=CHECK,CHECK32
; RUN: llc -march=sparcv9 < %s | FileCheck %s --check-prefixes=CHECK,CHECK64
declare void @stack_realign_helper(i32 %a, i32* %b)
;; This is a function where we have a local variable of 64-byte
@ -7,10 +8,15 @@ declare void @stack_realign_helper(i32 %a, i32* %b)
;; the argument is accessed via frame pointer not stack pointer (to %o0).
;; CHECK-LABEL: stack_realign:
;; CHECK: andn %sp, 63, %sp
;; CHECK-NEXT: ld [%fp+92], %o0
;; CHECK-NEXT: call stack_realign_helper
;; CHECK-NEXT: add %sp, 128, %o1
;; CHECK32: andn %sp, 63, %sp
;; CHECK32-NEXT: ld [%fp+92], %o0
;; CHECK64: add %sp, 2047, %g1
;; CHECK64-NEXT: andn %g1, 63, %g1
;; CHECK64-NEXT: add %g1, -2047, %sp
;; CHECK64-NEXT: ld [%fp+2227], %o0
;; CHECK-NEXT: call stack_realign_helper
;; CHECK32-NEXT: add %sp, 128, %o1
;; CHECK64-NEXT: add %sp, 2239, %o1
define void @stack_realign(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g) {
entry: