diff --git a/0003-Backport-ARM-Check-all-terms-in-emitPopInst-when-clearing-Res.patch b/0003-Backport-ARM-Check-all-terms-in-emitPopInst-when-clearing-Res.patch new file mode 100644 index 0000000000000000000000000000000000000000..4528f50f5eed02080e361a10047266e91558a91a --- /dev/null +++ b/0003-Backport-ARM-Check-all-terms-in-emitPopInst-when-clearing-Res.patch @@ -0,0 +1,87 @@ +From 4aec2da60ce3f639e31d81406c09d5c88b3b8f53 Mon Sep 17 00:00:00 2001 +From: Florian Hahn +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 + diff --git a/0004-Backport-ARM-Update-IsRestored-for-LR-based-on-all-returns-82.patch b/0004-Backport-ARM-Update-IsRestored-for-LR-based-on-all-returns-82.patch new file mode 100644 index 0000000000000000000000000000000000000000..eb34372c85aefb4a8e2d514f926adad455483eb9 --- /dev/null +++ b/0004-Backport-ARM-Update-IsRestored-for-LR-based-on-all-returns-82.patch @@ -0,0 +1,116 @@ +From 369bfc8ea8c0a9da51b4bd964f0045cb389c3c2f Mon Sep 17 00:00:00 2001 +From: ostannard +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 + diff --git a/llvm.spec b/llvm.spec index 6ba5cc9fabaea204aef6aaf2618e14690ff15bd8..a8df8be6a4ef1bf031c6c2ce6c91161d2c1200c3 100644 --- a/llvm.spec +++ b/llvm.spec @@ -1,4 +1,4 @@ -%define anolis_release 3 +%define anolis_release 4 %global toolchain clang @@ -66,6 +66,8 @@ Source4: https://github.com/llvm/llvm-project/releases/download/llvmorg-% Patch2: 0001-llvm-Add-install-targets-for-gtest.patch Patch3: 0001-backport-LoongArch-patches.patch Patch4: 0002-LoongArch-fix-symbol-lookup-error.patch +Patch5: 0003-Backport-ARM-Check-all-terms-in-emitPopInst-when-clearing-Res.patch +Patch6: 0004-Backport-ARM-Update-IsRestored-for-LR-based-on-all-returns-82.patch Patch201: 0201-third-party-Add-install-targets-for-gtest.patch BuildRequires: gcc gcc-c++ clang cmake ninja-build zlib-devel libffi-devel @@ -486,6 +488,9 @@ fi %endif %changelog +* Mon Jun 17 2024 hezhongkun - 17.0.6-4 +- Backport patch to fix CVE-2024-31852 + * Tue Oct 31 2023 Chen Li - 16.0.6-3 - LoongArch: Fix symbol lookup error when compiling clang on aarch and x86