117 lines
4.7 KiB
Diff
117 lines
4.7 KiB
Diff
From 369bfc8ea8c0a9da51b4bd964f0045cb389c3c2f Mon Sep 17 00:00:00 2001
|
|
From: ostannard <oliver.stannard@arm.com>
|
|
Date: Mon, 26 Feb 2024 12:23:25 +0000
|
|
Subject: [PATCH 3/3] [ARM] Update IsRestored for LR based on all returns
|
|
(#82745)
|
|
|
|
PR #75527 fixed ARMFrameLowering to set the IsRestored flag for LR based
|
|
on all of the return instructions in the function, not just one.
|
|
However, there is also code in ARMLoadStoreOptimizer which changes
|
|
return instructions, but it set IsRestored based on the one instruction
|
|
it changed, not the whole function.
|
|
|
|
The fix is to factor out the code added in #75527, and also call it from
|
|
ARMLoadStoreOptimizer if it made a change to return instructions.
|
|
|
|
Fixes #80287.
|
|
---
|
|
llvm/lib/Target/ARM/ARMFrameLowering.cpp | 11 +++++----
|
|
llvm/lib/Target/ARM/ARMFrameLowering.h | 4 ++++
|
|
llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 23 ++++++++-----------
|
|
3 files changed, 21 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
|
index 650f4650eef0..008ba4e5924b 100644
|
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
|
@@ -2766,10 +2766,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
|
|
}
|
|
|
|
-void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
|
- MachineFunction &MF, RegScavenger *RS) const {
|
|
- TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
|
-
|
|
+void ARMFrameLowering::updateLRRestored(MachineFunction &MF) {
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
if (!MFI.isCalleeSavedInfoValid())
|
|
return;
|
|
@@ -2793,6 +2790,12 @@ void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
|
}
|
|
}
|
|
|
|
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
|
+ MachineFunction &MF, RegScavenger *RS) const {
|
|
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
|
+ updateLRRestored(MF);
|
|
+}
|
|
+
|
|
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
|
|
BitVector &SavedRegs) const {
|
|
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
|
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
|
index 8d2b8beb9a58..3c7358d8cd53 100644
|
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
|
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
|
@@ -59,6 +59,10 @@ public:
|
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
|
RegScavenger *RS) const override;
|
|
|
|
+ /// Update the IsRestored flag on LR if it is spilled, based on the return
|
|
+ /// instructions.
|
|
+ static void updateLRRestored(MachineFunction &MF);
|
|
+
|
|
void processFunctionBeforeFrameFinalized(
|
|
MachineFunction &MF, RegScavenger *RS = nullptr) const override;
|
|
|
|
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
|
index 93db983b92c0..37d9e1addd1e 100644
|
|
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
|
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
|
@@ -2062,17 +2062,6 @@ 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;
|
|
}
|
|
}
|
|
@@ -2120,14 +2109,22 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
|
|
isThumb2 = AFI->isThumb2Function();
|
|
isThumb1 = AFI->isThumbFunction() && !isThumb2;
|
|
|
|
- bool Modified = false;
|
|
+ bool Modified = false, ModifiedLDMReturn = false;
|
|
for (MachineBasicBlock &MBB : Fn) {
|
|
Modified |= LoadStoreMultipleOpti(MBB);
|
|
if (STI->hasV5TOps() && !AFI->shouldSignReturnAddress())
|
|
- Modified |= MergeReturnIntoLDM(MBB);
|
|
+ ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
|
|
if (isThumb1)
|
|
Modified |= CombineMovBx(MBB);
|
|
}
|
|
+ Modified |= ModifiedLDMReturn;
|
|
+
|
|
+ // If we merged a BX instruction into an LDM, we need to re-calculate whether
|
|
+ // LR is restored. This check needs to consider the whole function, not just
|
|
+ // the instruction(s) we changed, because there may be other BX returns which
|
|
+ // still need LR to be restored.
|
|
+ if (ModifiedLDMReturn)
|
|
+ ARMFrameLowering::updateLRRestored(Fn);
|
|
|
|
Allocator.DestroyAll();
|
|
return Modified;
|
|
--
|
|
2.33.0
|
|
|