diff options
| author | Matthias Braun <matze@braunis.de> | 2017-09-28 23:12:06 +0000 |
|---|---|---|
| committer | Matthias Braun <matze@braunis.de> | 2017-09-28 23:12:06 +0000 |
| commit | 51687912a4da910426c8daf40994fde3a9ac3520 (patch) | |
| tree | 6fc94a09eb23f18e965e47e6b164f0f6606cb4fe /llvm/lib | |
| parent | 195b25cf3cbde92e8613465571b5f3511c5cc69d (diff) | |
| download | bcm5719-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.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Thumb1FrameLowering.cpp | 4 |
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) |

