[llvm-branch-commits] [RISCV] Port LoadStoreOpt to NewPM (PR #235511)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Oct 25 12:05:02 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Aiden Grossman (boomanaiden154)

<details>
<summary>Changes</summary>

Standard NewPM pass portign. Also mark in the LegacyPM this pass
preserves the CFG.


---
Full diff: https://github.com/llvm/llvm-project/pull/235511.diff


4 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCV.h (+9-2) 
- (modified) llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp (+66-32) 
- (modified) llvm/lib/Target/RISCV/RISCVPassRegistry.def (+1) 
- (modified) llvm/lib/Target/RISCV/RISCVTargetMachine.cpp (+2-2) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 96f4e23f2fafd..36924db70283d 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -256,8 +256,15 @@ class RISCVPushPopOptPass : public OptionalPassInfoMixin<RISCVPushPopOptPass> {
 FunctionPass *createRISCVPushPopOptLegacyPass();
 void initializeRISCVPushPopOptLegacyPass(PassRegistry &);
 
-FunctionPass *createRISCVLoadStoreOptPass();
-void initializeRISCVLoadStoreOptPass(PassRegistry &);
+class RISCVLoadStoreOptPass
+    : public OptionalPassInfoMixin<RISCVLoadStoreOptPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createRISCVLoadStoreOptLegacyPass();
+void initializeRISCVLoadStoreOptLegacyPass(PassRegistry &);
 
 FunctionPass *createRISCVPreAllocZilsdOptPass();
 void initializeRISCVPreAllocZilsdOptPass(PassRegistry &);
diff --git a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
index 9efe85d27c6c0..92cd393ca6add 100644
--- a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
@@ -29,7 +29,10 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Target/TargetOptions.h"
@@ -44,23 +47,27 @@ STATISTIC(NumSD2SW, "Number of SD instructions split back to SW");
 
 namespace {
 
-struct RISCVLoadStoreOpt : public MachineFunctionPass {
+class RISCVLoadStoreOptLegacy : public MachineFunctionPass {
+public:
   static char ID;
   bool runOnMachineFunction(MachineFunction &Fn) override;
 
-  RISCVLoadStoreOpt() : MachineFunctionPass(ID) {}
+  RISCVLoadStoreOptLegacy() : MachineFunctionPass(ID) {}
 
   MachineFunctionProperties getRequiredProperties() const override {
     return MachineFunctionProperties().setNoVRegs();
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesCFG();
     AU.addRequired<AAResultsWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
   StringRef getPassName() const override { return RISCV_LOAD_STORE_OPT_NAME; }
+};
 
+class RISCVLoadStoreOptImpl {
   // Find and pair load/store instructions.
   bool tryToPairLdStInst(MachineBasicBlock::iterator &MBBI);
 
@@ -92,35 +99,37 @@ struct RISCVLoadStoreOpt : public MachineFunctionPass {
   void splitLdSdIntoTwo(MachineBasicBlock &MBB,
                         MachineBasicBlock::iterator &MBBI, bool IsLoad);
 
-private:
   AliasAnalysis *AA;
   MachineRegisterInfo *MRI;
   const RISCVInstrInfo *TII;
   const RISCVRegisterInfo *TRI;
   const RISCVSubtarget *STI = nullptr;
   LiveRegUnits ModifiedRegUnits, UsedRegUnits;
+
+public:
+  bool runOnMachineFunction(MachineFunction &MF,
+                            function_ref<AliasAnalysis *()> GetAA);
 };
 } // end anonymous namespace
 
-char RISCVLoadStoreOpt::ID = 0;
-INITIALIZE_PASS(RISCVLoadStoreOpt, DEBUG_TYPE, RISCV_LOAD_STORE_OPT_NAME, false,
-                false)
+char RISCVLoadStoreOptLegacy::ID = 0;
+INITIALIZE_PASS(RISCVLoadStoreOptLegacy, DEBUG_TYPE, RISCV_LOAD_STORE_OPT_NAME,
+                false, false)
 
-bool RISCVLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
-  if (skipFunction(Fn.getFunction()))
-    return false;
+bool RISCVLoadStoreOptImpl::runOnMachineFunction(
+    MachineFunction &MF, function_ref<AliasAnalysis *()> GetAA) {
 
   bool MadeChange = false;
-  STI = &Fn.getSubtarget<RISCVSubtarget>();
+  STI = &MF.getSubtarget<RISCVSubtarget>();
   TII = STI->getInstrInfo();
   TRI = STI->getRegisterInfo();
-  MRI = &Fn.getRegInfo();
-  AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+  MRI = &MF.getRegInfo();
+  AA = GetAA();
   ModifiedRegUnits.init(*TRI);
   UsedRegUnits.init(*TRI);
 
   if (STI->useMIPSLoadStorePairs() || STI->hasVendorXqcilsm()) {
-    for (MachineBasicBlock &MBB : Fn) {
+    for (MachineBasicBlock &MBB : MF) {
       LLVM_DEBUG(dbgs() << "MBB: " << MBB.getName() << "\n");
 
       for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
@@ -135,7 +144,7 @@ bool RISCVLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
   }
 
   if (!STI->is64Bit() && STI->hasStdExtZilsd()) {
-    for (auto &MBB : Fn) {
+    for (auto &MBB : MF) {
       for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E;) {
         if (fixInvalidRegPairOp(MBB, MBBI)) {
           MadeChange = true;
@@ -152,7 +161,8 @@ bool RISCVLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
 
 // Find loads and stores that can be merged into a single load or store pair
 // instruction.
-bool RISCVLoadStoreOpt::tryToPairLdStInst(MachineBasicBlock::iterator &MBBI) {
+bool RISCVLoadStoreOptImpl::tryToPairLdStInst(
+    MachineBasicBlock::iterator &MBBI) {
   MachineInstr &MI = *MBBI;
 
   // If this is volatile, it is not a candidate.
@@ -189,7 +199,7 @@ static bool isMemOpAligned(MachineInstr &MI, Align RequiredAlignment) {
 // For now this only handles consecutive loads and stores traversing the basic
 // block top-down.
 // TODO: Traverse the basic block bottom-up as well.
-bool RISCVLoadStoreOpt::tryConvertToXqcilsmMultiLdSt(
+bool RISCVLoadStoreOptImpl::tryConvertToXqcilsmMultiLdSt(
     MachineBasicBlock::iterator &FirstIt) {
   MachineInstr &FirstMI = *FirstIt;
   MachineFunction *MF = FirstMI.getMF();
@@ -374,7 +384,7 @@ bool RISCVLoadStoreOpt::tryConvertToXqcilsmMultiLdSt(
   return true;
 }
 
-bool RISCVLoadStoreOpt::tryConvertToXqcilsmLdStPair(
+bool RISCVLoadStoreOptImpl::tryConvertToXqcilsmLdStPair(
     MachineFunction *MF, MachineBasicBlock::iterator First,
     MachineBasicBlock::iterator Second) {
   unsigned Opc = First->getOpcode();
@@ -475,7 +485,7 @@ bool RISCVLoadStoreOpt::tryConvertToXqcilsmLdStPair(
   return true;
 }
 
-bool RISCVLoadStoreOpt::tryConvertToMIPSLdStPair(
+bool RISCVLoadStoreOptImpl::tryConvertToMIPSLdStPair(
     MachineFunction *MF, MachineBasicBlock::iterator First,
     MachineBasicBlock::iterator Second) {
   // Try converting to SWP/LWP/LDP/SDP.
@@ -535,7 +545,7 @@ bool RISCVLoadStoreOpt::tryConvertToMIPSLdStPair(
 // appropriate paired opcode, verifies that the memory operand is properly
 // aligned, and checks that the offset is valid. If all conditions are met, it
 // builds and inserts the paired instruction.
-bool RISCVLoadStoreOpt::tryConvertToLdStPair(
+bool RISCVLoadStoreOptImpl::tryConvertToLdStPair(
     MachineBasicBlock::iterator First, MachineBasicBlock::iterator Second) {
   MachineFunction *MF = First->getMF();
 
@@ -564,8 +574,8 @@ static bool mayAlias(MachineInstr &MIa,
 // This requires more sophisticated checks for aliasing, register
 // liveness, and potential scheduling hazards.
 MachineBasicBlock::iterator
-RISCVLoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
-                                    bool &MergeForward) {
+RISCVLoadStoreOptImpl::findMatchingInsn(MachineBasicBlock::iterator I,
+                                        bool &MergeForward) {
   MachineBasicBlock::iterator E = I->getParent()->end();
   MachineBasicBlock::iterator MBBI = I;
   MachineInstr &FirstMI = *I;
@@ -677,9 +687,9 @@ RISCVLoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
 }
 
 MachineBasicBlock::iterator
-RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
-                                    MachineBasicBlock::iterator Paired,
-                                    bool MergeForward) {
+RISCVLoadStoreOptImpl::mergePairedInsns(MachineBasicBlock::iterator I,
+                                        MachineBasicBlock::iterator Paired,
+                                        bool MergeForward) {
   MachineBasicBlock::iterator E = I->getParent()->end();
   MachineBasicBlock::iterator NextI = next_nodbg(I, E);
   // If NextI is the second of the two instructions to be merged, skip one
@@ -763,7 +773,8 @@ RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
 // Post reg-alloc zilsd pass implementation
 //===----------------------------------------------------------------------===//
 
-bool RISCVLoadStoreOpt::isValidZilsdRegPair(Register First, Register Second) {
+bool RISCVLoadStoreOptImpl::isValidZilsdRegPair(Register First,
+                                                Register Second) {
   // Special case: First register can not be zero unless both registers are
   // zeros.
   // Spec says: LD instructions with destination x0 are processed as any other
@@ -781,9 +792,9 @@ bool RISCVLoadStoreOpt::isValidZilsdRegPair(Register First, Register Second) {
   return (FirstNum % 2 == 0) && (SecondNum == FirstNum + 1);
 }
 
-void RISCVLoadStoreOpt::splitLdSdIntoTwo(MachineBasicBlock &MBB,
-                                         MachineBasicBlock::iterator &MBBI,
-                                         bool IsLoad) {
+void RISCVLoadStoreOptImpl::splitLdSdIntoTwo(MachineBasicBlock &MBB,
+                                             MachineBasicBlock::iterator &MBBI,
+                                             bool IsLoad) {
   MachineInstr *MI = &*MBBI;
   DebugLoc DL = MI->getDebugLoc();
 
@@ -877,8 +888,8 @@ void RISCVLoadStoreOpt::splitLdSdIntoTwo(MachineBasicBlock &MBB,
   MBBI = MBB.erase(MBBI);
 }
 
-bool RISCVLoadStoreOpt::fixInvalidRegPairOp(MachineBasicBlock &MBB,
-                                            MachineBasicBlock::iterator &MBBI) {
+bool RISCVLoadStoreOptImpl::fixInvalidRegPairOp(
+    MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) {
   MachineInstr *MI = &*MBBI;
   unsigned Opcode = MI->getOpcode();
 
@@ -936,6 +947,29 @@ bool RISCVLoadStoreOpt::fixInvalidRegPairOp(MachineBasicBlock &MBB,
 }
 
 // Returns an instance of the Load / Store Optimization pass.
-FunctionPass *llvm::createRISCVLoadStoreOptPass() {
-  return new RISCVLoadStoreOpt();
+FunctionPass *llvm::createRISCVLoadStoreOptLegacyPass() {
+  return new RISCVLoadStoreOptLegacy();
+}
+
+bool RISCVLoadStoreOptLegacy::runOnMachineFunction(MachineFunction &MF) {
+  if (skipFunction(MF.getFunction()))
+    return false;
+  RISCVLoadStoreOptImpl Impl;
+  return Impl.runOnMachineFunction(MF, [&]() {
+    return &getAnalysis<AAResultsWrapperPass>().getAAResults();
+  });
+}
+
+PreservedAnalyses
+RISCVLoadStoreOptPass::run(MachineFunction &MF,
+                           MachineFunctionAnalysisManager &MFAM) {
+  RISCVLoadStoreOptImpl Impl;
+  bool Changed = Impl.runOnMachineFunction(MF, [&]() {
+    return &MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+                .getManager()
+                .getResult<AAManager>(MF.getFunction());
+  });
+  return Changed ? getMachineFunctionPassPreservedAnalyses()
+                       .preserveSet<CFGAnalyses>()
+                 : PreservedAnalyses::all();
 }
diff --git a/llvm/lib/Target/RISCV/RISCVPassRegistry.def b/llvm/lib/Target/RISCV/RISCVPassRegistry.def
index c909234e4004c..905c3fe29c771 100644
--- a/llvm/lib/Target/RISCV/RISCVPassRegistry.def
+++ b/llvm/lib/Target/RISCV/RISCVPassRegistry.def
@@ -52,6 +52,7 @@ MACHINE_FUNCTION_PASS("riscv-insert-vsetvli", RISCVInsertVSETVLIPass())
 MACHINE_FUNCTION_PASS("riscv-insert-write-vxrm", RISCVInsertWriteVXRMPass())
 MACHINE_FUNCTION_PASS("riscv-isel", RISCVISelDAGToDAGPass(*this, getOptLevel()))
 MACHINE_FUNCTION_PASS("riscv-late-branch-opt", RISCVLateBranchOptPass())
+MACHINE_FUNCTION_PASS("riscv-load-store-opt", RISCVLoadStoreOptPass())
 MACHINE_FUNCTION_PASS("riscv-lpad-setup", RISCVLandingPadSetupPass())
 MACHINE_FUNCTION_PASS("riscv-make-compressible", RISCVMakeCompressiblePass())
 MACHINE_FUNCTION_PASS("riscv-merge-base-offset", RISCVMergeBaseOffsetPass())
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index eda36ce5e0521..aa91c3de66061 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -76,7 +76,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
   initializeRISCVMoveMergeLegacyPass(*PR);
   initializeRISCVPushPopOptLegacyPass(*PR);
   initializeRISCVIndirectBranchTrackingLegacyPass(*PR);
-  initializeRISCVLoadStoreOptPass(*PR);
+  initializeRISCVLoadStoreOptLegacyPass(*PR);
   initializeRISCVPreAllocZilsdOptPass(*PR);
   initializeRISCVExpandPseudoAtomicsLegacyPass(*PR);
   initializeRISCVRedundantCopyEliminationLegacyPass(*PR);
@@ -491,7 +491,7 @@ void RISCVPassConfig::addPreSched2() {
   // Emit KCFI checks for indirect calls.
   addPass(createKCFIPass());
   if (TM->getOptLevel() != CodeGenOptLevel::None)
-    addPass(createRISCVLoadStoreOptPass());
+    addPass(createRISCVLoadStoreOptLegacyPass());
 }
 
 void RISCVPassConfig::addPreEmitPass() {

``````````

</details>


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


More information about the llvm-branch-commits mailing list