[Mlir-commits] [mlir] 2cb2fe7 - [mlir][scf] Fix crash in ForOp verifier when body block has no arguments (#183946)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun Mar 1 02:51:14 PST 2026
Author: Mehdi Amini
Date: 2026-03-01T10:51:09Z
New Revision: 2cb2fe7f2a1dfd51642651264c644e213809cb0b
URL: https://github.com/llvm/llvm-project/commit/2cb2fe7f2a1dfd51642651264c644e213809cb0b
DIFF: https://github.com/llvm/llvm-project/commit/2cb2fe7f2a1dfd51642651264c644e213809cb0b.diff
LOG: [mlir][scf] Fix crash in ForOp verifier when body block has no arguments (#183946)
A malformed `scf.for` whose body block contains no arguments caused
`getRegionIterArgs()` to crash via an out-of-bounds `drop_front(1)`
call. This happened because `verifyLoopLikeOpInterface` (a
`verifyRegionTrait`) invokes `getRegionIterArgs()` during
`verifyRegionInvariants`, which runs before `verifyRegions()` has a
chance to report a proper diagnostic.
Fix by adding an explicit check in `ForOp::verify()` (which runs in
`verifyInvariants`, before any region trait verifiers execute) that
ensures the body block has at least as many arguments as there are
induction variables. This prevents the crash and produces a clear error
message.
Fixes #159737
Added:
Modified:
mlir/lib/Dialect/SCF/IR/SCF.cpp
mlir/test/Dialect/SCF/invalid.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/SCF/IR/SCF.cpp b/mlir/lib/Dialect/SCF/IR/SCF.cpp
index c46a0577c4b96..76467154e869f 100644
--- a/mlir/lib/Dialect/SCF/IR/SCF.cpp
+++ b/mlir/lib/Dialect/SCF/IR/SCF.cpp
@@ -348,6 +348,16 @@ void ForOp::build(OpBuilder &builder, OperationState &result, Value lb,
}
LogicalResult ForOp::verify() {
+ // Check that the body block has at least the induction variable argument.
+ // This must be checked before verifyRegions() and before any region trait
+ // verifiers (e.g. LoopLikeOpInterface) that call getRegionIterArgs(), to
+ // avoid crashing with an out-of-bounds drop_front on an empty arg list.
+ if (getBody()->getNumArguments() < getNumInductionVars())
+ return emitOpError("expected body to have at least ")
+ << getNumInductionVars()
+ << " argument(s) for the induction variable, but got "
+ << getBody()->getNumArguments();
+
// Check that the number of init args and op results is the same.
if (getInitArgs().size() != getNumResults())
return emitOpError(
@@ -357,6 +367,12 @@ LogicalResult ForOp::verify() {
}
LogicalResult ForOp::verifyRegions() {
+ // Check that the body block has at least the induction variable argument.
+ if (getBody()->getNumArguments() < getNumInductionVars())
+ return emitOpError("expected body to have at least ")
+ << getNumInductionVars() << " argument(s) for the induction "
+ << "variable, but got " << getBody()->getNumArguments();
+
// Check that the body defines as single block argument for the induction
// variable.
if (getInductionVar().getType() != getLowerBound().getType())
diff --git a/mlir/test/Dialect/SCF/invalid.mlir b/mlir/test/Dialect/SCF/invalid.mlir
index 985e347fbf5ee..e7031b29adf69 100644
--- a/mlir/test/Dialect/SCF/invalid.mlir
+++ b/mlir/test/Dialect/SCF/invalid.mlir
@@ -835,3 +835,18 @@ func.func @invalid_reference(%a: index) {
}
return
}
+
+// -----
+
+// Regression test for https://github.com/llvm/llvm-project/issues/159737
+// A scf.for whose body block has no arguments used to crash in
+// getRegionIterArgs() via verifyLoopLikeOpInterface instead of producing a
+// proper diagnostic.
+func.func @for_missing_induction_var(%arg0: index, %arg1: index) {
+ %c1 = arith.constant 1 : index
+ // expected-error at +1 {{expected body to have at least 1 argument(s) for the induction variable, but got 0}}
+ "scf.for"(%arg0, %arg1, %c1) ({
+ "scf.yield"() : () -> ()
+ }) : (index, index, index) -> ()
+ return
+}
More information about the Mlir-commits
mailing list