diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2014-07-11 17:19:31 +0000 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2014-07-11 17:19:31 +0000 |
commit | ea147a9d4331af26cb0c5ec558dd93e2f44cedaf (patch) | |
tree | 04170cb5efcba814cb793ddfcf3937164ccff600 /llvm/lib/Target/PowerPC | |
parent | eac5062cc0fef587581d3242bd22f3da3dbfaf58 (diff) | |
download | bcm5719-llvm-ea147a9d4331af26cb0c5ec558dd93e2f44cedaf.tar.gz bcm5719-llvm-ea147a9d4331af26cb0c5ec558dd93e2f44cedaf.zip |
[PowerPC] Fix invalid displacement created by LocalStackAlloc
This commit fixes a bug in PPCRegisterInfo::isFrameOffsetLegal that
could result in the LocalStackAlloc pass creating an MI instruction
out-of-range displacement:
%vreg17<def> = LD 33184, %vreg31; mem:LD8[%g](align=32)
%G8RC:%vreg17 G8RC_and_G8RC_NOX0:%vreg31
(In final assembler output the top bits are stripped off, resulting
in a negative offset loading from below the stack pointer.)
Common code expects the isFrameOffsetLegal routine to verify whether
adding a given offset to the offset already present in the instruction
results in a valid displacement. However, on PowerPC the routine
did not take the already present instruction offset into account.
This commit fixes isFrameOffsetLegal to add the instruction offset,
and updates a local caller (needsFrameBaseReg) to no longer add the
instruction offset itself before calling isFrameOffsetLegal.
Reviewed by Hal Finkel.
llvm-svn: 212832
Diffstat (limited to 'llvm/lib/Target/PowerPC')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index eca774ead93..5149a8c23f1 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -885,16 +885,6 @@ bool PPCRegisterInfo:: needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { assert(Offset < 0 && "Local offset must be negative"); - unsigned FIOperandNum = 0; - while (!MI->getOperand(FIOperandNum).isFI()) { - ++FIOperandNum; - assert(FIOperandNum < MI->getNumOperands() && - "Instr doesn't have FrameIndex operand!"); - } - - unsigned OffsetOperandNo = getOffsetONFromFION(*MI, FIOperandNum); - Offset += MI->getOperand(OffsetOperandNo).getImm(); - // It's the load/store FI references that cause issues, as it can be difficult // to materialize the offset if it won't fit in the literal field. Estimate // based on the size of the local frame and some conservative assumptions @@ -985,6 +975,16 @@ void PPCRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, bool PPCRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, int64_t Offset) const { + unsigned FIOperandNum = 0; + while (!MI->getOperand(FIOperandNum).isFI()) { + ++FIOperandNum; + assert(FIOperandNum < MI->getNumOperands() && + "Instr doesn't have FrameIndex operand!"); + } + + unsigned OffsetOperandNo = getOffsetONFromFION(*MI, FIOperandNum); + Offset += MI->getOperand(OffsetOperandNo).getImm(); + return MI->getOpcode() == PPC::DBG_VALUE || // DBG_VALUE is always Reg+Imm (isInt<16>(Offset) && (!usesIXAddr(*MI) || (Offset & 3) == 0)); } |