[Mlir-commits] [mlir] [mlir][Transform] Fix crash in SequenceOp::getEffects when body region is empty (PR #185063)
Mehdi Amini
llvmlistbot at llvm.org
Wed Mar 11 04:48:13 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/185063
>From e795012962c51d176160b2a384f54a078a3050f3 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 6 Mar 2026 05:58:14 -0800
Subject: [PATCH] [mlir][Transform] Fix crash in SequenceOp::getEffects when
body region is empty
When walking operations post-order and erasing blocks, the inner body block of
a nested transform.sequence can be erased while the outer op is still alive.
If printAsOperand is called on the outer block at that point, it triggers
verification, which calls SequenceOp::getEffects -> getPotentialTopLevelEffects
-> getBodyBlock() -> Region::front() on an empty region, causing an assertion
failure in ilist_iterator ('\!NodePtr->isKnownSentinel()').
Fix by checking that the body region is non-empty before passing its front block
to detail::getPotentialTopLevelEffects in the PossibleTopLevelTransformOpTrait.
Fixes #60213
Assisted-by: Claude Code
---
.../Transform/Interfaces/TransformInterfaces.h | 5 ++++-
mlir/test/IR/visitors.mlir | 16 ++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h b/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h
index c2ceaba1128a3..c32d4a81a63ab 100644
--- a/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h
+++ b/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h
@@ -1169,9 +1169,12 @@ class PossibleTopLevelTransformOpTrait
/// Populates `effects` with side effects implied by this trait.
void getPotentialTopLevelEffects(
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
+ Region ®ion = this->getOperation()->getRegion(0);
+ if (region.empty())
+ return;
detail::getPotentialTopLevelEffects(
this->getOperation(), cast<OpTy>(this->getOperation()).getRoot(),
- *getBodyBlock(), effects);
+ region.front(), effects);
}
/// Sets up the mapping between the entry block of the given region of this op
diff --git a/mlir/test/IR/visitors.mlir b/mlir/test/IR/visitors.mlir
index e56c67922a662..93bb746528baf 100644
--- a/mlir/test/IR/visitors.mlir
+++ b/mlir/test/IR/visitors.mlir
@@ -444,3 +444,19 @@ func.func @graph_region_skip(%fill: tensor<2xf32>, %output: tensor<2xf32>) {
}
return
}
+
+// -----
+
+// Regression test for https://github.com/llvm/llvm-project/issues/60213:
+// testNoSkipErasureCallbacks should not crash when getEffects is called on a
+// transform.sequence op whose body block has already been erased. Previously
+// printAsOperand triggered verification which called SequenceOp::getEffects ->
+// getBodyBlock() -> Region::front() on an empty region, causing an assertion.
+// CHECK-LABEL: Block post-order erasures (no skip)
+// CHECK: Erasing block {{.*}} from region 0 from operation 'transform.sequence'
+transform.sequence failures(propagate) {
+^bb0(%arg0: !pdl.operation):
+ sequence %arg0 : !pdl.operation failures(propagate) {
+ ^bb0(%arg1: !pdl.operation):
+ }
+}
More information about the Mlir-commits
mailing list