[Mlir-commits] [mlir] [mlir][affine] Do not super-vectorize loops with a non-unit step (PR #227670)
Samarth Narang
llvmlistbot at llvm.org
Wed Sep 30 04:49:19 PDT 2026
https://github.com/snarang181 created https://github.com/llvm/llvm-project/pull/227670
The vectorizer multiplies the step of the vectorized loop by the vectorization factor but vectorizes the body with contiguous transfers, so for a loop with a non-unit step the lanes cover iv, iv + 1, ... instead of iv, iv + step, ... and stores land on the wrong elements. The existing guard only rejected this for reduction loops; we now reject it for every loop along the vectorized dimension.
Fixes #225247
>From 97cf8aceb717015c04a1941315b06d9a4af99076 Mon Sep 17 00:00:00 2001
From: Samarth Narang <sn2910 at nyu.edu>
Date: Wed, 30 Sep 2026 11:46:21 +0000
Subject: [PATCH] [mlir][affine] Do not super-vectorize loops with a non-unit
step
The vectorizer multiplies the step of the vectorized loop by the vectorization
factor but vectorizes the body with contiguous transfers, so for a loop with a
non-unit step the lanes cover iv, iv + 1, ... instead of iv, iv + step, ...
and stores land on the wrong elements. The existing guard only rejected this
for reduction loops; reject it for every loop along the vectorized dimension.
Fixes #225247
---
.../Dialect/Affine/Transforms/SuperVectorize.cpp | 14 ++++++++------
.../Affine/SuperVectorize/vectorize_1d.mlir | 16 ++++++++++++++++
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
index 6c6e8ed979d23..b3a98ead0e74f 100644
--- a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
@@ -1360,12 +1360,14 @@ static Operation *vectorizeAffineForOp(AffineForOp forOp,
auto loopToVecDimIt = strategy.loopToVectorDim.find(forOp);
bool isLoopVecDim = loopToVecDimIt != strategy.loopToVectorDim.end();
- // TODO: Vectorization of reduction loops is not supported for non-unit steps.
- if (isLoopVecDim && forOp.getNumIterOperands() > 0 && forOp.getStep() != 1) {
- LLVM_DEBUG(
- dbgs()
- << "\n[early-vect]+++++ unsupported step size for reduction loop: "
- << forOp.getStep() << "\n");
+ // The body is vectorized with contiguous transfers while the vector loop
+ // step is the original step times the vectorization factor, which is only
+ // consistent for a unit step.
+ // TODO: Support non-unit steps with strided accesses.
+ if (isLoopVecDim && forOp.getStep() != 1) {
+ LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ unsupported step size for "
+ "vectorized loop: "
+ << forOp.getStep() << "\n");
return nullptr;
}
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir
index f99190be6365d..167ab5f354422 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir
@@ -722,3 +722,19 @@ func.func @index_const_inside_loop(%mem: memref<1x8xi32>) {
}
return
}
+
+// -----
+
+// A non-unit loop step cannot be vectorized as contiguous lanes: the scalar
+// loop touches iv, iv + step, ... while a plain transfer touches iv, iv + 1, ...
+// CHECK-LABEL: @non_unit_step_not_vectorized
+// CHECK: affine.for %{{.*}} = -4 to 13 step 3
+// CHECK: affine.store
+// CHECK-NOT: vector.transfer_write
+func.func @non_unit_step_not_vectorized(%out: memref<32xi32>) {
+ %one = arith.constant 1 : i32
+ affine.for %iv = -4 to 13 step 3 {
+ affine.store %one, %out[%iv + 8] : memref<32xi32>
+ }
+ return
+}
More information about the Mlir-commits
mailing list