Skip to content

Commit 0e16af8

Browse files
ostannardllvmbot
authored andcommitted
[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. (cherry picked from commit 749384c)
1 parent 6f8016f commit 0e16af8

File tree

4 files changed

+27
-22
lines changed

4 files changed

+27
-22
lines changed

llvm/lib/Target/ARM/ARMFrameLowering.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -2781,10 +2781,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
27812781
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
27822782
}
27832783

2784-
void ARMFrameLowering::processFunctionBeforeFrameFinalized(
2785-
MachineFunction &MF, RegScavenger *RS) const {
2786-
TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
2787-
2784+
void ARMFrameLowering::updateLRRestored(MachineFunction &MF) {
27882785
MachineFrameInfo &MFI = MF.getFrameInfo();
27892786
if (!MFI.isCalleeSavedInfoValid())
27902787
return;
@@ -2808,6 +2805,12 @@ void ARMFrameLowering::processFunctionBeforeFrameFinalized(
28082805
}
28092806
}
28102807

2808+
void ARMFrameLowering::processFunctionBeforeFrameFinalized(
2809+
MachineFunction &MF, RegScavenger *RS) const {
2810+
TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
2811+
updateLRRestored(MF);
2812+
}
2813+
28112814
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
28122815
BitVector &SavedRegs) const {
28132816
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);

llvm/lib/Target/ARM/ARMFrameLowering.h

+4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class ARMFrameLowering : public TargetFrameLowering {
5959
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
6060
RegScavenger *RS) const override;
6161

62+
/// Update the IsRestored flag on LR if it is spilled, based on the return
63+
/// instructions.
64+
static void updateLRRestored(MachineFunction &MF);
65+
6266
void processFunctionBeforeFrameFinalized(
6367
MachineFunction &MF, RegScavenger *RS = nullptr) const override;
6468

llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp

+10-13
Original file line numberDiff line numberDiff line change
@@ -2062,17 +2062,6 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
20622062
MO.setReg(ARM::PC);
20632063
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
20642064
MBB.erase(MBBI);
2065-
// We now restore LR into PC so it is not live-out of the return block
2066-
// anymore: Clear the CSI Restored bit.
2067-
MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
2068-
// CSI should be fixed after PrologEpilog Insertion
2069-
assert(MFI.isCalleeSavedInfoValid() && "CSI should be valid");
2070-
for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
2071-
if (Info.getReg() == ARM::LR) {
2072-
Info.setRestored(false);
2073-
break;
2074-
}
2075-
}
20762065
return true;
20772066
}
20782067
}
@@ -2120,14 +2109,22 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
21202109
isThumb2 = AFI->isThumb2Function();
21212110
isThumb1 = AFI->isThumbFunction() && !isThumb2;
21222111

2123-
bool Modified = false;
2112+
bool Modified = false, ModifiedLDMReturn = false;
21242113
for (MachineBasicBlock &MBB : Fn) {
21252114
Modified |= LoadStoreMultipleOpti(MBB);
21262115
if (STI->hasV5TOps() && !AFI->shouldSignReturnAddress())
2127-
Modified |= MergeReturnIntoLDM(MBB);
2116+
ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
21282117
if (isThumb1)
21292118
Modified |= CombineMovBx(MBB);
21302119
}
2120+
Modified |= ModifiedLDMReturn;
2121+
2122+
// If we merged a BX instruction into an LDM, we need to re-calculate whether
2123+
// LR is restored. This check needs to consider the whole function, not just
2124+
// the instruction(s) we changed, because there may be other BX returns which
2125+
// still need LR to be restored.
2126+
if (ModifiedLDMReturn)
2127+
ARMFrameLowering::updateLRRestored(Fn);
21312128

21322129
Allocator.DestroyAll();
21332130
return Modified;

llvm/test/CodeGen/ARM/ldst-opt-lr-restored.ll

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@ define i32 @foo(ptr %ctx) {
1010
; CHECK: @ %bb.0: @ %entry
1111
; CHECK-NEXT: cbz r0, .LBB0_2
1212
; CHECK-NEXT: @ %bb.1: @ %if.end
13+
; CHECK-NEXT: movw r12, :lower16:val2
14+
; CHECK-NEXT: movw r3, :lower16:val1
1315
; CHECK-NEXT: movw r2, :lower16:val0
1416
; CHECK-NEXT: mov r1, r0
1517
; CHECK-NEXT: movs r0, #0
16-
; CHECK-NEXT: movw r12, :lower16:val2
17-
; CHECK-NEXT: movw r3, :lower16:val1
18-
; CHECK-NEXT: movt r2, :upper16:val0
19-
; CHECK-NEXT: add.w lr, r1, #4
2018
; CHECK-NEXT: movt r12, :upper16:val2
2119
; CHECK-NEXT: movt r3, :upper16:val1
22-
; CHECK-NEXT: stm.w lr, {r2, r3, r12}
20+
; CHECK-NEXT: movt r2, :upper16:val0
21+
; CHECK-NEXT: str r2, [r1, #4]
22+
; CHECK-NEXT: str r3, [r1, #8]
23+
; CHECK-NEXT: str.w r12, [r1, #12]
2324
; CHECK-NEXT: str r0, [r1, #16]
2425
; CHECK-NEXT: bx lr
2526
; CHECK-NEXT: .LBB0_2: @ %if.then

0 commit comments

Comments
 (0)