[Mlir-commits] [mlir] [mlir][linalg] Bail out of decomposition when peeled stmt has no results (PR #222618)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Sep 10 04:39:02 PDT 2026


https://github.com/AkunCube created https://github.com/llvm/llvm-project/pull/222618

Current `DecomposeLinalgOp` peels the first statement of a linalg.generic body into a new generic op and then calls `replaceOpUsesWithinBlock` on the peeled operation to rewire its uses within the residual op.

When the peeled statement produces no results (e.g. a bufferization.dealloc_tensor as the first body statement), replaceOpUsesWithinBlock iterates over zero results and leaves allUsesReplaced vacuously true, tripping the assertion and crashing mlir-opt -test-linalg-decompose-ops.

Reject such ops up front with a notifyMatchFailure instead of letting the decomposition proceed and crash, and add a regression test.

Fixed: #220523

>From 1312b506d8159dfdb02d6f3179f06a4c8d7ad424 Mon Sep 17 00:00:00 2001
From: cubehan3 <cubehan3 at gmail.com>
Date: Mon, 7 Sep 2026 11:27:15 +0000
Subject: [PATCH] [mlir][linalg] Bail out of decomposition when peeled stmt has
 no results

---
 .../Linalg/Transforms/DecomposeLinalgOps.cpp  |  7 ++++
 mlir/test/Dialect/Linalg/decompose-ops.mlir   | 36 +++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp b/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp
index 3c8d2aadc8c75..2fb5d11f95a37 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp
@@ -266,6 +266,13 @@ DecomposeLinalgOp::matchAndRewrite(GenericOp genericOp,
                                        "operation has less than 3 statements");
   }
 
+  /// The peeled statement is expected to produce at least one result.
+  if (body->getOperations().begin()->getNumResults() == 0) {
+    return rewriter.notifyMatchFailure(
+        &(*body->getOperations().begin()),
+        "peeled statement is expected to have at least one result");
+  }
+
   /// Check that the peeled statement has a scalar element type.
   if (llvm::any_of(body->getOperations().begin()->getResultTypes(),
                    [](Type t) { return !t.isIntOrIndexOrFloat(); })) {
diff --git a/mlir/test/Dialect/Linalg/decompose-ops.mlir b/mlir/test/Dialect/Linalg/decompose-ops.mlir
index d5be02976a663..43bd42528f34f 100644
--- a/mlir/test/Dialect/Linalg/decompose-ops.mlir
+++ b/mlir/test/Dialect/Linalg/decompose-ops.mlir
@@ -416,3 +416,39 @@ func.func @destination_passing_style(
 // CANONICALIZECHECK-NEXT:     %[[S2:.+]] = arith.mulf %[[ARG4]], %[[ARG6]]
 // CANONICALIZECHECK-NEXT:     linalg.yield %[[ARG5]], %[[S2]]
 //      CANONICALIZECHECK:   return %[[GENERIC1]], %[[GENERIC2]]#1
+
+// -----
+
+// The peeled statement is expected to produce at least one result. Here the
+// first statement (`bufferization.dealloc_tensor`) has no results, so the
+// operation is not decomposed.
+#map0 = affine_map<(d0) -> (d0)>
+func.func @first_statement_no_result(%arg0 : tensor<27xi32>) -> tensor<27xi32> {
+  %init = tensor.empty() : tensor<27xi32>
+  %r = linalg.generic {
+    indexing_maps = [#map0, #map0],
+    iterator_types = ["parallel"]}
+    ins(%arg0 : tensor<27xi32>)
+    outs(%init : tensor<27xi32>) {
+    ^bb0(%b0 : i32, %b1 : i32):
+      bufferization.dealloc_tensor %init : tensor<27xi32>
+      %0 = arith.addi %b0, %b1 : i32
+      linalg.yield %0 : i32
+  } -> tensor<27xi32>
+  return %r : tensor<27xi32>
+}
+//  CHECK-DAG: #[[MAP0:.+]] = affine_map<(d0) -> (d0)>
+//      CHECK: func.func @first_statement_no_result(
+//      CHECK:   %[[GENERIC:.+]] = linalg.generic
+//      CHECK:   bufferization.dealloc_tensor
+//      CHECK:   arith.addi
+//      CHECK:   linalg.yield
+//      CHECK:   return %[[GENERIC]]
+
+// CANONICALIZECHECK-DAG: #[[MAP0:.+]] = affine_map<(d0) -> (d0)>
+//      CANONICALIZECHECK: func.func @first_statement_no_result(
+//      CANONICALIZECHECK:   %[[GENERIC:.+]] = linalg.generic
+//      CANONICALIZECHECK:   bufferization.dealloc_tensor
+//      CANONICALIZECHECK:   arith.addi
+//      CANONICALIZECHECK:   linalg.yield
+//      CANONICALIZECHECK:   return %[[GENERIC]]



More information about the Mlir-commits mailing list