[llvm] [llvm] Support multiple save/restore points in mir (PR #119357)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 18 03:53:16 PDT 2025


================
@@ -478,12 +478,65 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
   MachineInstr &MI = *II;
   MachineFunction &MF = *MI.getParent()->getParent();
   MachineRegisterInfo &MRI = MF.getRegInfo();
+  const MachineFrameInfo &MFI = MF.getFrameInfo();
   DebugLoc DL = MI.getDebugLoc();
 
   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
   Register FrameReg;
   StackOffset Offset =
       getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
+
+  const auto &CSI =
+      getFrameLowering(MF)->getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
+
+  if (!CSI.empty()) {
+    int MinCSFI = CSI.front().getFrameIdx();
+    int MaxCSFI = CSI.back().getFrameIdx();
+
+    // If our FrameIndex is CSI FrameIndex we in some cases need additional
+    // adjustment
+    if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) {
+      MachineBasicBlock *SpilledIn = nullptr;
+      MachineBasicBlock *RestoredIn = nullptr;
+      auto It = std::find_if(CSI.begin(), CSI.end(), [FrameIndex](auto &CS) {
+        return CS.getFrameIdx() == FrameIndex;
+      });
+
+      assert(It != CSI.end() &&
+             "Did't find CalleeSavedInfo for CalleeSaved FrameIndex");
+
+      assert(!(MI.mayLoad() && MI.mayStore()) &&
+             "Instruction with frame index operand may load and store "
+             "simultaneously!");
+
+      if (MI.mayStore())
+        SpilledIn = MFI.findSpilledIn(*It);
+      else if (MI.mayLoad())
+        RestoredIn = MFI.findRestoredIn(*It);
+      else
+        llvm_unreachable(
+            "Instruction with frame index operand neither loads nor stores!");
+
+      bool SpilledRestoredInPrologEpilog = true;
+      // If we didn't managed to find NCD (NCPD) for the list of Save (Restore)
+      // blocks, spill (restore) will be unconditionally in Prolog (Epilog)
+      if (MI.mayStore() && MFI.getProlog())
+        SpilledRestoredInPrologEpilog = SpilledIn == MFI.getProlog();
+      else if (MI.mayLoad() && MFI.getEpilog())
+        SpilledRestoredInPrologEpilog = RestoredIn == MFI.getEpilog();
+
+      // For spills/restores performed not in Prolog/Epilog we need to add full
+      // SP offset, despite SPAdjusment optimization, because at the end of
+      // Prolog or at the start of Epilog SP has maximum offset
+      uint64_t FirstSPAdjustAmount =
+          getFrameLowering(MF)->getFirstSPAdjustAmount(MF);
+      if (FirstSPAdjustAmount && !SpilledRestoredInPrologEpilog)
----------------
arsenm wrote:

Braces 

https://github.com/llvm/llvm-project/pull/119357


More information about the llvm-commits mailing list