[Mlir-commits] [mlir] [mlir][vector] reject negative strides (PR #204611)
Federico Bruzzone
llvmlistbot at llvm.org
Thu Jun 18 07:41:20 PDT 2026
https://github.com/FedericoBruzzone created https://github.com/llvm/llvm-project/pull/204611
VectorLoadStoreConversion<vector::MaskedLoadOp>, // ← no verifier!
VectorLoadStoreConversion<vector::MaskedStoreOp>, // ← no verifier!
VectorGatherOpConversion,
VectorScatterOpConversion,
>From 88ac273ce2865cd4890a5d59635f6b75013f477f Mon Sep 17 00:00:00 2001
From: Federico Bruzzone <federico.bruzzone.i at gmail.com>
Date: Thu, 18 Jun 2026 16:18:08 +0200
Subject: [PATCH] [mlir][vector] reject negative strides
Signed-off-by: Federico Bruzzone <federico.bruzzone.i at gmail.com>
---
.../mlir/Dialect/Vector/IR/VectorOps.td | 6 +++++
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 14 +++++++++++
.../Vector/load-store-negative-strides.mlir | 25 +++++++++++++++++++
3 files changed, 45 insertions(+)
create mode 100644 mlir/test/Dialect/Vector/load-store-negative-strides.mlir
diff --git a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
index 7578ce78a0f00..24442a6336090 100644
--- a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
+++ b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
@@ -1717,6 +1717,9 @@ def Vector_LoadOp : Vector_Op<"load", [
%result = vector.load %memref[%i, %j] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32>
```
+ The memref must have non-negative strides. Negative strides are not supported
+ and will trigger a verification error.
+
Representation-wise, the 'vector.load' operation permits out-of-bounds
reads. Support and implementation of out-of-bounds vector loads is
target-specific. No assumptions should be made on the value of elements
@@ -1835,6 +1838,9 @@ def Vector_StoreOp : Vector_Op<"store", [
vector.store %valueToStore, %memref[%i, %j] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32>
```
+ The memref must have non-negative strides. Negative strides are not supported
+ and will trigger a verification error.
+
Representation-wise, the 'vector.store' operation permits out-of-bounds
writes. Support and implementation of out-of-bounds vector stores are
target-specific. No assumptions should be made on the memory written out of
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index 67c31730f4b65..651f75dc2498d 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -6194,6 +6194,13 @@ LogicalResult vector::LoadOp::verify() {
if (failed(verifyLoadStoreMemRefLayout(*this, resVecTy, memRefTy)))
return failure();
+ // Negative strides are not supported on vector.load.
+ auto [strides, offset] = memRefTy.getStridesAndOffset();
+ for (int64_t stride : strides) {
+ if (!ShapedType::isDynamic(stride) && stride < 0)
+ return emitOpError("memref strides must be non-negative");
+ }
+
if (memRefTy.getRank() < resVecTy.getRank())
return emitOpError(
"destination memref has lower rank than the result vector");
@@ -6240,6 +6247,13 @@ LogicalResult vector::StoreOp::verify() {
if (failed(verifyLoadStoreMemRefLayout(*this, valueVecTy, memRefTy)))
return failure();
+ // Negative strides are not supported on vector.store.
+ auto [strides, offset] = memRefTy.getStridesAndOffset();
+ for (int64_t stride : strides) {
+ if (!ShapedType::isDynamic(stride) && stride < 0)
+ return emitOpError("memref strides must be non-negative");
+ }
+
if (memRefTy.getRank() < valueVecTy.getRank())
return emitOpError("source memref has lower rank than the vector to store");
diff --git a/mlir/test/Dialect/Vector/load-store-negative-strides.mlir b/mlir/test/Dialect/Vector/load-store-negative-strides.mlir
new file mode 100644
index 0000000000000..777053fd632d2
--- /dev/null
+++ b/mlir/test/Dialect/Vector/load-store-negative-strides.mlir
@@ -0,0 +1,25 @@
+// RUN: mlir-opt %s -split-input-file -verify-diagnostics
+
+// -----
+
+func.func @load_negative_stride(%base: memref<100x100xf32>) -> vector<8xf32> {
+ // expected-error @+5 {{'vector.load' op memref strides must be non-negative}}
+ %flip = memref.reinterpret_cast %base to
+ offset: [0], sizes: [100, 100], strides: [-100, 1]
+ : memref<100x100xf32> to memref<100x100xf32, strided<[-100, 1]>>
+ %c0 = arith.constant 0 : index
+ %v = vector.load %flip[%c0, %c0] : memref<100x100xf32, strided<[-100, 1]>>, vector<8xf32>
+ return %v : vector<8xf32>
+}
+
+// -----
+
+func.func @store_negative_stride(%base: memref<100x100xf32>, %val: vector<4xf32>) {
+ // expected-error @+5 {{'vector.store' op memref strides must be non-negative}}
+ %flip = memref.reinterpret_cast %base to
+ offset: [0], sizes: [100, 100], strides: [-100, 1]
+ : memref<100x100xf32> to memref<100x100xf32, strided<[-100, 1]>>
+ %c0 = arith.constant 0 : index
+ vector.store %val, %flip[%c0, %c0] : memref<100x100xf32, strided<[-100, 1]>>, vector<4xf32>
+ return
+}
More information about the Mlir-commits
mailing list