[all-commits] [llvm/llvm-project] 067916: [mlir][Transforms] Check successor operand types b...
William Moses via All-commits
all-commits at lists.llvm.org
Sat Aug 8 21:04:28 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 067916bf4ddcfc328f343ae9aa0aa5983981ca1e
https://github.com/llvm/llvm-project/commit/067916bf4ddcfc328f343ae9aa0aa5983981ca1e
Author: William Moses <gh at wsmoses.com>
Date: 2026-08-08 (Sat, 08 Aug 2026)
Changed paths:
M mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
M mlir/include/mlir/Interfaces/ControlFlowInterfaces.td
M mlir/lib/Transforms/Utils/RegionUtils.cpp
A mlir/test/Dialect/LLVMIR/block-merge-successor-operand-types.mlir
Log Message:
-----------
[mlir][Transforms] Check successor operand types before merging identical blocks (#215036)
Merging identical blocks threads their differing values through the
predecessors' terminators as new successor operands, but the only
legality question asked of a predecessor was whether its terminator
implements `BranchOpInterface` (`ableToUpdatePredOperands`). The
transform's implicit assumption is that such a terminator can forward
operands of **any** type — false for dialects whose branch ops constrain
successor operand types. The LLVM dialect terminators declare theirs as
`Variadic<LLVM_Type>`, so merging two blocks that differ in, say, an
index-typed operand rewrote a verifying `llvm.cond_br` into one that no
longer verifies.
Reproducer (mixed-dialect IR of the kind a progressive lowering/raising
pipeline carries), via `mlir-opt
-pass-pipeline='builtin.module(func.func(canonicalize{region-simplify=aggressive}))'`:
```mlir
func.func @f(%m: memref<4xf32>, %c: i1) {
%f = arith.constant 1.0 : f32
%i0 = arith.constant 0 : index
%i1 = arith.constant 1 : index
llvm.cond_br %c, ^a, ^b
^a:
memref.store %f, %m[%i0] : memref<4xf32>
llvm.return
^b:
memref.store %f, %m[%i1] : memref<4xf32>
llvm.return
}
```
previously produced
```
error: 'llvm.cond_br' op operand #1 must be variadic of LLVM dialect-compatible type, but got 'index'
note: see current operation: "llvm.cond_br"(%arg1, %1, %2)[^bb1, ^bb1] ...
```
i.e. the transform manufactured IR that cannot verify. (Any greedy
driver running at `GreedySimplifyRegionLevel::Aggressive` — the
`applyPatternsGreedily` default — hits this; downstream we currently
work around it by dropping to `Normal`.)
This adds `mayForwardTypeToSuccessor(unsigned index, Type type)` to
`BranchOpInterface`, default permissive, and makes block merging refuse
a cluster when any predecessor terminator refuses any of the would-be
block argument types. The LLVM dialect terminators (`br`, `cond_br`,
`switch`, `invoke`, `indirectbr`) override it with `isCompatibleType`.
The new test pins both directions: the index-typed merge is refused, an
i32-typed merge through `llvm.cond_br` still happens.
Assisted-by: Claude
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