diff options
author | Hans Wennborg <hans@hanshq.net> | 2018-02-02 13:56:46 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2018-02-02 13:56:46 +0000 |
commit | 816adbd1b4a9e874953958d839951279dfbce5b7 (patch) | |
tree | 64c997ab02aeb13139d755d52ef1fc7ab277cabf | |
parent | abf249d90baf93a6f18f03a9f60007d47b65c697 (diff) |
Merging r323643:
------------------------------------------------------------------------
r323643 | jdevlieghere | 2018-01-29 13:10:32 +0100 (Mon, 29 Jan 2018) | 16 lines
[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
------------------------------------------------------------------------
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@324090 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Sparc/SparcFrameLowering.cpp | 29 | ||||
-rw-r--r-- | test/CodeGen/SPARC/stack-align.ll | 16 |
2 files changed, 35 insertions, 10 deletions
diff --git a/lib/Target/Sparc/SparcFrameLowering.cpp b/lib/Target/Sparc/SparcFrameLowering.cpp index 9864aa37235..9f6c7d65592 100644 --- a/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/lib/Target/Sparc/SparcFrameLowering.cpp @@ -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); + } } } diff --git a/test/CodeGen/SPARC/stack-align.ll b/test/CodeGen/SPARC/stack-align.ll index b152e6a038f..6516fb78e48 100644 --- a/test/CodeGen/SPARC/stack-align.ll +++ b/test/CodeGen/SPARC/stack-align.ll @@ -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: |