summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Hibbits <jrh29@alumni.cwru.edu>2015-01-10 01:57:21 +0000
committerJustin Hibbits <jrh29@alumni.cwru.edu>2015-01-10 01:57:21 +0000
commit1c6936f6d7721d2484b4e4bd2b7a1563ddbc056b (patch)
tree3fd0da3b0e5abba0ae9fab72744830230361ad70
parent2ba0f89d9e6120ba572798c578f019c640264bac (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225573 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp52
-rw-r--r--lib/Target/PowerPC/PPCMachineFunctionInfo.h7
-rw-r--r--test/CodeGen/PowerPC/ppc32-pic-large.ll8
-rw-r--r--test/CodeGen/PowerPC/ppc32-pic.ll12
4 files changed, 68 insertions, 11 deletions
diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp
index 1dd1e4d3d24..9b71bd94b82 100644
--- a/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -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)) {
diff --git a/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index 83de7992638..37b2ff83c45 100644
--- a/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -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; }
diff --git a/test/CodeGen/PowerPC/ppc32-pic-large.ll b/test/CodeGen/PowerPC/ppc32-pic-large.ll
index ac638dfec09..bb906ec78d1 100644
--- a/test/CodeGen/PowerPC/ppc32-pic-large.ll
+++ b/test/CodeGen/PowerPC/ppc32-pic-large.ll
@@ -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
diff --git a/test/CodeGen/PowerPC/ppc32-pic.ll b/test/CodeGen/PowerPC/ppc32-pic.ll
index 0ea50824579..abc13675717 100644
--- a/test/CodeGen/PowerPC/ppc32-pic.ll
+++ b/test/CodeGen/PowerPC/ppc32-pic.ll
@@ -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)