[Mlir-commits] [mlir] [mlir][reducer] Remove the restriction that OptReductionPass must be a ModuleOp (PR #189038)

lonely eagle llvmlistbot at llvm.org
Fri Mar 27 09:07:55 PDT 2026


https://github.com/linuxlonelyeagle created https://github.com/llvm/llvm-project/pull/189038

This PR aims to make the pass more generic by removing the ModuleOp restriction. This PR reimplements the logic using a standalone PassManager. Additionally, the isInteresting method has been updated to accept Operation* for better flexibility. Finally, a dedicated test directory has been added to improve the organization of OptReductionPass tests.

>From 11d00119567a4c6d15d09786fd88008fdc0ac942 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Fri, 27 Mar 2026 15:55:50 +0000
Subject: [PATCH] make opt-reduction pass can run on funcOp.

---
 mlir/include/mlir/Reducer/Passes.td           |  2 +-
 mlir/include/mlir/Reducer/Tester.h            |  2 +-
 mlir/lib/Reducer/OptReductionPass.cpp         | 33 +++++++++----------
 mlir/lib/Reducer/Tester.cpp                   |  6 ++--
 mlir/test/mlir-reduce/invalid.mlir            |  2 --
 .../mlir-reduce/opt-reduction/cse-test.mlir   | 16 +++++++++
 .../{ => opt-reduction}/dce-test.mlir         |  2 +-
 7 files changed, 37 insertions(+), 26 deletions(-)
 create mode 100644 mlir/test/mlir-reduce/opt-reduction/cse-test.mlir
 rename mlir/test/mlir-reduce/{ => opt-reduction}/dce-test.mlir (93%)

diff --git a/mlir/include/mlir/Reducer/Passes.td b/mlir/include/mlir/Reducer/Passes.td
index 624e2e1edc329..d63cac535ad8f 100644
--- a/mlir/include/mlir/Reducer/Passes.td
+++ b/mlir/include/mlir/Reducer/Passes.td
@@ -34,7 +34,7 @@ def ReductionTreePass : Pass<"reduction-tree"> {
   ] # CommonReductionPassOptions.options;
 }
 
