diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-12-02 07:38:06 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-12-02 07:38:06 +0000 |
commit | 1b26fdbf1f01e90b803cc035b6b932cd95c76830 (patch) | |
tree | c9717538bdb0fd127cbdd8cba12633cb32552fa8 /lib/Target/ARM/ARMBaseInstrInfo.cpp | |
parent | 3d238de4d54eb0b16afd96a57f49f92b2f7748e0 (diff) | |
download | llvm-1b26fdbf1f01e90b803cc035b6b932cd95c76830.tar.gz llvm-1b26fdbf1f01e90b803cc035b6b932cd95c76830.tar.bz2 llvm-1b26fdbf1f01e90b803cc035b6b932cd95c76830.tar.xz |
Merging r196046:
------------------------------------------------------------------------
r196046 | tnorthover | 2013-12-01 06:16:24 -0800 (Sun, 01 Dec 2013) | 8 lines
ARM: fix bug in -Oz stack adjustment folding
Previously, we clobbered callee-saved registers when folding an "add
sp, #N" into a "pop {rD, ...}" instruction. This change checks whether
a register we're going to add to the "pop" could actually be live
outside the function before doing so and should fix the issue.
This should fix PR18081.
------------------------------------------------------------------------
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_34@196074 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMBaseInstrInfo.cpp')
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 67534c4a44..df8c017515 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1913,29 +1913,40 @@ bool llvm::tryFoldSPUpdateIntoPushPop(MachineFunction &MF, MachineBasicBlock *MBB = MI->getParent(); const TargetRegisterInfo *TRI = MF.getRegInfo().getTargetRegisterInfo(); + const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF); // Now try to find enough space in the reglist to allocate NumBytes. for (unsigned CurReg = FirstReg - 1; CurReg >= RD0Reg && RegsNeeded; - --CurReg, --RegsNeeded) { + --CurReg) { if (!IsPop) { // Pushing any register is completely harmless, mark the // register involved as undef since we don't care about it in // the slightest. RegList.push_back(MachineOperand::CreateReg(CurReg, false, false, false, false, true)); + --RegsNeeded; continue; } - // However, we can only pop an extra register if it's not live. Otherwise we - // might clobber a return value register. We assume that once we find a live - // return register all lower ones will be too so there's no use proceeding. - if (MBB->computeRegisterLiveness(TRI, CurReg, MI) != - MachineBasicBlock::LQR_Dead) - return false; + // However, we can only pop an extra register if it's not live. For + // registers live within the function we might clobber a return value + // register; the other way a register can be live here is if it's + // callee-saved. + if (isCalleeSavedRegister(CurReg, CSRegs) || + MBB->computeRegisterLiveness(TRI, CurReg, MI) != + MachineBasicBlock::LQR_Dead) { + // VFP pops don't allow holes in the register list, so any skip is fatal + // for our transformation. GPR pops do, so we should just keep looking. + if (IsVFPPushPop) + return false; + else + continue; + } // Mark the unimportant registers as <def,dead> in the POP. RegList.push_back(MachineOperand::CreateReg(CurReg, true, false, false, true)); + --RegsNeeded; } if (RegsNeeded > 0) |