Skip to content

Commit 2ee5586

Browse files
authored
[mlir][vector] Make the in_bounds attribute mandatory (#97049)
At the moment, the in_bounds attribute has two confusing/contradicting properties: 1. It is both optional _and_ has an effective default-value. 2. The default value is "out-of-bounds" for non-broadcast dims, and "in-bounds" for broadcast dims. (see the `isDimInBounds` vector interface method for an example of this "default" behaviour [1]). This PR aims to clarify the logic surrounding the `in_bounds` attribute by: * making the attribute mandatory (i.e. it is always present), * always setting the default value to "out of bounds" (that's consistent with the current behaviour for the most common cases). #### Broadcast dimensions in tests As per [2], the broadcast dimensions requires the corresponding `in_bounds` attribute to be `true`: ``` vector.transfer_read op requires broadcast dimensions to be in-bounds ``` The changes in this PR mean that we can no longer rely on the default value in cases like the following (dim 0 is a broadcast dim): ```mlir %read = vector.transfer_read %A[%base1, %base2], %f, %mask {permutation_map = affine_map<(d0, d1) -> (0, d1)>} : memref<?x?xf32>, vector<4x9xf32> ``` Instead, the broadcast dimension has to explicitly be marked as "in bounds: ```mlir %read = vector.transfer_read %A[%base1, %base2], %f, %mask {in_bounds = [true, false], permutation_map = affine_map<(d0, d1) -> (0, d1)>} : memref<?x?xf32>, vector<4x9xf32> ``` All tests with broadcast dims are updated accordingly. #### Changes in "SuperVectorize.cpp" and "Vectorization.cpp" The following patterns in "Vectorization.cpp" are updated to explicitly set the `in_bounds` attribute to `false`: * `LinalgCopyVTRForwardingPattern` and `LinalgCopyVTWForwardingPattern` Also, `vectorizeAffineLoad` (from "SuperVectorize.cpp") and `vectorizeAsLinalgGeneric` (from "Vectorization.cpp") are updated to make sure that xfer Ops created by these hooks set the dimension corresponding to broadcast dims as "in bounds". Otherwise, the Op verifier would complain Note that there is no mechanism to verify whether the corresponding memory access are indeed in bounds. Still, this is consistent with the current behaviour where the broadcast dim would be implicitly assumed to be "in bounds". [1] https://github.com/llvm/llvm-project/blob/4145ad2bac4bb99d5034d60c74bb2789f6c6e802/mlir/include/mlir/Interfaces/VectorInterfaces.td#L243-L246 [2] https://mlir.llvm.org/docs/Dialects/Vector/#vectortransfer_read-vectortransferreadop
1 parent f1d3fe7 commit 2ee5586

25 files changed

+153
-90
lines changed

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

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,7 @@ def Vector_TransferReadOp :
13631363
AffineMapAttr:$permutation_map,
13641364
AnyType:$padding,
13651365
Optional<VectorOf<[I1]>>:$mask,
1366-
OptionalAttr<BoolArrayAttr>:$in_bounds)>,
1366+
BoolArrayAttr:$in_bounds)>,
13671367
Results<(outs AnyVectorOfAnyRank:$vector)> {
13681368

13691369
let summary = "Reads a supervector from memory into an SSA vector value.";
@@ -1401,16 +1401,19 @@ def Vector_TransferReadOp :
14011401
permutation or broadcasting. Elements whose corresponding mask element is
14021402
`0` are masked out and replaced with `padding`.
14031403

1404-
An optional boolean array attribute `in_bounds` specifies for every vector
1405-
dimension if the transfer is guaranteed to be within the source bounds. If
1406-
specified, the `in_bounds` array length has to be equal to the vector rank.
1407-
If set to "false", accesses (including the starting point) may run
1404+
For every vector dimension, the boolean array attribute `in_bounds`
1405+
specifies if the transfer is guaranteed to be within the source bounds. If
1406+
set to "false", accesses (including the starting point) may run
14081407
out-of-bounds along the respective vector dimension as the index increases.
1409-
Broadcast dimensions must always be in-bounds. In absence of the attribute,
1410-
accesses along all vector dimensions (except for broadcasts) may run
1411-
out-of-bounds. A `vector.transfer_read` can be lowered to a simple load if
1412-
all dimensions are specified to be within bounds and no `mask` was
1413-
specified. Note that non-vector dimensions *must* always be in-bounds.
1408+
Non-vector and broadcast dimensions *must* always be in-bounds. The
1409+
`in_bounds` array length has to be equal to the vector rank. This attribute
1410+
has a default value: `false` (i.e. "out-of-bounds"). When skipped in the
1411+
textual IR, the default value is assumed. Similarly, the OP printer will
1412+
omit this attribute when all dimensions are out-of-bounds (i.e. the default
1413+
value is used).
1414+
1415+
A `vector.transfer_read` can be lowered to a simple load if all dimensions
1416+
are specified to be within bounds and no `mask` was specified.
14141417

14151418
This operation is called 'read' by opposition to 'load' because the
14161419
super-vector granularity is generally not representable with a single
@@ -1607,7 +1610,7 @@ def Vector_TransferWriteOp :
16071610
Variadic<Index>:$indices,
16081611
AffineMapAttr:$permutation_map,
16091612
Optional<VectorOf<[I1]>>:$mask,
1610-
OptionalAttr<BoolArrayAttr>:$in_bounds)>,
1613+
BoolArrayAttr:$in_bounds)>,
16111614
Results<(outs Optional<AnyRankedTensor>:$result)> {
16121615

16131616
let summary = "The vector.transfer_write op writes a supervector to memory.";
@@ -1643,15 +1646,19 @@ def Vector_TransferWriteOp :
16431646
any permutation. Elements whose corresponding mask element is `0` are
16441647
masked out.
16451648

1646-
An optional boolean array attribute `in_bounds` specifies for every vector
1647-
dimension if the transfer is guaranteed to be within the source bounds. If
1648-
specified, the `in_bounds` array length has to be equal to the vector rank.
1649-
If set to "false", accesses (including the starting point) may run
1649+
For every vector dimension, the boolean array attribute `in_bounds`
1650+
specifies if the transfer is guaranteed to be within the source bounds. If
1651+
set to "false", accesses (including the starting point) may run
16501652
out-of-bounds along the respective vector dimension as the index increases.
1651-
In absence of the attribute, accesses along all vector dimensions may run
1652-
out-of-bounds. A `vector.transfer_write` can be lowered to a simple store if
1653-
all dimensions are specified to be within bounds and no `mask` was
1654-
specified. Note that non-vector dimensions *must* always be in-bounds.
1653+
Non-vector and broadcast dimensions *must* always be in-bounds. The
1654+
`in_bounds` array length has to be equal to the vector rank. This attribute
1655+
has a default value: `false` (i.e. "out-of-bounds"). When skipped in the
1656+
textual IR, the default value is assumed. Similarly, the OP printer will
1657+
omit this attribute when all dimensions are out-of-bounds (i.e. the default
1658+
value is used).
1659+
1660+
A `vector.transfer_write` can be lowered to a simple store if all
1661+
dimensions are specified to be within bounds and no `mask` was specified.
16551662

16561663
This operation is called 'write' by opposition to 'store' because the
16571664
super-vector granularity is generally not representable with a single

mlir/include/mlir/IR/AffineMap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ class AffineMap {
146146
/// affine map (d0, ..., dn) -> (dp, ..., dn) on the most minor dimensions.
147147
bool isMinorIdentity() const;
148148

149+
/// Returns the list of broadcast dimensions (i.e. dims indicated by value 0
150+
/// in the result).
151+
/// Ex:
152+
/// * (d0, d1, d2) -> (0, d1) gives [0]
153+
/// * (d0, d1, d2) -> (d2, d1) gives []
154+
/// * (d0, d1, d2, d4) -> (d0, 0, d1, 0) gives [1, 3]
155+
SmallVector<unsigned> getBroadcastDims() const;
156+
149157
/// Returns true if this affine map is a minor identity up to broadcasted
150158
/// dimensions which are indicated by value 0 in the result. If
151159
/// `broadcastedDims` is not null, it will be populated with the indices of

mlir/include/mlir/Interfaces/VectorInterfaces.td

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def VectorTransferOpInterface : OpInterface<"VectorTransferOpInterface"> {
9898
dimension whether it is in-bounds or not. (Broadcast dimensions are
9999
always in-bounds).
100100
}],
101-
/*retTy=*/"::std::optional<::mlir::ArrayAttr>",
101+
/*retTy=*/"::mlir::ArrayAttr",
102102
/*methodName=*/"getInBounds",
103103
/*args=*/(ins)
104104
>,
@@ -240,9 +240,7 @@ def VectorTransferOpInterface : OpInterface<"VectorTransferOpInterface"> {
240240
bool isDimInBounds(unsigned dim) {
241241
if ($_op.isBroadcastDim(dim))
242242
return true;
243-
if (!$_op.getInBounds())
244-
return false;
245-
auto inBounds = ::llvm::cast<::mlir::ArrayAttr>(*$_op.getInBounds());
243+
auto inBounds = $_op.getInBounds();
246244
return ::llvm::cast<::mlir::BoolAttr>(inBounds[dim]).getValue();
247245
}
248246

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,8 +1223,19 @@ 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+
12261236
auto transfer = state.builder.create<vector::TransferReadOp>(
1227-
loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices, permutationMap);
1237+
loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices, permutationMap,
1238+
inBounds);
12281239

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

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,8 +1343,17 @@ vectorizeAsLinalgGeneric(RewriterBase &rewriter, VectorizationState &state,
13431343

13441344
SmallVector<Value> indices(linalgOp.getShape(opOperand).size(), zero);
13451345

1346+
// Make sure that the in_bounds attribute corresponding to a broadcast dim
1347+
// is `true`
1348+
SmallVector<unsigned> broadcastedDims = readMap.getBroadcastDims();
1349+
SmallVector<bool> inBounds(readType.getRank(), false);
1350+
1351+
for (auto idx : broadcastedDims)
1352+
inBounds[idx] = true;
1353+
13461354
Operation *read = rewriter.create<vector::TransferReadOp>(
1347-
loc, readType, opOperand->get(), indices, readMap);
1355+
loc, readType, opOperand->get(), indices, readMap,
1356+
ArrayRef<bool>(inBounds));
13481357
read = state.maskOperation(rewriter, read, linalgOp, maskingMap);
13491358
Value readValue = read->getResult(0);
13501359

@@ -2681,11 +2690,12 @@ LogicalResult LinalgCopyVTRForwardingPattern::matchAndRewrite(
26812690
// The `masked` attribute is only valid on this padded buffer.
26822691
// When forwarding to vector.transfer_read, the attribute must be reset
26832692
// conservatively.
2693+
auto vectorType = xferOp.getVectorType();
26842694
Value res = rewriter.create<vector::TransferReadOp>(
2685-
xferOp.getLoc(), xferOp.getVectorType(), in, xferOp.getIndices(),
2695+
xferOp.getLoc(), vectorType, in, xferOp.getIndices(),
26862696
xferOp.getPermutationMapAttr(), xferOp.getPadding(), xferOp.getMask(),
2687-
// in_bounds is explicitly reset
2688-
/*inBoundsAttr=*/ArrayAttr());
2697+
rewriter.getBoolArrayAttr(
2698+
SmallVector<bool>(vectorType.getRank(), false)));
26892699

26902700
if (maybeFillOp)
26912701
rewriter.eraseOp(maybeFillOp);
@@ -2739,11 +2749,12 @@ LogicalResult LinalgCopyVTWForwardingPattern::matchAndRewrite(
27392749
// The `masked` attribute is only valid on this padded buffer.
27402750
// When forwarding to vector.transfer_write, the attribute must be reset
27412751
// conservatively.
2752+
auto vector = xferOp.getVector();
27422753
rewriter.create<vector::TransferWriteOp>(
2743-
xferOp.getLoc(), xferOp.getVector(), out, xferOp.getIndices(),
2754+
xferOp.getLoc(), vector, out, xferOp.getIndices(),
27442755
xferOp.getPermutationMapAttr(), xferOp.getMask(),
2745-
// in_bounds is explicitly reset
2746-
/*inBoundsAttr=*/ArrayAttr());
2756+
rewriter.getBoolArrayAttr(
2757+
SmallVector<bool>(vector.getType().getRank(), false)));
27472758

27482759
rewriter.eraseOp(copyOp);
27492760
rewriter.eraseOp(xferOp);

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

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,7 +3818,8 @@ void TransferReadOp::build(OpBuilder &builder, OperationState &result,
38183818
auto permutationMapAttr = AffineMapAttr::get(permutationMap);
38193819
auto inBoundsAttr = (inBounds && !inBounds.value().empty())
38203820
? builder.getBoolArrayAttr(inBounds.value())
3821-
: ArrayAttr();
3821+
: builder.getBoolArrayAttr(
3822+
SmallVector<bool>(vectorType.getRank(), false));
38223823
build(builder, result, vectorType, source, indices, permutationMapAttr,
38233824
inBoundsAttr);
38243825
}
@@ -3833,7 +3834,8 @@ void TransferReadOp::build(OpBuilder &builder, OperationState &result,
38333834
auto permutationMapAttr = AffineMapAttr::get(permutationMap);
38343835
auto inBoundsAttr = (inBounds && !inBounds.value().empty())
38353836
? builder.getBoolArrayAttr(inBounds.value())
3836-
: ArrayAttr();
3837+
: builder.getBoolArrayAttr(
3838+
SmallVector<bool>(vectorType.getRank(), false));
38373839
build(builder, result, vectorType, source, indices, permutationMapAttr,
38383840
padding,
38393841
/*mask=*/Value(), inBoundsAttr);
@@ -3951,17 +3953,15 @@ verifyTransferOp(VectorTransferOpInterface op, ShapedType shapedType,
39513953
<< inferredMaskType << ") and mask operand type (" << maskType
39523954
<< ") don't match";
39533955

3954-
if (inBounds) {
3955-
if (permutationMap.getNumResults() != static_cast<int64_t>(inBounds.size()))
3956-
return op->emitOpError("expects the optional in_bounds attr of same rank "
3957-
"as permutation_map results: ")
3958-
<< AffineMapAttr::get(permutationMap)
3959-
<< " vs inBounds of size: " << inBounds.size();
3960-
for (unsigned int i = 0; i < permutationMap.getNumResults(); ++i)
3961-
if (isa<AffineConstantExpr>(permutationMap.getResult(i)) &&
3962-
!llvm::cast<BoolAttr>(inBounds.getValue()[i]).getValue())
3963-
return op->emitOpError("requires broadcast dimensions to be in-bounds");
3964-
}
3956+
if (permutationMap.getNumResults() != static_cast<int64_t>(inBounds.size()))
3957+
return op->emitOpError("expects the in_bounds attr of same rank "
3958+
"as permutation_map results: ")
3959+
<< AffineMapAttr::get(permutationMap)
3960+
<< " vs inBounds of size: " << inBounds.size();
3961+
for (unsigned int i = 0, e = permutationMap.getNumResults(); i < e; ++i)
3962+
if (isa<AffineConstantExpr>(permutationMap.getResult(i)) &&
3963+
!llvm::cast<BoolAttr>(inBounds.getValue()[i]).getValue())
3964+
return op->emitOpError("requires broadcast dimensions to be in-bounds");
39653965

39663966
return success();
39673967
}
@@ -4037,6 +4037,13 @@ ParseResult TransferReadOp::parse(OpAsmParser &parser, OperationState &result) {
40374037
} else {
40384038
permMap = llvm::cast<AffineMapAttr>(permMapAttr).getValue();
40394039
}
4040+
auto inBoundsAttrName = TransferReadOp::getInBoundsAttrName(result.name);
4041+
Attribute inBoundsAttr = result.attributes.get(inBoundsAttrName);
4042+
if (!inBoundsAttr) {
4043+
result.addAttribute(inBoundsAttrName,
4044+
builder.getBoolArrayAttr(
4045+
SmallVector<bool>(permMap.getNumResults(), false)));
4046+
}
40404047
if (parser.resolveOperand(sourceInfo, shapedType, result.operands) ||
40414048
parser.resolveOperands(indexInfo, indexType, result.operands) ||
40424049
parser.resolveOperand(paddingInfo, shapedType.getElementType(),
@@ -4081,8 +4088,7 @@ LogicalResult TransferReadOp::verify() {
40814088

40824089
if (failed(verifyTransferOp(cast<VectorTransferOpInterface>(getOperation()),
40834090
shapedType, vectorType, maskType,
4084-
inferredMaskType, permutationMap,
4085-
getInBounds() ? *getInBounds() : ArrayAttr())))
4091+
inferredMaskType, permutationMap, getInBounds())))
40864092
return failure();
40874093

40884094
if (auto sourceVectorElementType =
@@ -4355,9 +4361,11 @@ void TransferWriteOp::build(OpBuilder &builder, OperationState &result,
43554361
AffineMap permutationMap,
43564362
std::optional<ArrayRef<bool>> inBounds) {
43574363
auto permutationMapAttr = AffineMapAttr::get(permutationMap);
4358-
auto inBoundsAttr = (inBounds && !inBounds.value().empty())
4359-
? builder.getBoolArrayAttr(inBounds.value())
4360-
: ArrayAttr();
4364+
auto inBoundsAttr =
4365+
(inBounds && !inBounds.value().empty())
4366+
? builder.getBoolArrayAttr(inBounds.value())
4367+
: builder.getBoolArrayAttr(SmallVector<bool>(
4368+
llvm::cast<VectorType>(vector.getType()).getRank(), false));
43614369
build(builder, result, vector, dest, indices, permutationMapAttr,
43624370
/*mask=*/Value(), inBoundsAttr);
43634371
}
@@ -4410,6 +4418,13 @@ ParseResult TransferWriteOp::parse(OpAsmParser &parser,
44104418
} else {
44114419
permMap = llvm::cast<AffineMapAttr>(permMapAttr).getValue();
44124420
}
4421+
auto inBoundsAttrName = TransferWriteOp::getInBoundsAttrName(result.name);
4422+
Attribute inBoundsAttr = result.attributes.get(inBoundsAttrName);
4423+
if (!inBoundsAttr) {
4424+
result.addAttribute(inBoundsAttrName,
4425+
builder.getBoolArrayAttr(
4426+
SmallVector<bool>(permMap.getNumResults(), false)));
4427+
}
44134428
if (parser.resolveOperand(vectorInfo, vectorType, result.operands) ||
44144429
parser.resolveOperand(sourceInfo, shapedType, result.operands) ||
44154430
parser.resolveOperands(indexInfo, indexType, result.operands))
@@ -4463,8 +4478,7 @@ LogicalResult TransferWriteOp::verify() {
44634478

44644479
if (failed(verifyTransferOp(cast<VectorTransferOpInterface>(getOperation()),
44654480
shapedType, vectorType, maskType,
4466-
inferredMaskType, permutationMap,
4467-
getInBounds() ? *getInBounds() : ArrayAttr())))
4481+
inferredMaskType, permutationMap, getInBounds())))
44684482
return failure();
44694483

44704484
return verifyPermutationMap(permutationMap,

mlir/lib/Dialect/Vector/Transforms/LowerVectorMask.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ struct MaskedTransferReadOpPattern
224224
rewriter.replaceOpWithNewOp<TransferReadOp>(
225225
maskingOp.getOperation(), readOp.getVectorType(), readOp.getSource(),
226226
readOp.getIndices(), readOp.getPermutationMap(), readOp.getPadding(),
227-
maskingOp.getMask(), readOp.getInBounds().value_or(ArrayAttr()));
227+
maskingOp.getMask(), readOp.getInBounds());
228228
return success();
229229
}
230230
};
@@ -246,7 +246,7 @@ struct MaskedTransferWriteOpPattern
246246
rewriter.replaceOpWithNewOp<TransferWriteOp>(
247247
maskingOp.getOperation(), resultType, writeOp.getVector(),
248248
writeOp.getSource(), writeOp.getIndices(), writeOp.getPermutationMap(),
249-
maskingOp.getMask(), writeOp.getInBounds().value_or(ArrayAttr()));
249+
maskingOp.getMask(), writeOp.getInBounds());
250250
return success();
251251
}
252252
};

