[Mlir-commits] [mlir] [mlir] Fix non-termination when a block becomes unreachable during rewriting (PR #221152)
Matthias Springer
llvmlistbot at llvm.org
Sat Sep 5 08:58:43 PDT 2026
matthias-springer wrote:
Can you try something like this? I believe the worklist-based IR walk from #221037 is not necessary.
```
--- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
+++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
@@ -166,12 +166,14 @@ simplifyBrToBlockWithSinglePred(BranchOp op, PatternRewriter &rewriter) {
if (succ == opParent || !llvm::hasSingleElement(succ->getPredecessors()))
return failure();
- // If any branch operand is itself a block argument of the successor, merging
- // would call replaceAllUsesWith(arg, arg) — a no-op — leaving dangling uses
- // of that argument after the successor block is erased.
- for (Value operand : op.getOperands())
- if (auto ba = dyn_cast<BlockArgument>(operand))
- if (ba.getOwner() == succ)
+ // Merging replaces the successor's arguments with this branch's operands. If
+ // an argument is already used in the predecessor, that replacement feeds a
+ // value derived from the argument back into its own uses: either a no-op
+ // replaceAllUsesWith(arg, arg) that leaves the argument live after the block
+ // is erased, or a self-referential op such as `%0 = arith.addi %0, %c1`.
+ for (BlockArgument arg : succ->getArguments())
+ for (Operation *user : arg.getUsers())
+ if (user->getBlock() == opParent)
return failure();
// Merge the successor into the current block and erase the branch.
```
https://github.com/llvm/llvm-project/pull/221152
More information about the Mlir-commits
mailing list