summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMBaseInstrInfo.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-12-02 07:38:06 +0000
committerBill Wendling <isanbard@gmail.com>2013-12-02 07:38:06 +0000
commit1b26fdbf1f01e90b803cc035b6b932cd95c76830 (patch)
treec9717538bdb0fd127cbdd8cba12633cb32552fa8 /lib/Target/ARM/ARMBaseInstrInfo.cpp
parent3d238de4d54eb0b16afd96a57f49f92b2f7748e0 (diff)
downloadllvm-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.cpp25
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)