[llvm] [RISCV] Port Fold Memory Offset Pass to NewPM (PR #215672)

Sam Elliott via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 21:46:14 PDT 2026


https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/215672

>From 52b19579193f2d85228c70f06206a8afdb35adc3 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Fri, 7 Aug 2026 16:57:30 -0700
Subject: [PATCH 1/3] [RISCV] Port Fold Memory Offset Pass to NewPM

Assisted-by: AI
---
 llvm/lib/Target/RISCV/RISCV.h                 |  3 --
 .../Target/RISCV/RISCVCodeGenPassBuilder.cpp  |  2 +-
 llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp  | 53 +++++++++++++------
 llvm/lib/Target/RISCV/RISCVFoldMemOffset.h    | 36 +++++++++++++
 llvm/lib/Target/RISCV/RISCVPassRegistry.def   |  1 +
 llvm/lib/Target/RISCV/RISCVTargetMachine.cpp  |  2 +-
 llvm/test/CodeGen/RISCV/O1-newpm-pipeline.ll  |  1 +
 llvm/test/CodeGen/RISCV/O3-newpm-pipeline.ll  |  1 +
 llvm/test/CodeGen/RISCV/fold-mem-offset.mir   |  1 +
 9 files changed, 79 insertions(+), 21 deletions(-)
 create mode 100644 llvm/lib/Target/RISCV/RISCVFoldMemOffset.h

diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 68f0a0ae0bee0..28fe07f4c8d1b 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -91,9 +91,6 @@ void initializeRISCVVectorPeepholeLegacyPass(PassRegistry &);
 FunctionPass *createRISCVOptWInstrsPass();
 void initializeRISCVOptWInstrsPass(PassRegistry &);
 
-FunctionPass *createRISCVFoldMemOffsetPass();
-void initializeRISCVFoldMemOffsetPass(PassRegistry &);
-
 FunctionPass *createRISCVMergeBaseOffsetOptPass();
 void initializeRISCVMergeBaseOffsetOptPass(PassRegistry &);
 
diff --git a/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp b/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp
index 3548a3ceea207..52bd413aa424f 100644
--- a/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp
@@ -114,7 +114,7 @@ void RISCVCodeGenPassBuilder::addMachineSSAOptimization(
   }
 
   addMachineFunctionPass(RISCVVectorPeepholePass(), PMW);
-  // TODO: RISCVFoldMemOffsetPass
+  addMachineFunctionPass(RISCVFoldMemOffsetPass(), PMW);
 
   Base::addMachineSSAOptimization(PMW);
 
diff --git a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
index 46d9fee2c9572..defb68de3b504 100644
--- a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
@@ -15,7 +15,7 @@
 //
 //===---------------------------------------------------------------------===//
 
-#include "RISCV.h"
+#include "RISCVFoldMemOffset.h"
 #include "RISCVSubtarget.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
@@ -28,17 +28,23 @@ using namespace llvm;
 
 namespace {
 
-class RISCVFoldMemOffset : public MachineFunctionPass {
+class RISCVFoldMemOffsetImpl {
 public:
-  static char ID;
-
-  RISCVFoldMemOffset() : MachineFunctionPass(ID) {}
-
-  bool runOnMachineFunction(MachineFunction &MF) override;
+  bool run(MachineFunction &MF);
 
+private:
   bool foldOffset(Register OrigReg, int64_t InitialOffset,
                   const MachineRegisterInfo &MRI,
                   DenseMap<MachineInstr *, int64_t> &FoldableInstrs);
+};
+
+class RISCVFoldMemOffsetLegacy : public MachineFunctionPass {
+public:
+  static char ID;
+
+  RISCVFoldMemOffsetLegacy() : MachineFunctionPass(ID) {}
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
@@ -74,12 +80,12 @@ class FoldableOffset {
 
 } // end anonymous namespace
 
-char RISCVFoldMemOffset::ID = 0;
-INITIALIZE_PASS(RISCVFoldMemOffset, DEBUG_TYPE, RISCV_FOLD_MEM_OFFSET_NAME,
-                false, false)
+char RISCVFoldMemOffsetLegacy::ID = 0;
+INITIALIZE_PASS(RISCVFoldMemOffsetLegacy, DEBUG_TYPE,
+                RISCV_FOLD_MEM_OFFSET_NAME, false, false)
 
 FunctionPass *llvm::createRISCVFoldMemOffsetPass() {
-  return new RISCVFoldMemOffset();
+  return new RISCVFoldMemOffsetLegacy();
 }
 
 // Walk forward from the ADDI looking for arithmetic instructions we can
@@ -89,7 +95,7 @@ FunctionPass *llvm::createRISCVFoldMemOffsetPass() {
 // calculate the contribution to the output of this instruction.
 // Only addition and left shift are supported.
 // FIXME: Add multiplication by constant. The constant will be in a register.
-bool RISCVFoldMemOffset::foldOffset(
+bool RISCVFoldMemOffsetImpl::foldOffset(
     Register OrigReg, int64_t InitialOffset, const MachineRegisterInfo &MRI,
     DenseMap<MachineInstr *, int64_t> &FoldableInstrs) {
   // Map to hold how much the offset contributes to the value of this register.
@@ -235,10 +241,7 @@ bool RISCVFoldMemOffset::foldOffset(
   return true;
 }
 
-bool RISCVFoldMemOffset::runOnMachineFunction(MachineFunction &MF) {
-  if (skipFunction(MF.getFunction()))
-    return false;
-
+bool RISCVFoldMemOffsetImpl::run(MachineFunction &MF) {
   // This optimization may increase size by preventing compression.
   if (MF.getFunction().hasOptSize())
     return false;
@@ -286,3 +289,21 @@ bool RISCVFoldMemOffset::runOnMachineFunction(MachineFunction &MF) {
 
   return MadeChange;
 }
+
+bool RISCVFoldMemOffsetLegacy::runOnMachineFunction(MachineFunction &MF) {
+  if (skipFunction(MF.getFunction()))
+    return false;
+  return RISCVFoldMemOffsetImpl().run(MF);
+}
+
+PreservedAnalyses
+RISCVFoldMemOffsetPass::run(MachineFunction &MF,
+                            MachineFunctionAnalysisManager &MFAM) {
+  bool Changed = RISCVFoldMemOffsetImpl().run(MF);
+  if (!Changed)
+    return PreservedAnalyses::all();
+
+  PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+  PA.preserveSet<CFGAnalyses>();
+  return PA;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.h b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.h
new file mode 100644
index 0000000000000..4c4212c65ac21
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file declares the RISC-V memory offset folding passes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVFOLDMEMOFFSET_H
+#define LLVM_LIB_TARGET_RISCV_RISCVFOLDMEMOFFSET_H
+
+#include "llvm/CodeGen/MachinePassManager.h"
+
+namespace llvm {
+
+class FunctionPass;
+class PassRegistry;
+
+class RISCVFoldMemOffsetPass
+    : public OptionalPassInfoMixin<RISCVFoldMemOffsetPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createRISCVFoldMemOffsetPass();
+void initializeRISCVFoldMemOffsetLegacyPass(PassRegistry &);
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_RISCV_RISCVFOLDMEMOFFSET_H
diff --git a/llvm/lib/Target/RISCV/RISCVPassRegistry.def b/llvm/lib/Target/RISCV/RISCVPassRegistry.def
index 23e783b4038d7..173c803646966 100644
--- a/llvm/lib/Target/RISCV/RISCVPassRegistry.def
+++ b/llvm/lib/Target/RISCV/RISCVPassRegistry.def
@@ -33,6 +33,7 @@ FUNCTION_PASS("riscv-zacas-abi-fix", RISCVZacasABIFixPass(this))
 #define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS)
 #endif
 MACHINE_FUNCTION_PASS("riscv-asm-printer", RISCVAsmPrinterPass())
+MACHINE_FUNCTION_PASS("riscv-fold-mem-offset", RISCVFoldMemOffsetPass())
 MACHINE_FUNCTION_PASS("riscv-isel", RISCVISelDAGToDAGPass(*this, getOptLevel()))
 MACHINE_FUNCTION_PASS("riscv-vector-peephole", RISCVVectorPeepholePass())
 MACHINE_FUNCTION_PASS("riscv-vl-optimizer", RISCVVLOptimizerPass())
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 078c6185e3812..f8962c8d333db 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -133,7 +133,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
   initializeRISCVPostRAExpandPseudoPass(*PR);
   initializeRISCVMergeBaseOffsetOptPass(*PR);
   initializeRISCVOptWInstrsPass(*PR);
-  initializeRISCVFoldMemOffsetPass(*PR);
+  initializeRISCVFoldMemOffsetLegacyPass(*PR);
   initializeRISCVPreRAExpandPseudoPass(*PR);
   initializeRISCVExpandPseudoPass(*PR);
   initializeRISCVVectorPeepholeLegacyPass(*PR);
diff --git a/llvm/test/CodeGen/RISCV/O1-newpm-pipeline.ll b/llvm/test/CodeGen/RISCV/O1-newpm-pipeline.ll
index 26f1074837f79..d25902948a166 100644
--- a/llvm/test/CodeGen/RISCV/O1-newpm-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O1-newpm-pipeline.ll
@@ -48,6 +48,7 @@
 ; CHECK-NEXT:     early-machinelicm
 ; CHECK-NEXT:     riscv-vl-optimizer
 ; CHECK-NEXT:     riscv-vector-peephole
+; CHECK-NEXT:     riscv-fold-mem-offset
 ; CHECK-NEXT:     early-tailduplication
 ; CHECK-NEXT:     opt-phis
 ; CHECK-NEXT:     stack-coloring
diff --git a/llvm/test/CodeGen/RISCV/O3-newpm-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-newpm-pipeline.ll
index 85cda9082b906..45ce42dd1fb67 100644
--- a/llvm/test/CodeGen/RISCV/O3-newpm-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O3-newpm-pipeline.ll
@@ -48,6 +48,7 @@
 ; CHECK-NEXT:     early-machinelicm
 ; CHECK-NEXT:     riscv-vl-optimizer
 ; CHECK-NEXT:     riscv-vector-peephole
+; CHECK-NEXT:     riscv-fold-mem-offset
 ; CHECK-NEXT:     early-tailduplication
 ; CHECK-NEXT:     opt-phis
 ; CHECK-NEXT:     stack-coloring
diff --git a/llvm/test/CodeGen/RISCV/fold-mem-offset.mir b/llvm/test/CodeGen/RISCV/fold-mem-offset.mir
index 41afa26e70641..9b39ece2196ca 100644
--- a/llvm/test/CodeGen/RISCV/fold-mem-offset.mir
+++ b/llvm/test/CodeGen/RISCV/fold-mem-offset.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
 # RUN: llc %s -mtriple=riscv32 -run-pass=riscv-fold-mem-offset -verify-machineinstrs -o - | FileCheck %s
+# RUN: llc %s -mtriple=riscv32 -passes=riscv-fold-mem-offset -verify-machineinstrs -o - | FileCheck %s
 
 ---
 name:            crash

>From abf09fa0aa073122eafc20fa63b8a473f118ce5d Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Tue, 11 Aug 2026 21:35:42 -0700
Subject: [PATCH 2/3] Preserve MachineRegisterClassAnalysis

---
 llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
index defb68de3b504..0469271a21227 100644
--- a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
@@ -305,5 +305,6 @@ RISCVFoldMemOffsetPass::run(MachineFunction &MF,
 
   PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
   PA.preserveSet<CFGAnalyses>();
+  PA.preserve<MachineRegisterClassAnalysis>();
   return PA;
 }

>From e22ebd0525e3673b1180a8933189d73a01e15a6c Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 19 Aug 2026 23:39:09 -0700
Subject: [PATCH 3/3] Header to RISCV.h, rename to
 createRISCVFoldMemOffsetLegacyPass

---
 llvm/lib/Target/RISCV/RISCV.h                | 10 ++++++
 llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp |  4 +--
 llvm/lib/Target/RISCV/RISCVFoldMemOffset.h   | 36 --------------------
 llvm/lib/Target/RISCV/RISCVTargetMachine.cpp |  2 +-
 4 files changed, 13 insertions(+), 39 deletions(-)
 delete mode 100644 llvm/lib/Target/RISCV/RISCVFoldMemOffset.h

diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 28fe07f4c8d1b..356dc442d9878 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -91,6 +91,16 @@ void initializeRISCVVectorPeepholeLegacyPass(PassRegistry &);
 FunctionPass *createRISCVOptWInstrsPass();
 void initializeRISCVOptWInstrsPass(PassRegistry &);
 
+class RISCVFoldMemOffsetPass
+    : public OptionalPassInfoMixin<RISCVFoldMemOffsetPass> {
+public:
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createRISCVFoldMemOffsetLegacyPass();
+void initializeRISCVFoldMemOffsetLegacyPass(PassRegistry &);
+
 FunctionPass *createRISCVMergeBaseOffsetOptPass();
 void initializeRISCVMergeBaseOffsetOptPass(PassRegistry &);
 
diff --git a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
index 0469271a21227..e9091a8c8b540 100644
--- a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.cpp
@@ -15,7 +15,7 @@
 //
 //===---------------------------------------------------------------------===//
 
-#include "RISCVFoldMemOffset.h"
+#include "RISCV.h"
 #include "RISCVSubtarget.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
@@ -84,7 +84,7 @@ char RISCVFoldMemOffsetLegacy::ID = 0;
 INITIALIZE_PASS(RISCVFoldMemOffsetLegacy, DEBUG_TYPE,
                 RISCV_FOLD_MEM_OFFSET_NAME, false, false)
 
-FunctionPass *llvm::createRISCVFoldMemOffsetPass() {
+FunctionPass *llvm::createRISCVFoldMemOffsetLegacyPass() {
   return new RISCVFoldMemOffsetLegacy();
 }
 
diff --git a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.h b/llvm/lib/Target/RISCV/RISCVFoldMemOffset.h
deleted file mode 100644
index 4c4212c65ac21..0000000000000
--- a/llvm/lib/Target/RISCV/RISCVFoldMemOffset.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file declares the RISC-V memory offset folding passes.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_RISCV_RISCVFOLDMEMOFFSET_H
-#define LLVM_LIB_TARGET_RISCV_RISCVFOLDMEMOFFSET_H
-
-#include "llvm/CodeGen/MachinePassManager.h"
-
-namespace llvm {
-
-class FunctionPass;
-class PassRegistry;
-
-class RISCVFoldMemOffsetPass
-    : public OptionalPassInfoMixin<RISCVFoldMemOffsetPass> {
-public:
-  PreservedAnalyses run(MachineFunction &MF,
-                        MachineFunctionAnalysisManager &MFAM);
-};
-
-FunctionPass *createRISCVFoldMemOffsetPass();
-void initializeRISCVFoldMemOffsetLegacyPass(PassRegistry &);
-
-} // namespace llvm
-
-#endif // LLVM_LIB_TARGET_RISCV_RISCVFOLDMEMOFFSET_H
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index f8962c8d333db..23621c02687ba 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -625,7 +625,7 @@ void RISCVPassConfig::addMachineSSAOptimization() {
   }
 
   addPass(createRISCVVectorPeepholeLegacyPass());
-  addPass(createRISCVFoldMemOffsetPass());
+  addPass(createRISCVFoldMemOffsetLegacyPass());
 
   TargetPassConfig::addMachineSSAOptimization();
 



More information about the llvm-commits mailing list