Skip to content

Commit 56d6b56

Browse files
authored
[mlir][vector] Relax the requirements on broadcast dims (#99341)
NOTE: This is a follow-up for #97049 in which the `in_bounds` attribute was made mandatory. This PR updates the semantics of the `in_bounds` attribute so that broadcast dimensions are no longer required to be "in bounds". Specifically, these xfer_read/xfer_write Ops become valid after this change: ```mlir %read = vector.transfer_read %A[%base1, %base2], %pad {in_bounds = [false], permutation_map = affine_map<(d0, d1) -> (0)>} {permutation_map = affine_map<(d0, d1) -> (0)>} : memref<?x?xf32>, vector<9xf32> vector.transfer_write %vec, %A[%base1, %base2], {in_bounds = [false], permutation_map = affine_map<(d0, d1) -> (0)>} {permutation_map = affine_map<(d0, d1) -> (0)>} : vector<9xf32>, memref<?x?xf32> ``` Note that the value `false` merely means "may run out-of-bounds", i.e., the corresponding access can still be "in bounds". In fact, the folder for xfer Ops is also updated (*) and will update the attribute value corresponding to broadcast dims to `true` if all non-broadcast dims are marked as "in bounds". Note that this PR doesn't change any of the lowerings. The changes in "SuperVectorize.cpp", "Vectorization.cpp" and "AffineMap.cpp" are simple reverts of recent changes in #97049. Those were only meant to facilitate making `in_bounds` mandatory and to work around the extra requirements for broadcast dims (those requirements ere removed in this PR). All changes in tests are also reverts of changes from #97049. For context, here's a PR in which "broadcast" dims where forced to always be "in-bounds": * https://reviews.llvm.org/D102566 (*) See `foldTransferInBoundsAttribute`.
1 parent 3b0e120 commit 56d6b56

File tree

18 files changed

+81
-81
lines changed

18 files changed

+81
-81
lines changed

mlir/include/mlir/Dialect/Vector/IR/VectorOps.td

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,12 +1290,12 @@ def Vector_TransferReadOp :
12901290
specifies if the transfer is guaranteed to be within the source bounds. If
12911291
set to "false", accesses (including the starting point) may run
12921292
out-of-bounds along the respective vector dimension as the index increases.
1293-
Non-vector and broadcast dimensions *must* always be in-bounds. The
1294-
`in_bounds` array length has to be equal to the vector rank. This attribute
1295-
has a default value: `false` (i.e. "out-of-bounds"). When skipped in the
1296-
textual IR, the default value is assumed. Similarly, the OP printer will
1297-
omit this attribute when all dimensions are out-of-bounds (i.e. the default
1298-
value is used).
1293+
Non-vector dimensions *must* always be in-bounds. The `in_bounds` array
1294+
length has to be equal to the vector rank. This attribute has a default
1295+
value: `false` (i.e. "out-of-bounds"). When skipped in the textual IR, the
1296+
default value is assumed. Similarly, the OP printer will omit this
1297+
attribute when all dimensions are out-of-bounds (i.e. the default value is
1298+
used).
12991299

13001300
A `vector.transfer_read` can be lowered to a simple load if all dimensions
13011301
are specified to be within bounds and no `mask` was specified.
@@ -1535,12 +1535,12 @@ def Vector_TransferWriteOp :
15351535
specifies if the transfer is guaranteed to be within the source bounds. If
15361536
set to "false", accesses (including the starting point) may run
15371537
out-of-bounds along the respective vector dimension as the index increases.
1538-
Non-vector and broadcast dimensions *must* always be in-bounds. The
1539-
`in_bounds` array length has to be equal to the vector rank. This attribute
1540-
has a default value: `false` (i.e. "out-of-bounds"). When skipped in the
1541-
textual IR, the default value is assumed. Similarly, the OP printer will
1542-
omit this attribute when all dimensions are out-of-bounds (i.e. the default
1543-
value is used).
1538+
Non-vector dimensions *must* always be in-bounds. The `in_bounds` array
1539+
length has to be equal to the vector rank. This attribute has a default
1540+
value: `false` (i.e. "out-of-bounds"). When skipped in the textual IR, the
1541+
default value is assumed. Similarly, the OP printer will omit this
1542+
attribute when all dimensions are out-of-bounds (i.e. the default value is
1543+
used).
15441544

15451545
A `vector.transfer_write` can be lowered to a simple store if all
15461546
dimensions are specified to be within bounds and no `mask` was specified.

mlir/include/mlir/Interfaces/VectorInterfaces.td

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,9 @@ def VectorTransferOpInterface : OpInterface<"VectorTransferOpInterface"> {
234234
return constExpr && constExpr.getValue() == 0;
235235
}
236236

237-
/// Return "true" if the vector transfer dimension `dim` is in-bounds. Also
238-
/// return "true" if the dimension is a broadcast dimension. Return "false"
239-
/// otherwise.
237+
/// Return "true" if the vector transfer dimension `dim` is in-bounds.
238+
/// Return "false" otherwise.
240239
bool isDimInBounds(unsigned dim) {
241-
if ($_op.isBroadcastDim(dim))
242-
return true;
243240
auto inBounds = $_op.getInBounds();
244241
return ::llvm::cast<::mlir::BoolAttr>(inBounds[dim]).getValue();
245242
}

mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,19 +1223,8 @@ static Operation *vectorizeAffineLoad(AffineLoadOp loadOp,
12231223
LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ permutationMap: ");
12241224
LLVM_DEBUG(permutationMap.print(dbgs()));
12251225

1226-
// Make sure that the in_bounds attribute corresponding to a broadcast dim
1227-
// is set to `true` - that's required by the xfer Op.
1228-
// FIXME: We're not veryfying whether the corresponding access is in bounds.
1229-
// TODO: Use masking instead.
1230-
SmallVector<unsigned> broadcastedDims = permutationMap.getBroadcastDims();
1231-
SmallVector<bool> inBounds(vectorType.getRank(), false);
1232-
1233-
for (auto idx : broadcastedDims)
1234-
inBounds[idx] = true;
1235-
12361226
auto transfer = state.builder.create<vector::TransferReadOp>(
1237-
loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices, permutationMap,
1238-
inBounds);
1227+
loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices, permutationMap);
12391228

12401229
// Register replacement for future uses in the scope.
12411230
state.registerOpVectorReplacement(loadOp, transfer);

mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,17 +1380,8 @@ vectorizeAsLinalgGeneric(RewriterBase &rewriter, VectorizationState &state,
13801380

13811381
SmallVector<Value> indices(linalgOp.getShape(opOperand).size(), zero);
13821382

1383-
// Make sure that the in_bounds attribute corresponding to a broadcast dim
1384-
// is `true`
1385-
SmallVector<unsigned> broadcastedDims = readMap.getBroadcastDims();
1386-
SmallVector<bool> inBounds(readType.getRank(), false);
1387-
1388-
for (auto idx : broadcastedDims)
1389-
inBounds[idx] = true;
1390-
13911383
Operation *read = rewriter.create<vector::TransferReadOp>(
1392-
loc, readType, opOperand->get(), indices, readMap,
1393-
ArrayRef<bool>(inBounds));
1384+
loc, readType, opOperand->get(), indices, readMap);
13941385
read = state.maskOperation(rewriter, read, linalgOp, indexingMap);
13951386
Value readValue = read->getResult(0);
13961387

mlir/lib/Dialect/Vector/IR/VectorOps.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3947,10 +3947,6 @@ verifyTransferOp(VectorTransferOpInterface op, ShapedType shapedType,
39473947
"as permutation_map results: ")
39483948
<< AffineMapAttr::get(permutationMap)
39493949
<< " vs inBounds of size: " << inBounds.size();
3950-
for (unsigned int i = 0, e = permutationMap.getNumResults(); i < e; ++i)
3951-
if (isa<AffineConstantExpr>(permutationMap.getResult(i)) &&
3952-
!llvm::cast<BoolAttr>(inBounds.getValue()[i]).getValue())
3953-
return op->emitOpError("requires broadcast dimensions to be in-bounds");
39543950

39553951
return success();
39563952
}
@@ -4138,22 +4134,43 @@ static LogicalResult foldTransferInBoundsAttribute(TransferOp op) {
41384134
bool changed = false;
41394135
SmallVector<bool, 4> newInBounds;
41404136
newInBounds.reserve(op.getTransferRank());
4137+
// Idxs of non-bcast dims - used when analysing bcast dims.
4138+
SmallVector<unsigned> nonBcastDims;
4139+
4140+
// 1. Process non-broadcast dims
41414141
for (unsigned i = 0; i < op.getTransferRank(); ++i) {
4142-
// Already marked as in-bounds, nothing to see here.
4142+
// 1.1. Already marked as in-bounds, nothing to see here.
41434143
if (op.isDimInBounds(i)) {
41444144
newInBounds.push_back(true);
41454145
continue;
41464146
}
4147-
// Currently out-of-bounds, check whether we can statically determine it is
4148-
// inBounds.
4147+
// 1.2. Currently out-of-bounds, check whether we can statically determine
4148+
// it is inBounds.
4149+
bool inBounds = false;
41494150
auto dimExpr = dyn_cast<AffineDimExpr>(permutationMap.getResult(i));
4150-
assert(dimExpr && "Broadcast dims must be in-bounds");
4151-
auto inBounds =
4152-
isInBounds(op, /*resultIdx=*/i, /*indicesIdx=*/dimExpr.getPosition());
4151+
if (dimExpr) {
4152+
inBounds = isInBounds(op, /*resultIdx=*/i,
4153+
/*indicesIdx=*/dimExpr.getPosition());
4154+
nonBcastDims.push_back(i);
4155+
}
4156+
41534157
newInBounds.push_back(inBounds);
41544158
// We commit the pattern if it is "more inbounds".
41554159
changed |= inBounds;
41564160
}
4161+
4162+
// 2. Handle broadcast dims
4163+
// If all non-broadcast dims are "in bounds", then all bcast dims should be
4164+
// "in bounds" as well.
4165+
bool allNonBcastDimsInBounds = llvm::all_of(
4166+
nonBcastDims, [&newInBounds](unsigned idx) { return newInBounds[idx]; });
4167+
if (allNonBcastDimsInBounds) {
4168+
for (size_t idx : permutationMap.getBroadcastDims()) {
4169+
changed |= !newInBounds[idx];
4170+
newInBounds[idx] = true;
4171+
}
4172+
}
4173+
41574174
if (!changed)
41584175
return failure();
41594176
// OpBuilder is only used as a helper to build an I64ArrayAttr.

mlir/test/Conversion/VectorToSCF/vector-to-scf.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func.func @materialize_read(%M: index, %N: index, %O: index, %P: index) {
133133
affine.for %i1 = 0 to %N {
134134
affine.for %i2 = 0 to %O {
135135
affine.for %i3 = 0 to %P step 5 {
136-
%f = vector.transfer_read %A[%i0, %i1, %i2, %i3], %f0 {in_bounds = [false, true, false], permutation_map = affine_map<(d0, d1, d2, d3) -> (d3, 0, d0)>} : memref<?x?x?x?xf32>, vector<5x4x3xf32>
136+
%f = vector.transfer_read %A[%i0, %i1, %i2, %i3], %f0 {permutation_map = affine_map<(d0, d1, d2, d3) -> (d3, 0, d0)>} : memref<?x?x?x?xf32>, vector<5x4x3xf32>
137137
// Add a dummy use to prevent dead code elimination from removing
138138
// transfer read ops.
139139
"dummy_use"(%f) : (vector<5x4x3xf32>) -> ()
@@ -507,7 +507,7 @@ func.func @transfer_read_with_tensor(%arg: tensor<f32>) -> vector<1xf32> {
507507
// CHECK-NEXT: %[[RESULT:.*]] = vector.broadcast %[[EXTRACTED]] : f32 to vector<1xf32>
508508
// CHECK-NEXT: return %[[RESULT]] : vector<1xf32>
509509
%f0 = arith.constant 0.0 : f32
510-
%0 = vector.transfer_read %arg[], %f0 {in_bounds = [true], permutation_map = affine_map<()->(0)>} :
510+
%0 = vector.transfer_read %arg[], %f0 {permutation_map = affine_map<()->(0)>} :
511511
tensor<f32>, vector<1xf32>
512512
return %0: vector<1xf32>
513513
}
@@ -746,7 +746,7 @@ func.func @cannot_lower_transfer_read_with_leading_scalable(%arg0: memref<?x4xf3
746746
func.func @does_not_crash_on_unpack_one_dim(%subview: memref<1x1x1x1xi32>, %mask: vector<1x1xi1>) -> vector<1x1x1x1xi32> {
747747
%c0 = arith.constant 0 : index
748748
%c0_i32 = arith.constant 0 : i32
749-
%3 = vector.transfer_read %subview[%c0, %c0, %c0, %c0], %c0_i32, %mask {in_bounds = [false, true, true, false], permutation_map = #map1}
749+
%3 = vector.transfer_read %subview[%c0, %c0, %c0, %c0], %c0_i32, %mask {permutation_map = #map1}
750750
: memref<1x1x1x1xi32>, vector<1x1x1x1xi32>
751751
return %3 : vector<1x1x1x1xi32>
752752
}

mlir/test/Dialect/Affine/SuperVectorize/vectorize_1d.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func.func @vec1d_1(%A : memref<?x?xf32>, %B : memref<?x?x?xf32>) {
2222
// CHECK-NEXT: %{{.*}} = affine.apply #[[$map_id1]](%[[C0]])
2323
// CHECK-NEXT: %{{.*}} = affine.apply #[[$map_id1]](%[[C0]])
2424
// CHECK-NEXT: %{{.*}} = arith.constant 0.0{{.*}}: f32
25-
// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {in_bounds = [true], permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
25+
// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
2626
affine.for %i0 = 0 to %M { // vectorized due to scalar -> vector
2727
%a0 = affine.load %A[%c0, %c0] : memref<?x?xf32>
2828
}
@@ -425,7 +425,7 @@ func.func @vec_rejected_8(%A : memref<?x?xf32>, %B : memref<?x?x?xf32>) {
425425
// CHECK: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
426426
// CHECK: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
427427
// CHECK: %{{.*}} = arith.constant 0.0{{.*}}: f32
428-
// CHECK: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {in_bounds = [true], permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
428+
// CHECK: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
429429
affine.for %i17 = 0 to %M { // not vectorized, the 1-D pattern that matched %{{.*}} in DFS post-order prevents vectorizing %{{.*}}
430430
affine.for %i18 = 0 to %M { // vectorized due to scalar -> vector
431431
%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>) {
459459
// CHECK: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
460460
// CHECK-NEXT: %{{.*}} = affine.apply #[[$map_id1]](%{{.*}})
461461
// CHECK-NEXT: %{{.*}} = arith.constant 0.0{{.*}}: f32
462-
// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {in_bounds = [true], permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
462+
// CHECK-NEXT: {{.*}} = vector.transfer_read %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}} {permutation_map = #[[$map_proj_d0d1_0]]} : memref<?x?xf32>, vector<128xf32>
463463
affine.for %i17 = 0 to %M { // not vectorized, the 1-D pattern that matched %i18 in DFS post-order prevents vectorizing %{{.*}}
464464
affine.for %i18 = 0 to %M { // vectorized due to scalar -> vector
465465
%a18 = affine.load %A[%c0, %c0] : memref<?x?xf32>

mlir/test/Dialect/Affine/SuperVectorize/vectorize_2d.mlir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ func.func @vectorize_matmul(%arg0: memref<?x?xf32>, %arg1: memref<?x?xf32>, %arg
123123
// VECT: affine.for %[[I2:.*]] = #[[$map_id1]](%[[C0]]) to #[[$map_id1]](%[[M]]) step 4 {
124124
// VECT-NEXT: affine.for %[[I3:.*]] = #[[$map_id1]](%[[C0]]) to #[[$map_id1]](%[[N]]) step 8 {
125125
// VECT-NEXT: affine.for %[[I4:.*]] = #[[$map_id1]](%[[C0]]) to #[[$map_id1]](%[[K]]) {
126-
// VECT: %[[A:.*]] = vector.transfer_read %{{.*}}[%[[I4]], %[[I3]]], %{{.*}} {in_bounds = [true, false], permutation_map = #[[$map_proj_d0d1_zerod1]]} : memref<?x?xf32>, vector<4x8xf32>
127-
// VECT: %[[B:.*]] = vector.transfer_read %{{.*}}[%[[I2]], %[[I4]]], %{{.*}} {in_bounds = [false, true], permutation_map = #[[$map_proj_d0d1_d0zero]]} : memref<?x?xf32>, vector<4x8xf32>
126+
// VECT: %[[A:.*]] = vector.transfer_read %{{.*}}[%[[I4]], %[[I3]]], %{{.*}} {permutation_map = #[[$map_proj_d0d1_zerod1]]} : memref<?x?xf32>, vector<4x8xf32>
127+
// VECT: %[[B:.*]] = vector.transfer_read %{{.*}}[%[[I2]], %[[I4]]], %{{.*}} {permutation_map = #[[$map_proj_d0d1_d0zero]]} : memref<?x?xf32>, vector<4x8xf32>
128128
// VECT-NEXT: %[[C:.*]] = arith.mulf %[[B]], %[[A]] : vector<4x8xf32>
129129
// VECT: %[[D:.*]] = vector.transfer_read %{{.*}}[%[[I2]], %[[I3]]], %{{.*}} : memref<?x?xf32>, vector<4x8xf32>
130130
// VECT-NEXT: %[[E:.*]] = arith.addf %[[D]], %[[C]] : vector<4x8xf32>

mlir/test/Dialect/Affine/SuperVectorize/vectorize_affine_apply.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func.func @affine_map_with_expr_2(%arg0: memref<8x12x16xf32>, %arg1: memref<8x24
141141
// CHECK-NEXT: %[[S1:.*]] = affine.apply #[[$MAP_ID4]](%[[ARG3]], %[[ARG4]], %[[I0]])
142142
// CHECK-NEXT: %[[S2:.*]] = affine.apply #[[$MAP_ID5]](%[[ARG3]], %[[ARG4]], %[[I0]])
143143
// CHECK-NEXT: %[[CST:.*]] = arith.constant 0.000000e+00 : f32
144-
// CHECK-NEXT: %[[S3:.*]] = vector.transfer_read %[[ARG0]][%[[S0]], %[[S1]], %[[S2]]], %[[CST]] {in_bounds = [true], permutation_map = #[[$MAP_ID6]]} : memref<8x12x16xf32>, vector<8xf32>
144+
// CHECK-NEXT: %[[S3:.*]] = vector.transfer_read %[[ARG0]][%[[S0]], %[[S1]], %[[S2]]], %[[CST]] {permutation_map = #[[$MAP_ID6]]} : memref<8x12x16xf32>, vector<8xf32>
145145
// CHECK-NEXT: vector.transfer_write %[[S3]], %[[ARG1]][%[[ARG3]], %[[ARG4]], %[[ARG5]]] : vector<8xf32>, memref<8x24x48xf32>
146146
// CHECK-NEXT: }
147147
// CHECK-NEXT: }

mlir/test/Dialect/Linalg/hoisting.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func.func @hoist_vector_transfer_pairs_in_affine_loops(%memref0: memref<64x64xi3
200200
affine.for %arg3 = 0 to 64 {
201201
affine.for %arg4 = 0 to 64 step 16 {
202202
affine.for %arg5 = 0 to 64 {
203-
%0 = vector.transfer_read %memref0[%arg3, %arg5], %c0_i32 {in_bounds = [true], permutation_map = affine_map<(d0, d1) -> (0)>} : memref<64x64xi32>, vector<16xi32>
203+
%0 = vector.transfer_read %memref0[%arg3, %arg5], %c0_i32 {permutation_map = affine_map<(d0, d1) -> (0)>} : memref<64x64xi32>, vector<16xi32>
204204
%1 = vector.transfer_read %memref1[%arg5, %arg4], %c0_i32 : memref<64x64xi32>, vector<16xi32>
205205
%2 = vector.transfer_read %memref2[%arg3, %arg4], %c0_i32 : memref<64x64xi32>, vector<16xi32>
206206
%3 = arith.muli %0, %1 : vector<16xi32>

mlir/test/Dialect/Linalg/vectorization.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func.func @vectorize_dynamic_1d_broadcast(%arg0: tensor<?xf32>,
130130
// CHECK-LABEL: @vectorize_dynamic_1d_broadcast
131131
// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
132132
// CHECK: %[[VAL_4:.*]] = tensor.dim %{{.*}}, %[[VAL_3]] : tensor<?xf32>
133-
// CHECK: %[[VAL_7:.*]] = vector.transfer_read %{{.*}} {in_bounds = {{.*}}, permutation_map = #{{.*}}} : tensor<?xf32>, vector<4xf32>
133+
// CHECK: %[[VAL_7:.*]] = vector.transfer_read %{{.*}} {permutation_map = #{{.*}}} : tensor<?xf32>, vector<4xf32>
134134
// CHECK: %[[VAL_9:.*]] = vector.create_mask %[[VAL_4]] : vector<4xi1>
135135
// CHECK: %[[VAL_10:.*]] = vector.mask %[[VAL_9]] { vector.transfer_read %{{.*}} {in_bounds = [true]} : tensor<?xf32>, vector<4xf32> } : vector<4xi1> -> vector<4xf32>
136136
// CHECK: %[[VAL_12:.*]] = vector.mask %[[VAL_9]] { vector.transfer_read %{{.*}} {in_bounds = [true]} : tensor<?xf32>, vector<4xf32> } : vector<4xi1> -> vector<4xf32>

mlir/test/Dialect/Vector/invalid.mlir

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ func.func @test_vector.transfer_read(%arg0: memref<?x?xf32>) {
454454

455455
// -----
456456

457+
func.func @test_vector.transfer_read(%arg0: memref<?x?xf32>) {
458+
%c3 = arith.constant 3 : index
459+
%cst = arith.constant 3.0 : f32
460+
// expected-error@+1 {{requires a projected permutation_map (at most one dim or the zero constant can appear in each result)}}
461+
%0 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(1)>} : memref<?x?xf32>, vector<128xf32>
462+
}
463+
464+
// -----
465+
457466
func.func @test_vector.transfer_read(%arg0: memref<?x?x?xf32>) {
458467
%c3 = arith.constant 3 : index
459468
%cst = arith.constant 3.0 : f32
@@ -505,16 +514,6 @@ func.func @test_vector.transfer_read(%arg0: memref<?x?xvector<2x3xf32>>) {
505514

506515
// -----
507516

508-
func.func @test_vector.transfer_read(%arg0: memref<?x?xvector<2x3xf32>>) {
509-
%c3 = arith.constant 3 : index
510-
%f0 = arith.constant 0.0 : f32
511-
%vf0 = vector.splat %f0 : vector<2x3xf32>
512-
// expected-error@+1 {{requires broadcast dimensions to be in-bounds}}
513-
%0 = vector.transfer_read %arg0[%c3, %c3], %vf0 {in_bounds = [false, true], permutation_map = affine_map<(d0, d1)->(0, d1)>} : memref<?x?xvector<2x3xf32>>, vector<1x1x2x3xf32>
514-
}
515-
516-
// -----
517-
518517
func.func @test_vector.transfer_read(%arg0: memref<?x?xvector<2x3xf32>>) {
519518
%c3 = arith.constant 3 : index
520519
%f0 = arith.constant 0.0 : f32
@@ -618,6 +617,15 @@ func.func @test_vector.transfer_write(%arg0: memref<?x?xf32>) {
618617

619618
// -----
620619

620+
func.func @test_vector.transfer_write(%arg0: memref<?x?xf32>) {
621+
%c3 = arith.constant 3 : index
622+
%cst = arith.constant dense<3.0> : vector<128 x f32>
623+
// expected-error@+1 {{requires a projected permutation_map (at most one dim or the zero constant can appear in each result)}}
624+
vector.transfer_write %cst, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(1)>} : vector<128xf32>, memref<?x?xf32>
625+
}
626+
627+
// -----
628+
621629
func.func @test_vector.transfer_write(%arg0: memref<?x?x?xf32>) {
622630
%c3 = arith.constant 3 : index
623631
%cst = arith.constant dense<3.0> : vector<3 x 7 x f32>

mlir/test/Dialect/Vector/ops.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func.func @vector_transfer_ops(%arg0: memref<?x?xf32>,
7070
// CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}}, %{{.*}} : memref<?x?xf32>, vector<5xf32>
7171
%8 = vector.transfer_read %arg0[%c3, %c3], %f0, %m : memref<?x?xf32>, vector<5xf32>
7272
// CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]], %[[C3]]], %{{.*}}, %{{.*}} : memref<?x?x?xf32>, vector<5x4x8xf32>
73-
%9 = vector.transfer_read %arg4[%c3, %c3, %c3], %f0, %m2 {in_bounds = [false, false, true], permutation_map = affine_map<(d0, d1, d2)->(d1, d0, 0)>} : memref<?x?x?xf32>, vector<5x4x8xf32>
73+
%9 = vector.transfer_read %arg4[%c3, %c3, %c3], %f0, %m2 {permutation_map = affine_map<(d0, d1, d2)->(d1, d0, 0)>} : memref<?x?x?xf32>, vector<5x4x8xf32>
7474

7575
// CHECK: vector.transfer_write
7676
vector.transfer_write %0, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0)>} : vector<128xf32>, memref<?x?xf32>

mlir/test/Dialect/Vector/vector-transfer-permutation-lowering.mlir

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,13 +327,11 @@ func.func @masked_permutation_xfer_read_fixed_width(
327327
%c0 = arith.constant 0 : index
328328
%3 = vector.mask %mask {
329329
vector.transfer_read %dest[%c0, %c0], %cst {
330-
in_bounds = [false, true, false],
331330
permutation_map = affine_map<(d0, d1) -> (d1, 0, d0)>
332331
} : tensor<?x1xf32>, vector<1x4x4xf32>
333332
} : vector<4x1xi1> -> vector<1x4x4xf32>
334333

335334
"test.some_use"(%3) : (vector<1x4x4xf32>) -> ()
336-
337335
return
338336
}
339337

0 commit comments

Comments
 (0)