[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