mlir/lib/Dialect/Vector/Transforms/LowerVectorTransfer.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@ struct TransferReadPermutationLowering
133133

134134
// Transpose in_bounds attribute.
135135
ArrayAttr newInBoundsAttr =
136-
op.getInBounds() ? inverseTransposeInBoundsAttr(
137-
rewriter, op.getInBounds().value(), permutation)
138-
: ArrayAttr();
136+
inverseTransposeInBoundsAttr(rewriter, op.getInBounds(), permutation);
139137

140138
// Generate new transfer_read operation.
141139
VectorType newReadType = VectorType::get(
@@ -208,9 +206,7 @@ struct TransferWritePermutationLowering
208206

209207
// Transpose in_bounds attribute.
210208
ArrayAttr newInBoundsAttr =
211-
op.getInBounds() ? inverseTransposeInBoundsAttr(
212-
rewriter, op.getInBounds().value(), permutation)
213-
: ArrayAttr();
209+
inverseTransposeInBoundsAttr(rewriter, op.getInBounds(), permutation);
214210

215211
// Generate new transfer_write operation.
216212
Value newVec = rewriter.create<vector::TransposeOp>(

mlir/lib/IR/AffineMap.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,19 @@ bool AffineMap::isMinorIdentity() const {
158158
getMinorIdentityMap(getNumDims(), getNumResults(), getContext());
159159
}
160160

161+
SmallVector<unsigned> AffineMap::getBroadcastDims() const {
162+
SmallVector<unsigned> broadcastedDims;
163+
for (const auto &[resIdx, expr] : llvm::enumerate(getResults())) {
164+
if (auto constExpr = dyn_cast<AffineConstantExpr>(expr)) {
165+
if (constExpr.getValue() != 0)
166+
continue;
167+
broadcastedDims.push_back(resIdx);
168+
}
169+
}
170+
171+
return broadcastedDims;
172+
}
173+
161174
/// Returns true if this affine map is a minor identity up to broadcasted
162175
/// dimensions which are indicated by value 0 in the result.
163176
bool AffineMap::isMinorIdentityWithBroadcasting(

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 {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 {in_bounds = [false, true, false], 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 {permutation_map = affine_map<()->(0)>} :
510+
%0 = vector.transfer_read %arg[], %f0 {in_bounds = [true], 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 {permutation_map = #map1}
749+
%3 = vector.transfer_read %subview[%c0, %c0, %c0, %c0], %c0_i32, %mask {in_bounds = [false, true, true, false], permutation_map = #map1}
750750
: memref<1x1x1x1xi32>, vector<1x1x1x1xi32>
751751
return %3 : vector<1x1x1x1xi32>
752752
}

0 commit comments

Comments
 (0)