[Mlir-commits] [mlir] [MLIR][Transform] Fix crash in CheckUses when op lacks MemoryEffectOpInterface (PR #188998)
Mehdi Amini
llvmlistbot at llvm.org
Fri Mar 27 06:39:12 PDT 2026
https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/188998
collectFreedValues used cast<MemoryEffectOpInterface> unconditionally on every op encountered during the walk. Ops that do not implement the interface (e.g. pdl.pattern, pdl.operands, pdl.types inside a transform.with_pdl_patterns region) trigger the cast assertion, crashing mlir-opt when -transform-dialect-check-uses is requested.
Change the cast to dyn_cast and skip ops that don't implement the interface; they cannot free transform values and are safely ignored.
Fixes #120944
Assisted-by: Claude Code
>From e402b51711c8b48cb735b94c079d3ebcf4dc63d6 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 27 Mar 2026 03:56:52 -0700
Subject: [PATCH] [MLIR][Transform] Fix crash in CheckUses when op lacks
MemoryEffectOpInterface
collectFreedValues used cast<MemoryEffectOpInterface> unconditionally on
every op encountered during the walk. Ops that do not implement the
interface (e.g. pdl.pattern, pdl.operands, pdl.types inside a
transform.with_pdl_patterns region) trigger the cast assertion, crashing
mlir-opt when -transform-dialect-check-uses is requested.
Change the cast to dyn_cast and skip ops that don't implement the
interface; they cannot free transform values and are safely ignored.
Fixes #120944
Assisted-by: Claude Code
---
.../Transform/Transforms/CheckUses.cpp | 5 ++-
.../Transform/check-use-after-free.mlir | 37 +++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/Transform/Transforms/CheckUses.cpp b/mlir/lib/Dialect/Transform/Transforms/CheckUses.cpp
index 18dfd504203a9..6ef8ca6c4b3af 100644
--- a/mlir/lib/Dialect/Transform/Transforms/CheckUses.cpp
+++ b/mlir/lib/Dialect/Transform/Transforms/CheckUses.cpp
@@ -339,9 +339,12 @@ class TransformOpMemFreeAnalysis {
root->walk([&](Operation *child) {
if (isa<transform::PatternDescriptorOpInterface>(child))
return;
+ // Ops without the interface are assumed not to free any transform values.
// TODO: extend this to conservatively handle operations with undeclared
// side effects as maybe freeing the operands.
- auto iface = cast<MemoryEffectOpInterface>(child);
+ auto iface = dyn_cast<MemoryEffectOpInterface>(child);
+ if (!iface)
+ return;
instances.clear();
iface.getEffectsOnResource(transform::TransformMappingResource::get(),
instances);
diff --git a/mlir/test/Dialect/Transform/check-use-after-free.mlir b/mlir/test/Dialect/Transform/check-use-after-free.mlir
index 0fe8b5da17355..76f4b4fb6bd69 100644
--- a/mlir/test/Dialect/Transform/check-use-after-free.mlir
+++ b/mlir/test/Dialect/Transform/check-use-after-free.mlir
@@ -191,3 +191,40 @@ module attributes {transform.with_named_sequence} {
transform.yield
}
}
+
+// -----
+
+// collectFreedValues should not crash on ops that don't implement
+// MemoryEffectOpInterface (e.g. pdl ops inside with_pdl_patterns).
+// https://github.com/llvm/llvm-project/issues/120944
+
+// CHECK-LABEL: func @foo
+func.func @foo(%arg0: index, %arg1: index, %arg2: index) {
+ scf.for %i = %arg0 to %arg1 step %arg2 {
+ %0 = arith.constant 0 : i32
+ }
+ return
+}
+
+module attributes {transform.with_named_sequence} {
+ transform.named_sequence @__transform_main(%root: !transform.any_op) {
+ transform.with_pdl_patterns %root : !transform.any_op {
+ ^bb0(%arg0: !transform.any_op):
+ pdl.pattern @match_const : benefit(1) {
+ %0 = pdl.operands
+ %1 = pdl.types
+ %2 = pdl.operation "arith.constant"(%0 : !pdl.range<value>) -> (%1 : !pdl.range<type>)
+ pdl.rewrite %2 with "transform.dialect"
+ }
+ sequence %arg0 : !transform.any_op failures(propagate) {
+ ^bb1(%arg1: !transform.any_op):
+ %0 = transform.pdl_match @match_const in %arg1 : (!transform.any_op) -> !transform.any_op
+ %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.any_op
+ alternatives %1 : !transform.any_op {
+ ^bb2(%arg2: !transform.any_op):
+ }
+ }
+ }
+ transform.yield
+ }
+}
More information about the Mlir-commits
mailing list