Add "Restored" flag to CalleeSavedInfo
The liveness-tracking code assumes that the registers that were saved
in the function's prolog are live outside of the function. Specifically,
that registers that were saved are also live-on-exit from the function.
This isn't always the case as illustrated by the LR register on ARM.
Differential Revision: https://reviews.llvm.org/D36160
llvm-svn: 310619
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index f5a745f..dc3e547 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1019,7 +1019,7 @@
void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ std::vector<CalleeSavedInfo> &CSI,
unsigned LdmOpc, unsigned LdrOpc,
bool isVarArg, bool NoGap,
bool(*Func)(unsigned, bool),
@@ -1090,9 +1090,18 @@
.add(predOps(ARMCC::AL));
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
MIB.addReg(Regs[i], getDefRegState(true));
- if (DeleteRet && MI != MBB.end()) {
- MIB.copyImplicitOps(*MI);
- MI->eraseFromParent();
+ if (DeleteRet) {
+ if (MI != MBB.end()) {
+ MIB.copyImplicitOps(*MI);
+ MI->eraseFromParent();
+ }
+ // If LR is not restored, mark it in CSI.
+ for (CalleeSavedInfo &I : CSI) {
+ if (I.getReg() != ARM::LR)
+ continue;
+ I.setRestored(false);
+ break;
+ }
}
MI = MIB;
} else if (Regs.size() == 1) {
@@ -1421,7 +1430,7 @@
bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const {
if (CSI.empty())
return false;