Skip to content

Commit f6f1ab9

Browse files
authored
[mlir][scf] Fix for-loop-peeling crash (#77697)
Before applying the peeling patterns, it can happen that the `ForOp` gets a step of zero during folding. This leads to a division-by-zero down the line. This patch adds an additional check for a constant-zero step and a test. Fix #75758
1 parent 2f2217a commit f6f1ab9

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,9 @@ static LogicalResult peelForLoop(RewriterBase &b, ForOp forOp,
123123
auto ubInt = getConstantIntValue(forOp.getUpperBound());
124124
auto stepInt = getConstantIntValue(forOp.getStep());
125125

126-
// No specialization necessary if step size is 1.
127-
if (getConstantIntValue(forOp.getStep()) == static_cast<int64_t>(1))
126+
// No specialization necessary if step size is 1. Also bail out in case of an
127+
// invalid zero or negative step which might have happened during folding.
128+
if (stepInt && *stepInt <= 1)
128129
return failure();
129130

130131
// No specialization necessary if step already divides upper bound evenly.

mlir/test/Dialect/SCF/for-loop-peeling.mlir

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: mlir-opt %s -scf-for-loop-peeling -canonicalize -split-input-file | FileCheck %s
2-
// RUN: mlir-opt %s -scf-for-loop-peeling=skip-partial=false -canonicalize -split-input-file | FileCheck %s -check-prefix=CHECK-NO-SKIP
1+
// RUN: mlir-opt %s -scf-for-loop-peeling -canonicalize -split-input-file -verify-diagnostics | FileCheck %s
2+
// RUN: mlir-opt %s -scf-for-loop-peeling=skip-partial=false -canonicalize -split-input-file -verify-diagnostics | FileCheck %s -check-prefix=CHECK-NO-SKIP
33

44
// CHECK-DAG: #[[MAP0:.*]] = affine_map<()[s0, s1, s2] -> (s1 - (-s0 + s1) mod s2)>
55
// CHECK-DAG: #[[MAP1:.*]] = affine_map<(d0)[s0] -> (-d0 + s0)>
@@ -289,3 +289,18 @@ func.func @regression(%arg0: memref<i64>, %arg1: index) {
289289
}
290290
return
291291
}
292+
293+
// -----
294+
295+
// Check that this doesn't crash but trigger the verifier.
296+
func.func @zero_step(%arg0: memref<i64>) {
297+
%c0 = arith.constant 0 : index
298+
%c1 = arith.constant 1 : index
299+
%foldto0 = arith.subi %c1, %c1 : index
300+
// expected-error @+1 {{'scf.for' op constant step operand must be positive}}
301+
scf.for %arg2 = %c0 to %c1 step %foldto0 {
302+
%2 = arith.index_cast %arg2 : index to i64
303+
memref.store %2, %arg0[] : memref<i64>
304+
}
305+
return
306+
}

0 commit comments

Comments
 (0)