[Mlir-commits] [mlir] [mlir][affine] Do not super-vectorize loops with a non-unit step (PR #227670)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Sep 30 04:49:55 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Samarth Narang (snarang181)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/227670.diff


2 Files Affected:

- (modified) mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp (+8-6) 
- (modified) mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir (+16) 


``````````diff
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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/227670


More information about the Mlir-commits mailing list