88 lines
3.5 KiB
Diff
88 lines
3.5 KiB
Diff
From 4aec2da60ce3f639e31d81406c09d5c88b3b8f53 Mon Sep 17 00:00:00 2001
|
|
From: Florian Hahn <flo@fhahn.com>
|
|
Date: Wed, 20 Dec 2023 16:56:15 +0100
|
|
Subject: [PATCH 2/3] [ARM] Check all terms in emitPopInst when clearing
|
|
Restored for LR. (#75527)
|
|
|
|
emitPopInst checks a single function exit MBB. If other paths also exit
|
|
the function and any of there terminators uses LR implicitly, it is not
|
|
save to clear the Restored bit.
|
|
|
|
Check all terminators for the function before clearing Restored.
|
|
|
|
This fixes a mis-compile in outlined-fn-may-clobber-lr-in-caller.ll
|
|
where the machine-outliner previously introduced BLs that clobbered LR
|
|
which in turn is used by the tail call return.
|
|
|
|
Alternative to #73553
|
|
---
|
|
llvm/lib/Target/ARM/ARMFrameLowering.cpp | 30 +++++++++++++++++++++---
|
|
llvm/lib/Target/ARM/ARMFrameLowering.h | 3 +++
|
|
2 files changed, 30 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
|
index 4496d4928ebe..650f4650eef0 100644
|
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
|
@@ -1645,9 +1645,6 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
|
|
// Fold the return instruction into the LDM.
|
|
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);
|
|
}
|
|
|
|
// If NoGap is true, pop consecutive registers and then leave the rest
|
|
@@ -2769,6 +2766,33 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
|
|
}
|
|
|
|
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
|
+ MachineFunction &MF, RegScavenger *RS) const {
|
|
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
|
+
|
|
+ MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
+ if (!MFI.isCalleeSavedInfoValid())
|
|
+ return;
|
|
+
|
|
+ // Check if all terminators do not implicitly use LR. Then we can 'restore' LR
|
|
+ // into PC so it is not live out of the return block: Clear the Restored bit
|
|
+ // in that case.
|
|
+ for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
|
|
+ if (Info.getReg() != ARM::LR)
|
|
+ continue;
|
|
+ if (all_of(MF, [](const MachineBasicBlock &MBB) {
|
|
+ return all_of(MBB.terminators(), [](const MachineInstr &Term) {
|
|
+ return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
|
|
+ Term.getOpcode() == ARM::t2LDMIA_RET ||
|
|
+ Term.getOpcode() == ARM::tPOP_RET;
|
|
+ });
|
|
+ })) {
|
|
+ Info.setRestored(false);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
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 16f2ce6bea6f..8d2b8beb9a58 100644
|
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
|
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
|
@@ -59,6 +59,9 @@ public:
|
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
|
RegScavenger *RS) const override;
|
|
|
|
+ void processFunctionBeforeFrameFinalized(
|
|
+ MachineFunction &MF, RegScavenger *RS = nullptr) const override;
|
|
+
|
|
void adjustForSegmentedStacks(MachineFunction &MF,
|
|
MachineBasicBlock &MBB) const override;
|
|
|
|
--
|
|
2.33.0
|
|
|