[llvm-branch-commits] [llvm] release/18.x: [ARM] Update IsRestored for LR based on all returns (#82745) (PR #83129)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Feb 27 05:08:51 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: None (llvmbot)
<details>
<summary>Changes</summary>
Backport 8779cf68e80dcc0b15e8034f39e6ce18b08352b6 749384c08e042739342c88b521c8ba5dac1b9276
Requested by: @<!-- -->P1119r1m
---
Full diff: https://github.com/llvm/llvm-project/pull/83129.diff
4 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMFrameLowering.cpp (+7-4)
- (modified) llvm/lib/Target/ARM/ARMFrameLowering.h (+4)
- (modified) llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (+10-13)
- (added) llvm/test/CodeGen/ARM/ldst-opt-lr-restored.ll (+56)
``````````diff
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index eeb7f64aa5810e..9b54dd4e4e618d 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -2781,10 +2781,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;
@@ -2808,6 +2805,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 8d2b8beb9a58fb..3c7358d8cd53e2 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
@@ -59,6 +59,10 @@ class ARMFrameLowering : public TargetFrameLowering {
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 ed9d30c3c3ab90..6121055eb02176 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;
diff --git a/llvm/test/CodeGen/ARM/ldst-opt-lr-restored.ll b/llvm/test/CodeGen/ARM/ldst-opt-lr-restored.ll
new file mode 100644
index 00000000000000..9494880f990258
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/ldst-opt-lr-restored.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple thumbv7a-none-eabi < %s | FileCheck %s
+
+ at val0 = global i32 0, align 4
+ at val1 = global i32 0, align 4
+ at val2 = global i32 0, align 4
+
+define i32 @foo(ptr %ctx) {
+; CHECK-LABEL: foo:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: cbz r0, .LBB0_2
+; CHECK-NEXT: @ %bb.1: @ %if.end
+; CHECK-NEXT: movw r12, :lower16:val2
+; CHECK-NEXT: movw r3, :lower16:val1
+; CHECK-NEXT: movw r2, :lower16:val0
+; CHECK-NEXT: mov r1, r0
+; CHECK-NEXT: movs r0, #0
+; CHECK-NEXT: movt r12, :upper16:val2
+; CHECK-NEXT: movt r3, :upper16:val1
+; CHECK-NEXT: movt r2, :upper16:val0
+; CHECK-NEXT: str r2, [r1, #4]
+; CHECK-NEXT: str r3, [r1, #8]
+; CHECK-NEXT: str.w r12, [r1, #12]
+; CHECK-NEXT: str r0, [r1, #16]
+; CHECK-NEXT: bx lr
+; CHECK-NEXT: .LBB0_2: @ %if.then
+; CHECK-NEXT: .save {r7, lr}
+; CHECK-NEXT: push {r7, lr}
+; CHECK-NEXT: bl bar
+; CHECK-NEXT: mov.w r0, #-1
+; CHECK-NEXT: pop {r7, pc}
+entry:
+ %tobool.not = icmp eq ptr %ctx, null
+ br i1 %tobool.not, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ tail call void @bar() #2
+ br label %return
+
+if.end: ; preds = %entry
+ %cmd_a = getelementptr inbounds i8, ptr %ctx, i32 4
+ store ptr @val0, ptr %cmd_a, align 4
+ %cmd_b = getelementptr inbounds i8, ptr %ctx, i32 8
+ store ptr @val1, ptr %cmd_b, align 4
+ %cmd_c = getelementptr inbounds i8, ptr %ctx, i32 12
+ store ptr @val2, ptr %cmd_c, align 4
+ %cmd_d = getelementptr inbounds i8, ptr %ctx, i32 16
+ store ptr null, ptr %cmd_d, align 4
+ br label %return
+
+return: ; preds = %if.end, %if.then
+ %retval.0 = phi i32 [ 0, %if.end ], [ -1, %if.then ]
+ ret i32 %retval.0
+}
+
+declare void @bar()
``````````
</details>
https://github.com/llvm/llvm-project/pull/83129
More information about the llvm-branch-commits
mailing list