[Mlir-commits] [mlir] 3d6ae4b - [MLIR] Fix infinite loop in tryFold in Graph Regions (#189232)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Sep 11 01:24:07 PDT 2026
Author: Mehdi Amini
Date: 2026-09-11T08:24:02Z
New Revision: 3d6ae4bdf4c6d45d5e2f2c55c06f84568fde0fe0
URL: https://github.com/llvm/llvm-project/commit/3d6ae4bdf4c6d45d5e2f2c55c06f84568fde0fe0
DIFF: https://github.com/llvm/llvm-project/commit/3d6ae4bdf4c6d45d5e2f2c55c06f84568fde0fe0.diff
LOG: [MLIR] Fix infinite loop in tryFold in Graph Regions (#189232)
In a graph region (e.g. the module body), an op may use its own result
as an operand, creating a circular SSA dependency. When such an op was
passed to OpBuilder::tryFold, the do-while loop could spin forever:
1. foldCommutative moved the constant operand to the RHS (in-place fold,
foldResults still empty).
2. The next fold call returned the op's own result, signalling an
in-place fold, but foldSingleResultHook re-ran trait folds, found
nothing to swap, and returned success with empty foldResults.
3. Step 2 repeated without end.
Fix: cap the number of in-place fold iterations at 64. Legitimate chains
are very short in practice (foldCommutative swaps once, then the op folds to
a value or constant), so the cap is never reached for correct IR. For the
circular-SSA case the loop now terminates and tryFold returns failure,
letting dialect conversion fall through to a conversion pattern instead of
looping.
An alternative could be for each iteration of the loop, snapshot the
operand list and attributes/properties. If a fold returns empty results
but the operands are unchanged, we have reached a fixpoint. Stop the
loop and return failure.
However this is more expensive for the common case, while fixing an edge
case.
Fixes #159675
Assisted-by: Claude Code
Added:
Modified:
mlir/lib/IR/Builders.cpp
mlir/test/Transforms/test-legalizer.mlir
Removed:
################################################################################
diff --git a/mlir/lib/IR/Builders.cpp b/mlir/lib/IR/Builders.cpp
index 98fdfb5dfd042..47e09faf0e04f 100644
--- a/mlir/lib/IR/Builders.cpp
+++ b/mlir/lib/IR/Builders.cpp
@@ -501,11 +501,21 @@ OpBuilder::tryFold(Operation *op, SmallVectorImpl<Value> &results,
if (failed(op->fold(foldResults)))
return cleanupFailure();
+ // Bound the number of in-place fold iterations. Legitimate chains are very
+ // short (e.g. foldCommutative swaps once, then the op folds to a value).
+ // Without a bound, circular SSA uses in graph regions can cause an infinite
+ // loop (e.g. addi(x, 0) where x is the op's own result).
+ constexpr int kMaxInPlaceFolds = 64;
int count = 0;
do {
LDBG() << "Folded in place #" << count
<< " times: " << OpWithFlags(op, OpPrintingFlags().skipRegions());
- count++;
+ if (++count >= kMaxInPlaceFolds) {
+ LDBG() << "Aborting after " << kMaxInPlaceFolds
+ << " in-place fold iterations: "
+ << OpWithFlags(op, OpPrintingFlags().skipRegions());
+ return cleanupFailure();
+ }
} while (foldResults.empty() && succeeded(op->fold(foldResults)));
// An in-place fold does not require generation of any constants.
diff --git a/mlir/test/Transforms/test-legalizer.mlir b/mlir/test/Transforms/test-legalizer.mlir
index 96aeccfb7c161..1b20422298f74 100644
--- a/mlir/test/Transforms/test-legalizer.mlir
+++ b/mlir/test/Transforms/test-legalizer.mlir
@@ -496,3 +496,14 @@ func.func @test_preorder_legalization() {
// expected-remark @+1 {{'func.return' is not legalizable}}
return
}
+
+// -----
+
+// Regression test for https://github.com/llvm/llvm-project/issues/159675.
+// In a graph region, SSA values may be used before their definitions. Folding
+// the addi below first swaps its operands, then repeatedly attempts an
+// in-place self-fold. The legalizer must stop rather than looping forever.
+// expected-remark at +1 {{op 'arith.addi' is not legalizable}}
+%0 = "arith.addi"(%1, %0) <{overflowFlags = #arith.overflow<none>}> : (index, index) -> index
+// expected-remark at +1 {{op 'arith.constant' is not legalizable}}
+%1 = "arith.constant"() <{value = 0 : index}> : () -> index
More information about the Mlir-commits
mailing list