[all-commits] [llvm/llvm-project] 48df0a: [mlir] Avoid rewriting unreachable blocks in the g...

Vijay Kandiah via All-commits all-commits at lists.llvm.org
Wed Sep 30 13:59:03 PDT 2026


  Branch: refs/heads/users/mamini/greedy-rewrite-reachability
  Home:   https://github.com/llvm/llvm-project
  Commit: 48df0ae5e97ca58de0b0698bb4bbd39b83c0feee
      https://github.com/llvm/llvm-project/commit/48df0ae5e97ca58de0b0698bb4bbd39b83c0feee
  Author: Vijay Kandiah <vkandiah at nvidia.com>
  Date:   2026-09-30 (Wed, 30 Sep 2026)

  Changed paths:
    M mlir/include/mlir/Transforms/GreedyPatternRewriteDriver.h
    M mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
    A mlir/test/Transforms/canonicalize-cfg-reachability.mlir
    M mlir/test/Transforms/canonicalize-dce.mlir
    A mlir/test/Transforms/greedy-cfg-reachability.mlir
    M mlir/test/Transforms/test-strict-pattern-driver.mlir
    M mlir/test/lib/Dialect/Test/TestEnumDefs.td
    M mlir/test/lib/Dialect/Test/TestOpDefs.cpp
    M mlir/test/lib/Dialect/Test/TestOps.td
    M mlir/test/lib/Dialect/Test/TestPatterns.cpp

  Log Message:
  -----------
  [mlir] Avoid rewriting unreachable blocks in the greedy driver

A rewrite can disconnect a block after the iteration's initial CFG
sweep. Queued operations can develop self-referential SSA uses in
unreachable code, causing crashes or repeated rewrites that prevent the
worklist pass from returning. Track reachability through rewriter
notifications and skip these operations until the next iteration removes
their blocks.

The reproducer in #221152 exposes this gap in the initial sweep added by
#153957 for #153732. #154038 similarly skips unreachable blocks in the
walk-based driver. Reachable graph-region self-cycles in #194824 and
#205064 remain separate; #207185 proposes a fold-specific fix for them.

A forwarding ReachabilityListener sits between the rewriter and the
worklist driver. Notifications only record what changed: terminator
changes and removed blocks are recorded per block. Queries happen
between rewrites, once per popped operation, and bring the cache up to
date. A region without cached state, or with a different entry block
than at the time of the traversal, is traversed from its entry block.
For recorded terminator changes, the cached successors of each block are
compared with its current successors: added edges extend the reachable
set, and a lost edge is accepted without a traversal when its target is
gone or has no predecessors left and all of the target's successors are
still successors of the changed block, which is the shape left by
folding a constant conditional branch and by merging a block into its
predecessor. Any other lost edge marks the blocks behind its target
uncertain; only a query for one of them traverses the region. In-place
folds are reported to the listener by the driver. Nested regions check
their containing blocks up to the scope. Caches are cleared at
worklist-pass boundaries. With expensive pattern API checks enabled,
every query is compared against a fresh traversal.

Canonicalizing 20000 blocks shows no measurable difference with and
without this change for a chain of constant conditional branches, a
chain of diamonds whose pass-through blocks fold away, the same chains
placed behind a loop header so that they cannot merge into the entry
block, or a chain of constant conditional branches into a shared dead
block. Inputs without CFG changes show no measurable difference.
Invalidating the cache whenever a block is inserted or erased, or
traversing the region after every lost edge, makes the loop variants
quadratic, up to 50 times slower than without this change.

Tests cover inserted and redirected blocks, blocks connected before
rewrite completion, nested regions, block moves and merges, entry-block
insertion and erasure, edges lost by two blocks in one rewrite, a lost
edge into a loop, a block reconnected after being disconnected, in-place
folds that retarget a branch, and explicit op lists. Observer
diagnostics check whether affected operations are processed within a
single greedy iteration. Skipped operations are not automatically
retried if a later rewrite makes their block reachable; this is
documented and tested in each strictness mode.

Assisted-by: Codex
Assisted-by: Claude Code

Co-Authored-By: Claude Fable 5.1 <noreply at anthropic.com>



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list