mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Fully fix Bug #22115.
Summary: In the previous commit, the register was saved, but space was not allocated. This resulted in the parameter save area potentially clobbering r30, leading to nasty results. Test Plan: Tests updated Reviewers: hfinkel Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6906 llvm-svn: 225573
This commit is contained in:
parent
9feb2076df
commit
b4eb439b90
@ -611,6 +611,14 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
}
|
||||
}
|
||||
|
||||
int PBPOffset = 0;
|
||||
if (FI->usesPICBase()) {
|
||||
MachineFrameInfo *FFI = MF.getFrameInfo();
|
||||
int PBPIndex = FI->getPICBasePointerSaveIndex();
|
||||
assert(PBPIndex && "No PIC Base Pointer Save Slot!");
|
||||
PBPOffset = FFI->getObjectOffset(PBPIndex);
|
||||
}
|
||||
|
||||
// Get stack alignments.
|
||||
unsigned MaxAlign = MFI->getMaxAlignment();
|
||||
if (HasBP && MaxAlign > 1)
|
||||
@ -644,12 +652,11 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
.addImm(FPOffset)
|
||||
.addReg(SPReg);
|
||||
|
||||
if (isPIC && !isDarwinABI && !isPPC64 &&
|
||||
MF.getInfo<PPCFunctionInfo>()->usesPICBase())
|
||||
if (FI->usesPICBase())
|
||||
// FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
|
||||
BuildMI(MBB, MBBI, dl, StoreInst)
|
||||
.addReg(PPC::R30)
|
||||
.addImm(-8U)
|
||||
.addImm(PBPOffset)
|
||||
.addReg(SPReg);
|
||||
|
||||
if (HasBP)
|
||||
@ -763,6 +770,15 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
.addCFIIndex(CFIIndex);
|
||||
}
|
||||
|
||||
if (FI->usesPICBase()) {
|
||||
// Describe where FP was saved, at a fixed offset from CFA.
|
||||
unsigned Reg = MRI->getDwarfRegNum(PPC::R30, true);
|
||||
CFIIndex = MMI.addFrameInst(
|
||||
MCCFIInstruction::createOffset(nullptr, Reg, PBPOffset));
|
||||
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
|
||||
.addCFIIndex(CFIIndex);
|
||||
}
|
||||
|
||||
if (HasBP) {
|
||||
// Describe where BP was saved, at a fixed offset from CFA.
|
||||
unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
|
||||
@ -932,6 +948,14 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
}
|
||||
}
|
||||
|
||||
int PBPOffset = 0;
|
||||
if (FI->usesPICBase()) {
|
||||
MachineFrameInfo *FFI = MF.getFrameInfo();
|
||||
int PBPIndex = FI->getPICBasePointerSaveIndex();
|
||||
assert(PBPIndex && "No PIC Base Pointer Save Slot!");
|
||||
PBPOffset = FFI->getObjectOffset(PBPIndex);
|
||||
}
|
||||
|
||||
bool UsesTCRet = RetOpcode == PPC::TCRETURNri ||
|
||||
RetOpcode == PPC::TCRETURNdi ||
|
||||
RetOpcode == PPC::TCRETURNai ||
|
||||
@ -1011,12 +1035,11 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
.addImm(FPOffset)
|
||||
.addReg(SPReg);
|
||||
|
||||
if (isPIC && !isDarwinABI && !isPPC64 &&
|
||||
MF.getInfo<PPCFunctionInfo>()->usesPICBase())
|
||||
if (FI->usesPICBase())
|
||||
// FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
|
||||
BuildMI(MBB, MBBI, dl, LoadInst)
|
||||
.addReg(PPC::R30)
|
||||
.addImm(-8U)
|
||||
.addImm(PBPOffset)
|
||||
.addReg(SPReg);
|
||||
|
||||
if (HasBP)
|
||||
@ -1135,6 +1158,14 @@ PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
FI->setBasePointerSaveIndex(BPSI);
|
||||
}
|
||||
|
||||
// Reserve stack space for the PIC Base register (R30).
|
||||
// Only used in SVR4 32-bit.
|
||||
if (FI->usesPICBase()) {
|
||||
int PBPSI = FI->getPICBasePointerSaveIndex();
|
||||
PBPSI = MFI->CreateFixedObject(4, -8, true);
|
||||
FI->setPICBasePointerSaveIndex(PBPSI);
|
||||
}
|
||||
|
||||
// Reserve stack space to move the linkage area to in case of a tail call.
|
||||
int TCSPDelta = 0;
|
||||
if (MF.getTarget().Options.GuaranteedTailCallOpt &&
|
||||
@ -1266,6 +1297,15 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
|
||||
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
|
||||
}
|
||||
|
||||
if (PFI->usesPICBase()) {
|
||||
HasGPSaveArea = true;
|
||||
|
||||
int FI = PFI->getPICBasePointerSaveIndex();
|
||||
assert(FI && "No PIC Base Pointer Save Slot!");
|
||||
|
||||
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
|
||||
}
|
||||
|
||||
const PPCRegisterInfo *RegInfo =
|
||||
static_cast<const PPCRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
|
||||
if (RegInfo->hasBasePointer(MF)) {
|
||||
|
@ -35,6 +35,9 @@ class PPCFunctionInfo : public MachineFunctionInfo {
|
||||
/// Frame index where the old base pointer is stored.
|
||||
int BasePointerSaveIndex;
|
||||
|
||||
/// Frame index where the old PIC base pointer is stored.
|
||||
int PICBasePointerSaveIndex;
|
||||
|
||||
/// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current
|
||||
/// function. This is only valid after the initial scan of the function by
|
||||
/// PEI.
|
||||
@ -103,6 +106,7 @@ public:
|
||||
: FramePointerSaveIndex(0),
|
||||
ReturnAddrSaveIndex(0),
|
||||
BasePointerSaveIndex(0),
|
||||
PICBasePointerSaveIndex(0),
|
||||
HasSpills(false),
|
||||
HasNonRISpills(false),
|
||||
SpillsCR(false),
|
||||
@ -128,6 +132,9 @@ public:
|
||||
int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
|
||||
void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
|
||||
|
||||
int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
|
||||
void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
|
||||
|
||||
unsigned getMinReservedArea() const { return MinReservedArea; }
|
||||
void setMinReservedArea(unsigned size) { MinReservedArea = size; }
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=LARGE-BSS %s
|
||||
@bar = common global i32 0, align 4
|
||||
|
||||
declare i32 @call_foo(i32, ...)
|
||||
|
||||
define i32 @foo() {
|
||||
entry:
|
||||
%0 = load i32* @bar, align 4
|
||||
%call = call i32 (i32, ...)* @call_foo(i32 %0, i32 0, i32 1, i32 2, i32 4, i32 8, i32 16, i32 32, i32 64)
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
@ -18,8 +21,9 @@ entry:
|
||||
; LARGE-BSS: mflr 30
|
||||
; LARGE-BSS: lwz [[REG:[0-9]+]], [[POFF]]-[[PB]](30)
|
||||
; LARGE-BSS-NEXT: add 30, [[REG]], 30
|
||||
; LARGE-BSS: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.LTOC(30)
|
||||
; LARGE-BSS-DAG: lwz [[VREG:[0-9]+]], [[VREF:\.LC[0-9]+]]-.LTOC(30)
|
||||
; LARGE-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]])
|
||||
; LARGE-BSS-DAG: lwz 30, -8(1)
|
||||
; LARGE-BSS-DAG: stw {{[0-9]+}}, 8(1)
|
||||
; LARGE-BSS: lwz 30, -8(1)
|
||||
; LARGE-BSS: [[VREF]]:
|
||||
; LARGE-BSS-NEXT: .long bar
|
||||
|
@ -1,18 +1,24 @@
|
||||
; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=SMALL-BSS %s
|
||||
@bar = common global i32 0, align 4
|
||||
|
||||
declare i32 @call_foo(i32, ...)
|
||||
|
||||
define i32 @foo() {
|
||||
entry:
|
||||
%0 = load i32* @bar, align 4
|
||||
ret i32 %0
|
||||
%call = call i32 (i32, ...)* @call_foo(i32 %0, i32 0, i32 1, i32 2, i32 4, i32 8, i32 16, i32 32, i32 64)
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"PIC Level", i32 1}
|
||||
; SMALL-BSS-LABEL:foo:
|
||||
; SMALL-BSS: stw 30, -8(1)
|
||||
; SMALL-BSS: stwu 1, -32(1)
|
||||
; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4
|
||||
; SMALL-BSS: mflr 30
|
||||
; SMALL-BSS: lwz [[VREG:[0-9]+]], bar@GOT(30)
|
||||
; SMALL-BSS-DAG: stw {{[0-9]+}}, 8(1)
|
||||
; SMALL-BSS-DAG: lwz [[VREG:[0-9]+]], bar@GOT(30)
|
||||
; SMALL-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]])
|
||||
; SMALL-BSS-DAG: lwz 30, -8(1)
|
||||
; SMALL-BSS: bl call_foo@PLT
|
||||
; SMALL-BSS: lwz 30, -8(1)
|
||||
|
Loading…
Reference in New Issue
Block a user