[Mlir-commits] [mlir] [mlir][transform] add ApplyEraseUnusedOperandsAndResultsPatternsOp transform op (PR #225864)

Tuomas Kärnä llvmlistbot at llvm.org
Wed Sep 23 11:00:31 PDT 2026


https://github.com/tkarna updated https://github.com/llvm/llvm-project/pull/225864

>From da43d4661a447ae0829a6a74d43a6dc344f99951 Mon Sep 17 00:00:00 2001
From: Tuomas Karna <tuomas.karna at intel.com>
Date: Wed, 23 Sep 2026 20:04:23 +0300
Subject: [PATCH 1/2] linalg: add ApplyEraseUnusedOperandsAndResultsPatternsOp
 transform op

---
 .../Linalg/TransformOps/LinalgTransformOps.td | 11 +++++++
 .../TransformOps/LinalgTransformOps.cpp       |  5 +++
 ...-op-erase-unused-operands-and-results.mlir | 32 +++++++++++++++++++
 mlir/test/python/dialects/transform.py        | 13 ++++++++
 4 files changed, 61 insertions(+)
 create mode 100644 mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir

diff --git a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 5df9e14b8a3f06..c31cd399032986 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -176,6 +176,17 @@ def ApplySwapExtractSliceWithFillPatternsOp : Op<Transform_Dialect,
   let assemblyFormat = "attr-dict";
 }
 
+def ApplyEraseUnusedOperandsAndResultsPatternsOp : Op<Transform_Dialect,
+    "apply_patterns.linalg.erase_unused_operands_and_results",
+    [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
+  let description = [{
+    Collects patterns that deduplicate operands and remove dead results of
+    `linalg.generic` ops.
+  }];
+
+  let assemblyFormat = "attr-dict";
+}
+
 //===----------------------------------------------------------------------===//
 // BufferizeToAllocationOp
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
index 16b03ab5426a0d..9e382b61e03840 100644
--- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
+++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
@@ -271,6 +271,11 @@ void transform::ApplySwapExtractSliceWithFillPatternsOp::populatePatterns(
   linalg::populateSwapExtractSliceWithFillPatterns(patterns);
 }
 
+void transform::ApplyEraseUnusedOperandsAndResultsPatternsOp::populatePatterns(
+    RewritePatternSet &patterns) {
+  linalg::populateEraseUnusedOperandsAndResultsPatterns(patterns);
+}
+
 //===----------------------------------------------------------------------===//
 // BufferizeToAllocationOp
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir b/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir
new file mode 100644
index 00000000000000..ed47329e197a1c
--- /dev/null
+++ b/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir
@@ -0,0 +1,32 @@
+// RUN: mlir-opt %s -transform-interpreter | FileCheck %s
+
+#map0 = affine_map<(d0) -> (d0)>
+func.func @remove_deadargs_generic_basic(%arg0: tensor<?xf32>) -> (tensor<?xf32>) {
+  %c0 = arith.constant 0 : index
+  %cst = arith.constant 7.0 : f32
+  %0 = tensor.dim %arg0, %c0 : tensor<?xf32>
+  %1 = tensor.empty(%0) : tensor<?xf32>
+  %2 = tensor.empty(%0) : tensor<?xf32>
+  %3 = linalg.generic {indexing_maps = [#map0, #map0, #map0], iterator_types=["parallel"]} ins(%arg0, %1 : tensor<?xf32>, tensor<?xf32>) outs (%2:tensor<?xf32>) {
+  ^bb0(%arg1: f32, %arg2: f32, %arg3: f32):
+    %4 = arith.addf  %arg1, %cst : f32
+        linalg.yield %4 : f32
+  } -> tensor<?xf32>
+  return %3 : tensor<?xf32>
+}
+
+module attributes {transform.with_named_sequence} {
+  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {
+    %f = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op
+    transform.apply_patterns to %f {
+      transform.apply_patterns.linalg.erase_unused_operands_and_results
+    } : !transform.any_op
+    transform.yield
+  }
+}
+
+// CHECK-LABEL: func @remove_deadargs_generic_basic
+//  CHECK-SAME: (%[[ARG0:.*]]: tensor<?xf32>) -> tensor<?xf32> {
+//       CHECK: %[[GENERIC_OP:.*]] = linalg.generic
+//  CHECK-SAME: ins(%[[ARG0]] : tensor<?xf32>)
+//  CHECK-SAME: outs({{.*}} : tensor<?xf32>) {
diff --git a/mlir/test/python/dialects/transform.py b/mlir/test/python/dialects/transform.py
index 4b7a2bb39c8800..55643f2bba870a 100644
--- a/mlir/test/python/dialects/transform.py
+++ b/mlir/test/python/dialects/transform.py
@@ -315,6 +315,19 @@ def testApplyLinalgSwapExtractSliceWithFillPattern(module: Module):
     # CHECK: transform.apply_patterns.linalg.swap_extract_slice_with_fill
 
 
+ at run
+def testApplyLinalgEraseUnusedOperandsAndResultsPattern(module: Module):
+    sequence = transform.SequenceOp(
+        transform.FailurePropagationMode.Propagate, [], transform.AnyOpType.get()
+    )
+    with InsertionPoint(sequence.body):
+        with InsertionPoint(transform.ApplyPatternsOp(sequence.bodyTarget).patterns):
+            structured.apply_patterns_linalg_erase_unused_operands_and_results()
+        transform.YieldOp()
+    # CHECK-LABEL: TEST: testApplyLinalgEraseUnusedOperandsAndResultsPattern
+    # CHECK: transform.apply_patterns.linalg.erase_unused_operands_and_results
+
+
 @run
 def testReplicateOp(module: Module):
     with_pdl = transform_pdl.WithPDLPatternsOp(transform.AnyOpType.get())

>From 70a665e8a9992229d1345b1eaabd1d44fb2181dc Mon Sep 17 00:00:00 2001
From: Tuomas Karna <tuomas.karna at intel.com>
Date: Wed, 23 Sep 2026 21:00:07 +0300
Subject: [PATCH 2/2] formatting

---
 .../Linalg/transform-op-erase-unused-operands-and-results.mlir | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir b/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir
index ed47329e197a1c..bd6d8399ba73bf 100644
--- a/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir
+++ b/mlir/test/Dialect/Linalg/transform-op-erase-unused-operands-and-results.mlir
@@ -10,11 +10,12 @@ func.func @remove_deadargs_generic_basic(%arg0: tensor<?xf32>) -> (tensor<?xf32>
   %3 = linalg.generic {indexing_maps = [#map0, #map0, #map0], iterator_types=["parallel"]} ins(%arg0, %1 : tensor<?xf32>, tensor<?xf32>) outs (%2:tensor<?xf32>) {
   ^bb0(%arg1: f32, %arg2: f32, %arg3: f32):
     %4 = arith.addf  %arg1, %cst : f32
-        linalg.yield %4 : f32
+    linalg.yield %4 : f32
   } -> tensor<?xf32>
   return %3 : tensor<?xf32>
 }
 
+
 module attributes {transform.with_named_sequence} {
   transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {
     %f = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op



More information about the Mlir-commits mailing list