-def OptReductionPass : Pass<"opt-reduction-pass", "ModuleOp"> {
+def OptReductionPass : Pass<"opt-reduction-pass"> {
   let summary = "A wrapper pass that reduces the file with optimization passes";
 
   let options = [
diff --git a/mlir/include/mlir/Reducer/Tester.h b/mlir/include/mlir/Reducer/Tester.h
index bed4408342034..fe0b31f79090a 100644
--- a/mlir/include/mlir/Reducer/Tester.h
+++ b/mlir/include/mlir/Reducer/Tester.h
@@ -44,7 +44,7 @@ class Tester {
   /// Runs the interestingness testing script on a MLIR test case file. Returns
   /// true if the interesting behavior is present in the test case or false
   /// otherwise.
-  std::pair<Interestingness, size_t> isInteresting(ModuleOp module) const;
+  std::pair<Interestingness, size_t> isInteresting(Operation *topOp) const;
 
   /// Return whether the file in the given path is interesting.
   Interestingness isInteresting(StringRef testCase) const;
diff --git a/mlir/lib/Reducer/OptReductionPass.cpp b/mlir/lib/Reducer/OptReductionPass.cpp
index 4bdc7b17567d9..255df1ca092af 100644
--- a/mlir/lib/Reducer/OptReductionPass.cpp
+++ b/mlir/lib/Reducer/OptReductionPass.cpp
@@ -46,46 +46,43 @@ void OptReductionPass::runOnOperation() {
 
   Tester test(testerName, testerArgs);
 
-  ModuleOp module = this->getOperation();
-  ModuleOp moduleVariant = module.clone();
+  Operation *topOp = this->getOperation();
+  Operation *topOpVariant = topOp->clone();
 
-  OpPassManager passManager("builtin.module");
+  PassManager passManager(topOp->getName());
   if (failed(parsePassPipeline(optPass, passManager))) {
-    module.emitError() << "\nfailed to parse pass pipeline";
+    topOp->emitError() << "\nfailed to parse pass pipeline";
     return signalPassFailure();
   }
 
-  std::pair<Tester::Interestingness, int> original = test.isInteresting(module);
+  std::pair<Tester::Interestingness, int> original = test.isInteresting(topOp);
   if (original.first != Tester::Interestingness::True) {
-    module.emitError() << "\nthe original input is not interested";
+    topOp->emitError() << "\nthe original input is not interested";
     return signalPassFailure();
   }
 
-  // Temporarily push the variant under the main module and execute the pipeline
-  // on it.
-  module.getBody()->push_back(moduleVariant);
-  LogicalResult pipelineResult = runPipeline(passManager, moduleVariant);
-  moduleVariant->remove();
-
+  LogicalResult pipelineResult = passManager.run(topOpVariant);
   if (failed(pipelineResult)) {
-    module.emitError() << "\nfailed to run pass pipeline";
+    topOp->emitError() << "\nfailed to run pass pipeline";
     return signalPassFailure();
   }
 
   std::pair<Tester::Interestingness, int> reduced =
-      test.isInteresting(moduleVariant);
+      test.isInteresting(topOpVariant);
 
   if (reduced.first == Tester::Interestingness::True &&
       reduced.second < original.second) {
-    module.getBody()->clear();
-    module.getBody()->getOperations().splice(
-        module.getBody()->begin(), moduleVariant.getBody()->getOperations());
+    topOp->getRegion(0).getBlocks().clear();
+    topOp->getRegion(0).getBlocks().splice(
+        topOp->getRegion(0).getBlocks().begin(),
+        topOpVariant->getRegion(0).getBlocks());
+
     LDBG() << "\nSuccessful Transformed version\n";
   } else {
     LDBG() << "\nUnsuccessful Transformed version\n";
   }
 
-  moduleVariant->destroy();
+  topOpVariant->destroy();
 
   LDBG() << "Pass Complete\n";
 }
diff --git a/mlir/lib/Reducer/Tester.cpp b/mlir/lib/Reducer/Tester.cpp
index 03f12af174839..0890c7d127752 100644
--- a/mlir/lib/Reducer/Tester.cpp
+++ b/mlir/lib/Reducer/Tester.cpp
@@ -24,11 +24,11 @@ Tester::Tester(StringRef scriptName, ArrayRef<std::string> scriptArgs)
     : testScript(scriptName), testScriptArgs(scriptArgs) {}
 
 std::pair<Tester::Interestingness, size_t>
-Tester::isInteresting(ModuleOp module) const {
+Tester::isInteresting(Operation *topOp) const {
   // The reduced module should always be vaild, or we may end up retaining the
   // error message by an invalid case. Besides, an invalid module may not be
   // able to print properly.
-  if (failed(verify(module)))
+  if (failed(verify(topOp)))
     return std::make_pair(Interestingness::False, /*size=*/0);
 
   SmallString<128> filepath;
@@ -43,7 +43,7 @@ Tester::isInteresting(ModuleOp module) const {
                              ec.message());
 
   llvm::ToolOutputFile out(filepath, fd);
-  module.print(out.os());
+  topOp->print(out.os());
   out.os().close();
 
   if (out.os().has_error())
diff --git a/mlir/test/mlir-reduce/invalid.mlir b/mlir/test/mlir-reduce/invalid.mlir
index 88544bfa21519..c421e20778311 100644
--- a/mlir/test/mlir-reduce/invalid.mlir
+++ b/mlir/test/mlir-reduce/invalid.mlir
@@ -1,8 +1,6 @@
 // UNSUPPORTED: system-windows
-// RUN: not mlir-reduce -opt-reduction-pass --no-implicit-module %s 2>&1 | FileCheck %s --check-prefix=CHECK-PASS
 // RUN: not mlir-reduce -reduction-tree --no-implicit-module %s 2>&1 | FileCheck %s --check-prefix=CHECK-TREE
 
 // The reduction passes are currently restricted to 'builtin.module'.
-// CHECK-PASS: error: Can't add pass '{{.+}}' restricted to 'builtin.module' on a PassManager intended to run on 'func.func'
 // CHECK-TREE: error: top-level op must be 'builtin.module'
 func.func private @foo()
diff --git a/mlir/test/mlir-reduce/opt-reduction/cse-test.mlir b/mlir/test/mlir-reduce/opt-reduction/cse-test.mlir
new file mode 100644
index 0000000000000..34633ab10a75e
--- /dev/null
+++ b/mlir/test/mlir-reduce/opt-reduction/cse-test.mlir
@@ -0,0 +1,16 @@
+// UNSUPPORTED: system-windows
+// RUN: mlir-reduce %s --no-implicit-module -opt-reduction-pass='opt-pass=cse test=%S/../failure-test.sh' | FileCheck %s
+
+// CHECK-LABEL: func @cse_on_func
+//  CHECK-SAME:   %[[ARG0:.*]]: i32,
+//  CHECK-SAME:   %[[ARG1:.*]]: i32) {
+func.func @cse_on_func(%arg0: i32, %arg1: i32) {
+  %0 = arith.addi %arg0, %arg1 : i32
+  %1 = arith.addi %arg0, %arg1 : i32 
+  %2 = "test.op_crash_long" (%0, %0, %1) : (i32, i32, i32) -> i32
+  return
+}
+
+// CHECK: %[[ADD:.*]] = arith.addi %[[ARG0]], %[[ARG1]]
+// CHECK: %[[CRASH:.*]] = "test.op_crash_long"(%[[ADD]], %[[ADD]], %[[ADD]])
+// CHECK: return
\ No newline at end of file
diff --git a/mlir/test/mlir-reduce/dce-test.mlir b/mlir/test/mlir-reduce/opt-reduction/dce-test.mlir
similarity index 93%
rename from mlir/test/mlir-reduce/dce-test.mlir
rename to mlir/test/mlir-reduce/opt-reduction/dce-test.mlir
index 57b5fd9c2ea73..f9b016108caa5 100644
--- a/mlir/test/mlir-reduce/dce-test.mlir
+++ b/mlir/test/mlir-reduce/opt-reduction/dce-test.mlir
@@ -1,5 +1,5 @@
 // UNSUPPORTED: system-windows
-// RUN: mlir-reduce %s -opt-reduction-pass='opt-pass=symbol-dce test=%S/failure-test.sh' | FileCheck %s
+// RUN: mlir-reduce %s -opt-reduction-pass='opt-pass=symbol-dce test=%S/../failure-test.sh' | FileCheck %s
 // This input should be reduced by the pass pipeline so that only
 // the @simple1 function remains as the other functions should be
 // removed by the dead code elimination pass.



More information about the Mlir-commits mailing list