summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-09-28 23:12:06 +0000
committerMatthias Braun <matze@braunis.de>2017-09-28 23:12:06 +0000
commit51687912a4da910426c8daf40994fde3a9ac3520 (patch)
tree6fc94a09eb23f18e965e47e6b164f0f6606cb4fe /llvm/lib
parent195b25cf3cbde92e8613465571b5f3511c5cc69d (diff)
downloadbcm5719-llvm-51687912a4da910426c8daf40994fde3a9ac3520.tar.gz
bcm5719-llvm-51687912a4da910426c8daf40994fde3a9ac3520.zip
ARM: Fix cases where CSI Restored bit is not cleared
LR is an untypical callee saved register in that it is restored into a different register (PC) and thus does not live-out of the return block. This case requires the `Restored` flag in CalleeSavedInfo to be cleared. This fixes a number of cases where this wasn't handled correctly yet. llvm-svn: 314471
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMFrameLowering.cpp13
-rw-r--r--llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp11
-rw-r--r--llvm/lib/Target/ARM/Thumb1FrameLowering.cpp4
3 files changed, 19 insertions, 9 deletions
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 65ca2ad504a..4af744f5ec3 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1053,7 +1053,8 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
unsigned LastReg = 0;
bool DeleteRet = false;
for (; i != 0; --i) {
- unsigned Reg = CSI[i-1].getReg();
+ CalleeSavedInfo &Info = CSI[i-1];
+ unsigned Reg = Info.getReg();
if (!(Func)(Reg, STI.splitFramePushPop(MF))) continue;
// The aligned reloads from area DPRCS2 are not inserted here.
@@ -1066,6 +1067,9 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
Reg = ARM::PC;
DeleteRet = true;
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
+ // We 'restore' LR into PC so it is not live out of the return block:
+ // Clear Restored bit.
+ Info.setRestored(false);
} else
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
// Fold the return instruction into the LDM.
@@ -1099,13 +1103,6 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
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) {
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 47e49562246..4aa7e150342 100644
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -1909,6 +1909,17 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
MO.setReg(ARM::PC);
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
MBB.erase(MBBI);
+ // We now restore LR into PC so it is not live-out of the return block
+ // anymore: Clear the CSI Restored bit.
+ MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
+ // CSI should be fixed after PrologEpilog Insertion
+ assert(MFI.isCalleeSavedInfoValid() && "CSI should be valid");
+ for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
+ if (Info.getReg() == ARM::LR) {
+ Info.setRestored(false);
+ break;
+ }
+ }
return true;
}
}
diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
index 85abe1d3b73..13068992e8f 100644
--- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -876,13 +876,15 @@ restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
bool NeedsPop = false;
for (unsigned i = CSI.size(); i != 0; --i) {
- unsigned Reg = CSI[i-1].getReg();
+ CalleeSavedInfo &Info = CSI[i-1];
+ unsigned Reg = Info.getReg();
// High registers (excluding lr) have already been dealt with
if (!(ARM::tGPRRegClass.contains(Reg) || Reg == ARM::LR))
continue;
if (Reg == ARM::LR) {
+ Info.setRestored(false);
if (MBB.succ_empty()) {
// Special epilogue for vararg functions. See emitEpilogue
if (isVarArg)
OpenPOWER on IntegriCloud