[Mlir-commits] [mlir] 53107fb - [MLIR] Prevent CF to SCF transform from erasing blocks still in use (#206310)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Jul 1 05:16:39 PDT 2026


Author: Martin P
Date: 2026-07-01T12:16:34Z
New Revision: 53107fb19af49724ae810bf8fb0c8356759124ed

URL: https://github.com/llvm/llvm-project/commit/53107fb19af49724ae810bf8fb0c8356759124ed
DIFF: https://github.com/llvm/llvm-project/commit/53107fb19af49724ae810bf8fb0c8356759124ed.diff

LOG: [MLIR] Prevent CF to SCF transform from erasing blocks still in use (#206310)

While merging blocks, `transformToStructuredCFBranches` may try to erase
blocks that still have uses. This may happen when the block has
self-loop or when it has 1 successor, but the successor has multiple
predecessors. This probably happens only with unreachable blocks in the
function.

Note that running a DCE pass before CF to SCF transform would remove the
triggering assert in the lit test.

Fixes #206086.

Added: 
    mlir/test/Conversion/ControlFlowToSCF/unreachable-blocks.mlir

Modified: 
    mlir/include/mlir/Transforms/CFGToSCF.h
    mlir/lib/Transforms/Utils/CFGToSCF.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Transforms/CFGToSCF.h b/mlir/include/mlir/Transforms/CFGToSCF.h
index 517e116f3c58e..2ca019ddfe23d 100644
--- a/mlir/include/mlir/Transforms/CFGToSCF.h
+++ b/mlir/include/mlir/Transforms/CFGToSCF.h
@@ -149,9 +149,10 @@ class CFGToSCFInterface {
 /// Otherwise a single control flow graph operation branching to one block
 /// per return-like operation kind remains.
 ///
-/// The transformation currently requires that all control flow graph operations
-/// have no side effects, implement the BranchOpInterface and does not have any
-/// operation produced successor operands.
+/// The transformation currently requires that the region has no unreachable
+/// blocks and that all control flow graph operations have no side effects,
+/// implement the BranchOpInterface and does not have any operation produced
+/// successor operands.
 /// Returns failure if any of the preconditions are violated or if any of the
 /// methods of `interface` failed. The IR is left in an unspecified state.
 ///

diff  --git a/mlir/lib/Transforms/Utils/CFGToSCF.cpp b/mlir/lib/Transforms/Utils/CFGToSCF.cpp
index 0cc6bb43ddd38..2cda4a26543bd 100644
--- a/mlir/lib/Transforms/Utils/CFGToSCF.cpp
+++ b/mlir/lib/Transforms/Utils/CFGToSCF.cpp
@@ -1234,8 +1234,13 @@ static ReturnLikeExitCombiner createSingleExitBlocksForReturnLike(
 /// Returns failure if any precondition is violated.
 static LogicalResult
 checkTransformationPreconditions(Region &region, CFGToSCFInterface &interface) {
+  llvm::df_iterator_default_set<Block *, 16> reachable;
+  // Find all blocks reachable from the entry.
+  for (Block *block : depth_first_ext(&region.front(), reachable))
+    (void)block;
+
   for (Block &block : region.getBlocks())
-    if (block.hasNoPredecessors() && !block.isEntryBlock())
+    if (!reachable.contains(&block))
       return block.front().emitOpError(
           "transformation does not support unreachable blocks");
 

diff  --git a/mlir/test/Conversion/ControlFlowToSCF/unreachable-blocks.mlir b/mlir/test/Conversion/ControlFlowToSCF/unreachable-blocks.mlir
new file mode 100644
index 0000000000000..4317e5a5a8102
--- /dev/null
+++ b/mlir/test/Conversion/ControlFlowToSCF/unreachable-blocks.mlir
@@ -0,0 +1,18 @@
+// RUN: mlir-opt --lift-cf-to-scf -verify-diagnostics -split-input-file %s
+
+// Verify that --lift-cf-to-scf does not crash when it encounters an
+// unreachable blocks (dead code).  Instead it should emit a clean error.
+// See: https://github.com/llvm/llvm-project/issues/206086
+
+module {
+  func.func @single_return_statement(%arg0: i32) -> i32 {
+    return %arg0 : i32
+  ^bb1:  // pred: ^bb1
+    // expected-error at below {{'arith.constant' op transformation does not support unreachable blocks}}
+    %true = arith.constant true
+    cf.cond_br %true, ^bb2, ^bb1
+  ^bb2:  // pred: ^bb1
+    return %arg0 : i32
+  }
+}
+


        


More information about the Mlir-commits mailing list