[Mlir-commits] [mlir] [mlir][affine] emit `in_bounds` on `transfer_read`/`write` when statically provable in `affine-super-vectorize` (PR #201180)
Artem Gindinson
llvmlistbot at llvm.org
Tue Jun 9 00:56:42 PDT 2026
https://github.com/AGindinson updated https://github.com/llvm/llvm-project/pull/201180
>From 0ef3c34f053a370d9978d232ccf0f6ac67a0dad6 Mon Sep 17 00:00:00 2001
From: Federico Bruzzone <federico.bruzzone.i at gmail.com>
Date: Tue, 2 Jun 2026 20:36:47 +0200
Subject: [PATCH] [mlir][affine] emit in_bounds on transfer_read/write when
statically provable in affine-super-vectorize
Signed-off-by: Federico Bruzzone <federico.bruzzone.i at gmail.com>
---
.../Affine/Transforms/SuperVectorize.cpp | 32 ++++++++++-
.../Affine/SuperVectorize/vector_utils.mlir | 2 +-
.../Affine/SuperVectorize/vectorize_1d.mlir | 8 +--
.../Affine/SuperVectorize/vectorize_2d.mlir | 4 +-
.../SuperVectorize/vectorize_2d_inbounds.mlir | 53 +++++++++++++++++++
.../vectorize_affine_apply.mlir | 12 ++---
.../SuperVectorize/vectorize_reduction.mlir | 6 +--
7 files changed, 99 insertions(+), 18 deletions(-)
create mode 100644 mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d_inbounds.mlir
diff --git a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
index c90d9bd8730e6..2027b389c02d3 100644
--- a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
@@ -1220,6 +1220,28 @@ static bool isIVMappedToMultipleIndices(
return false;
}
+/// Returns an in-bounds mask for a transfer op given its permutation map and
+/// the memref being accessed. Dimension i is in-bounds when the map result is
+/// an AffineDimExpr pointing to a static memref dimension that is divisible by
+/// the vector size, or an AffineConstantExpr.
+static SmallVector<bool> computeInBoundsMask(AffineMap permutationMap,
+ VectorType vectorType,
+ MemRefType memrefType) {
+ SmallVector<bool> inBounds(vectorType.getRank(), false);
+ for (unsigned i = 0; i < vectorType.getRank(); ++i) {
+ AffineExpr expr = permutationMap.getResult(i);
+ if (auto dimExpr = dyn_cast<AffineDimExpr>(expr)) {
+ unsigned memDim = dimExpr.getPosition();
+ if (!memrefType.isDynamicDim(memDim) &&
+ memrefType.getDimSize(memDim) % vectorType.getDimSize(i) == 0)
+ inBounds[i] = true;
+ } else if (isa<AffineConstantExpr>(expr)) {
+ inBounds[i] = true;
+ }
+ }
+ return inBounds;
+}
+
/// Vectorizes an affine load with the vectorization strategy in 'state' by
/// generating a 'vector.transfer_read' op with the proper permutation map
/// inferred from the indices of the load. The new 'vector.transfer_read' is
@@ -1265,9 +1287,12 @@ static Operation *vectorizeAffineLoad(AffineLoadOp loadOp,
LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ permutationMap: ");
LLVM_DEBUG(permutationMap.print(dbgs()));
+ SmallVector<bool> inBounds =
+ computeInBoundsMask(permutationMap, vectorType,
+ cast<MemRefType>(loadOp.getMemRef().getType()));
auto transfer = vector::TransferReadOp::create(
state.builder, loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices,
- /*padding=*/std::nullopt, permutationMap);
+ /*padding=*/std::nullopt, permutationMap, ArrayRef<bool>(inBounds));
// Register replacement for future uses in the scope.
state.registerOpVectorReplacement(loadOp, transfer);
@@ -1321,9 +1346,12 @@ static Operation *vectorizeAffineStore(AffineStoreOp storeOp,
return nullptr;
}
+ auto vType = cast<VectorType>(vectorValue.getType());
+ SmallVector<bool> inBounds = computeInBoundsMask(
+ permutationMap, vType, cast<MemRefType>(storeOp.getMemRef().getType()));
auto transfer = vector::TransferWriteOp::create(
state.builder, storeOp.getLoc(), vectorValue, storeOp.getMemRef(),
- indices, permutationMap);
+ indices, permutationMap, ArrayRef<bool>(inBounds));
LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ vectorized store: " << transfer);
// Register replacement for future uses in the scope.
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir
index fcf31daa987b4..71d8314bb60d8 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir
@@ -73,7 +73,7 @@ func.func @transfer_rank_mismatch_no_crash(%arg0: memref<82x97xf32>) {
// VECNEST: vector.transfer_read
// VECNEST-NEXT: affine.for %{{.*}} = 0 to 30 {
// VECNEST: vector.transfer_read
-// VECNEST-NEXT: vector.transfer_write %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] {permutation_map = #{{.*}}}
+// VECNEST-NEXT: vector.transfer_write %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] {in_bounds = [true], permutation_map = #{{.*}}}
// VECNEST-NEXT: }
// VECNEST-NEXT: vector.transfer_write
// VECNEST: }
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir
index f9593221e1843..e47c1d186ce40 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir
@@ -22,7 +22,7 @@ func.func @vec1d_1(%A : memref<?x?xf32>, %B : memref<?x?x?xf32>) {
// CHECK-NEXT: %{{.*}} = affine.apply #[[$map_id1]](%[[C0]])
// CHECK-NEXT: %{{.*}} = affine.apply #[[$map_id1]](%[[C0]])
// CHECK-NEXT: %{{.*}} = ub.poison : f32
-// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
+// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {in_bounds = [true], permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
affine.for %i0 = 0 to %M { // vectorized due to scalar -> vector
%a0 = affine.load %A[%c0, %c0] : memref<?x?xf32>
}
@@ -171,7 +171,7 @@ func.func @vec_block_arg(%A : memref<32x512xi32>) {
// CHECK-NEXT: affine.for %[[IV1:[0-9a-zA-Z_]+]] = 0 to 32 {
// CHECK-NEXT: %[[BROADCAST:.*]] = vector.broadcast %[[IV1]] : index to vector<128xindex>
// CHECK-NEXT: %[[CAST:.*]] = arith.index_cast %[[BROADCAST]] : vector<128xindex> to vector<128xi32>
- // CHECK-NEXT: vector.transfer_write %[[CAST]], {{.*}}[%[[IV1]], %[[IV0]]] : vector<128xi32>, memref<32x512xi32>
+ // CHECK-NEXT: vector.transfer_write %[[CAST]], {{.*}}[%[[IV1]], %[[IV0]]] {in_bounds = [true]} : vector<128xi32>, memref<32x512xi32>
affine.for %i = 0 to 512 { // vectorized
affine.for %j = 0 to 32 {
%idx = arith.index_cast %j : index to i32
@@ -425,7 +425,7 @@ func.func @vec_rejected_8(%A : memref<?x?xf32>, %B : memref<?x?x?xf32>) {
// CHECK: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
// CHECK: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
// CHECK: %{{.*}} = ub.poison : f32
-// CHECK: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
+// CHECK: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {in_bounds = [true], permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
affine.for %i17 = 0 to %M { // not vectorized, the 1-D pattern that matched %{{.*}} in DFS post-order prevents vectorizing %{{.*}}
affine.for %i18 = 0 to %M { // vectorized due to scalar -> vector
%a18 = affine.load %A[%c0, %c0] : memref<?x?xf32>
@@ -459,7 +459,7 @@ func.func @vec_rejected_9(%A : memref<?x?xf32>, %B : memref<?x?x?xf32>) {
// CHECK: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
// CHECK-NEXT: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
// CHECK-NEXT: %{{.*}} = ub.poison : f32
-// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
+// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {in_bounds = [true], permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
affine.for %i17 = 0 to %M { // not vectorized, the 1-D pattern that matched %i18 in DFS post-order prevents vectorizing %{{.*}}
affine.for %i18 = 0 to %M { // vectorized due to scalar -> vector
%a18 = affine.load %A[%c0, %c0] : memref<?x?xf32>
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d.mlir
index 83916e755363b..eb5120a49e3d4 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d.mlir
@@ -123,8 +123,8 @@ func.func @vectorize_matmul(%arg0: memref<?x?xf32>, %arg1: memref<?x?xf32>, %arg
// VECT: affine.for %[[I2:.*]] = #[[$map_id1]](%[[C0]]) to #[[$map_id1]](%[[M]]) step 4 {
// VECT-NEXT: affine.for %[[I3:.*]] = #[[$map_id1]](%[[C0]]) to #[[$map_id1]](%[[N]]) step 8 {
// VECT-NEXT: affine.for %[[I4:.*]] = #[[$map_id1]](%[[C0]]) to #[[$map_id1]](%[[K]]) {
- // VECT: %[[A:.*]] = vector.transfer_read %{{.*}}[%[[I4]], %[[I3]]], %{{.*}} {permutation_map = #[[$map_proj_d0d1_zerod1]]} : memref<?x?xf32>, vector<4x8xf32>
- // VECT: %[[B:.*]] = vector.transfer_read %{{.*}}[%[[I2]], %[[I4]]], %{{.*}} {permutation_map = #[[$map_proj_d0d1_d0zero]]} : memref<?x?xf32>, vector<4x8xf32>
+ // VECT: %[[A:.*]] = vector.transfer_read %{{.*}}[%[[I4]], %[[I3]]], %{{.*}} {in_bounds = [true, false], permutation_map = #[[$map_proj_d0d1_zerod1]]} : memref<?x?xf32>, vector<4x8xf32>
+ // VECT: %[[B:.*]] = vector.transfer_read %{{.*}}[%[[I2]], %[[I4]]], %{{.*}} {in_bounds = [false, true], permutation_map = #[[$map_proj_d0d1_d0zero]]} : memref<?x?xf32>, vector<4x8xf32>
// VECT-NEXT: %[[C:.*]] = arith.mulf %[[B]], %[[A]] : vector<4x8xf32>
// VECT: %[[D:.*]] = vector.transfer_read %{{.*}}[%[[I2]], %[[I3]]], %{{.*}} : memref<?x?xf32>, vector<4x8xf32>
// VECT-NEXT: %[[E:.*]] = arith.addf %[[D]], %[[C]] : vector<4x8xf32>
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d_inbounds.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d_inbounds.mlir
new file mode 100644
index 0000000000000..a5daa8544b309
--- /dev/null
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d_inbounds.mlir
@@ -0,0 +1,53 @@
+// RUN: mlir-opt %s --affine-super-vectorize="virtual-vector-size=4" | FileCheck %s
+// RUN: mlir-opt %s \
+// RUN: --convert-linalg-to-affine-loops \
+// RUN: --affine-loop-tile="tile-sizes=16,16,16" \
+// RUN: --enable-loopinterchange \
+// RUN: --affine-super-vectorize="virtual-vector-size=4" \
+// RUN: --canonicalize \
+// RUN: | FileCheck %s --check-prefix=MATMUL
+// RUN: mlir-opt %s \
+// RUN: --affine-super-vectorize="virtual-vector-size=4" \
+// RUN: --convert-vector-to-llvm \
+// RUN: --finalize-memref-to-llvm \
+// RUN: --convert-func-to-llvm \
+// RUN: | FileCheck %s --check-prefix=LLVM
+
+// CHECK-LABEL: func.func @copy
+// Verify that transfer_read and transfer_write carry {in_bounds = [true]} when
+// the memref is static and its dimension is divisible by the vector width.
+// CHECK: vector.transfer_read {{.*}} {in_bounds = [true]} : memref<512x512xf32>, vector<4xf32>
+// CHECK-NOT: vector.transfer_read
+// CHECK: vector.transfer_write {{.*}} {in_bounds = [true]} : vector<4xf32>, memref<512x512xf32>
+// CHECK-NOT: vector.transfer_write
+
+// LLVM-LABEL: llvm.func @copy
+// Verify that in_bounds lowers to plain llvm.load/store, not masked intrinsics.
+// LLVM: llvm.load {{.*}} : !llvm.ptr -> vector<4xf32>
+// LLVM: llvm.store {{.*}} : vector<4xf32>, !llvm.ptr
+// LLVM-NOT: llvm.intr.masked.load
+// LLVM-NOT: llvm.intr.masked.store
+func.func @copy(%A: memref<512x512xf32>, %B: memref<512x512xf32>) {
+ affine.for %i = 0 to 512 {
+ affine.for %j = 0 to 512 {
+ %v = affine.load %A[%i, %j] : memref<512x512xf32>
+ affine.store %v, %B[%i, %j] : memref<512x512xf32>
+ }
+ }
+ return
+}
+
+
+// MATMUL-LABEL: func.func @matmul
+// Verify all three transfer_read ops carry in_bounds=[true] after the full
+// linalg-to-affine + tiling + vectorization pipeline.
+// Without the fix only the broadcast A-read gets it; B and C do not.
+// MATMUL-COUNT-3: vector.transfer_read {{.*}} {in_bounds = [true]
+// MATMUL-NOT: vector.transfer_read
+func.func @matmul(%A: memref<512x512xf32>,
+ %B: memref<512x512xf32>,
+ %C: memref<512x512xf32>) {
+ linalg.matmul ins(%A, %B : memref<512x512xf32>, memref<512x512xf32>)
+ outs(%C : memref<512x512xf32>)
+ return
+}
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_affine_apply.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_affine_apply.mlir
index 7d4d111c09799..08ebea37b159d 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_affine_apply.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_affine_apply.mlir
@@ -12,8 +12,8 @@ func.func @vec_affine_apply(%arg0: memref<8x12x16xf32>, %arg1: memref<8x24x48xf3
// CHECK-NEXT: %[[S0:.*]] = affine.apply #[[$MAP_ID0]](%[[ARG3]])
// CHECK-NEXT: %[[S1:.*]] = affine.apply #[[$MAP_ID1]](%[[ARG4]])
// CHECK-NEXT: %[[CST:.*]] = ub.poison : f32
-// CHECK-NEXT: %[[S2:.*]] = vector.transfer_read %[[ARG0]][%[[ARG2]], %[[S0]], %[[S1]]], %[[CST]] : memref<8x12x16xf32>, vector<8xf32>
-// CHECK-NEXT: vector.transfer_write %[[S2]], %[[ARG1]][%[[ARG2]], %[[ARG3]], %[[ARG4]]] : vector<8xf32>, memref<8x24x48xf32>
+// CHECK-NEXT: %[[S2:.*]] = vector.transfer_read %[[ARG0]][%[[ARG2]], %[[S0]], %[[S1]]], %[[CST]] {in_bounds = [true]} : memref<8x12x16xf32>, vector<8xf32>
+// CHECK-NEXT: vector.transfer_write %[[S2]], %[[ARG1]][%[[ARG2]], %[[ARG3]], %[[ARG4]]] {in_bounds = [true]} : vector<8xf32>, memref<8x24x48xf32>
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
@@ -43,8 +43,8 @@ func.func @vec_affine_apply_2(%arg0: memref<8x12x16xf32>, %arg1: memref<8x24x48x
// CHECK-NEXT: affine.for %[[ARG4:.*]] = 0 to 48 step 8 {
// CHECK-NEXT: %[[S0:.*]] = affine.apply #[[$MAP_ID2]](%[[ARG4]])
// CHECK-NEXT: %[[CST:.*]] = ub.poison : f32
-// CHECK-NEXT: %[[S1:.*]] = vector.transfer_read %[[ARG0]][%[[ARG2]], %[[ARG3]], %[[S0]]], %[[CST]] : memref<8x12x16xf32>, vector<8xf32>
-// CHECK-NEXT: vector.transfer_write %[[S1]], %[[ARG1]][%[[ARG2]], %[[ARG3]], %[[ARG4]]] : vector<8xf32>, memref<8x24x48xf32>
+// CHECK-NEXT: %[[S1:.*]] = vector.transfer_read %[[ARG0]][%[[ARG2]], %[[ARG3]], %[[S0]]], %[[CST]] {in_bounds = [true]} : memref<8x12x16xf32>, vector<8xf32>
+// CHECK-NEXT: vector.transfer_write %[[S1]], %[[ARG1]][%[[ARG2]], %[[ARG3]], %[[ARG4]]] {in_bounds = [true]} : vector<8xf32>, memref<8x24x48xf32>
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
@@ -141,8 +141,8 @@ func.func @affine_map_with_expr_2(%arg0: memref<8x12x16xf32>, %arg1: memref<8x24
// CHECK-NEXT: %[[S1:.*]] = affine.apply #[[$MAP_ID4]](%[[ARG3]], %[[ARG4]], %[[I0]])
// CHECK-NEXT: %[[S2:.*]] = affine.apply #[[$MAP_ID5]](%[[ARG3]], %[[ARG4]], %[[I0]])
// CHECK-NEXT: %[[CST:.*]] = ub.poison : f32
-// CHECK-NEXT: %[[S3:.*]] = vector.transfer_read %[[ARG0]][%[[S0]], %[[S1]], %[[S2]]], %[[CST]] {permutation_map = #[[$MAP_ID6]]} : memref<8x12x16xf32>, vector<8xf32>
-// CHECK-NEXT: vector.transfer_write %[[S3]], %[[ARG1]][%[[ARG3]], %[[ARG4]], %[[ARG5]]] : vector<8xf32>, memref<8x24x48xf32>
+// CHECK-NEXT: %[[S3:.*]] = vector.transfer_read %[[ARG0]][%[[S0]], %[[S1]], %[[S2]]], %[[CST]] {in_bounds = [true], permutation_map = #[[$MAP_ID6]]} : memref<8x12x16xf32>, vector<8xf32>
+// CHECK-NEXT: vector.transfer_write %[[S3]], %[[ARG1]][%[[ARG3]], %[[ARG4]], %[[ARG5]]] {in_bounds = [true]} : vector<8xf32>, memref<8x24x48xf32>
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir
index b062736575ad7..9dacc316f1072 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vectorize_reduction.mlir
@@ -266,7 +266,7 @@ func.func @vecdim_reduction_xori(%in: memref<256x512xi32>, %out: memref<256xi32>
// CHECK: %[[vzero:.*]] = arith.constant dense<0> : vector<128xi32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vzero]]) -> (vector<128xi32>) {
// CHECK: %[[poison:.*]] = ub.poison : i32
-// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] : memref<256x512xi32>, vector<128xi32>
+// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] {in_bounds = [true]} : memref<256x512xi32>, vector<128xi32>
// CHECK: %[[xor:.*]] = arith.xori %[[red_iter]], %[[ld]] : vector<128xi32>
// CHECK: affine.yield %[[xor]] : vector<128xi32>
// CHECK: }
@@ -299,7 +299,7 @@ func.func @vecdim_reduction_minnumf(%in: memref<256x512xf32>, %out: memref<256xf
// CHECK: %[[vzero:.*]] = arith.constant dense<0x7FC00000> : vector<128xf32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vzero]]) -> (vector<128xf32>) {
// CHECK: %[[poison:.*]] = ub.poison : f32
-// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] : memref<256x512xf32>, vector<128xf32>
+// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] {in_bounds = [true]} : memref<256x512xf32>, vector<128xf32>
// CHECK: %[[min:.*]] = arith.minnumf %[[red_iter]], %[[ld]] : vector<128xf32>
// CHECK: affine.yield %[[min]] : vector<128xf32>
// CHECK: }
@@ -333,7 +333,7 @@ func.func @vecdim_reduction_maxnumf(%in: memref<256x512xf32>, %out: memref<256xf
// CHECK: %[[vzero:.*]] = arith.constant dense<0xFFC00000> : vector<128xf32>
// CHECK: %[[vred:.*]] = affine.for %{{.*}} = 0 to 512 step 128 iter_args(%[[red_iter:.*]] = %[[vzero]]) -> (vector<128xf32>) {
// CHECK: %[[poison:.*]] = ub.poison : f32
-// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] : memref<256x512xf32>, vector<128xf32>
+// CHECK: %[[ld:.*]] = vector.transfer_read %[[input]]{{\[}}%{{.*}}, %{{.*}}], %[[poison]] {in_bounds = [true]} : memref<256x512xf32>, vector<128xf32>
// CHECK: %[[max:.*]] = arith.maxnumf %[[red_iter]], %[[ld]] : vector<128xf32>
// CHECK: affine.yield %[[max]] : vector<128xf32>
// CHECK: }
More information about the Mlir-commits
mailing list