From: Justin Hibbits Date: Sat, 10 Jan 2015 01:57:21 +0000 (+0000) Subject: Fully fix Bug #22115. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c6936f6d7721d2484b4e4bd2b7a1563ddbc056b;p=llvm 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 --- 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()->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()->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(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)