Skip to content

Commit 41481df

Browse files
committed
[mlir] ViewLikeInterface - verify ranks in verifyOffsetSizeAndStrideOp
getMixedOffsets() calls getMixedValues() with `static_offsets` and `offsets`. It is assumed that the number of dynamic offsets in `static_offsets` equals the rank of `offsets`. Otherwise, we fail on assert when trying to access an array out of its bounds. The same applies to getMixedStrides() and getMixedOffsets(). A verification of this assumption is added to verifyOffsetSizeAndStrideOp() and a clear assert is added in getMixedValues().
1 parent 2d030b0 commit 41481df

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

mlir/lib/Dialect/Utils/StaticValueUtils.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,16 @@ bool isEqualConstantIntOrValueArray(ArrayRef<OpFoldResult> ofrs1,
181181
return true;
182182
}
183183

184-
/// Return a vector of OpFoldResults with the same size a staticValues, but all
184+
/// Return a vector of OpFoldResults with the same size as staticValues, but all
185185
/// elements for which ShapedType::isDynamic is true, will be replaced by
186186
/// dynamicValues.
187187
SmallVector<OpFoldResult> getMixedValues(ArrayRef<int64_t> staticValues,
188188
ValueRange dynamicValues,
189189
MLIRContext *context) {
190+
assert(dynamicValues.size() ==
191+
(unsigned)llvm::count_if(staticValues, ShapedType::isDynamic) &&
192+
"expected the rank of dynamic values to match the number of "
193+
"values known to be dynamic");
190194
SmallVector<OpFoldResult> res;
191195
res.reserve(staticValues.size());
192196
unsigned numDynamic = 0;

mlir/lib/Interfaces/ViewLikeInterface.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,32 @@ SliceBoundsVerificationResult mlir::verifyInBoundsSlice(
9494

9595
LogicalResult
9696
mlir::detail::verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) {
97+
// A dynamic size is represented as ShapedType::kDynamic in `static_sizes`.
98+
// Its corresponding Value appears in `sizes`. Thus, the number of dynamic
99+
// dimensions in `static_sizes` must equal the rank of `sizes`.
100+
// The same applies to strides and offsets.
101+
unsigned int numDynamicDims =
102+
llvm::count_if(op.getStaticSizes(), ShapedType::isDynamic);
103+
if (op.getSizes().size() != numDynamicDims) {
104+
return op->emitError("expected sizes rank to match the number of dynamic "
105+
"dimensions (")
106+
<< op.getSizes().size() << " vs " << numDynamicDims << ")";
107+
}
108+
unsigned int numDynamicStrides =
109+
llvm::count_if(op.getStaticStrides(), ShapedType::isDynamic);
110+
if (op.getStrides().size() != numDynamicStrides) {
111+
return op->emitError("expected strides rank to match the number of dynamic "
112+
"strides (")
113+
<< op.getStrides().size() << " vs " << numDynamicStrides << ")";
114+
}
115+
unsigned int numDynamicOffsets =
116+
llvm::count_if(op.getStaticOffsets(), ShapedType::isDynamic);
117+
if (op.getOffsets().size() != numDynamicOffsets) {
118+
return op->emitError("expected offsets rank to match the number of dynamic "
119+
"offsets (")
120+
<< op.getOffsets().size() << " vs " << numDynamicOffsets << ")";
121+
}
122+
97123
std::array<unsigned, 3> maxRanks = op.getArrayAttrMaxRanks();
98124
// Offsets can come in 2 flavors:
99125
// 1. Either single entry (when maxRanks == 1).

mlir/test/Dialect/MemRef/invalid.mlir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,18 @@ func.func @invalid_subview(%arg0 : index, %arg1 : index, %arg2 : index) {
658658

659659
// -----
660660

661+
// This test is not written in the op's assembly format, to reproduce a mismatch
662+
// between the rank of static_offsets and the number of Values sent as the
663+
// dynamic offsets.
664+
func.func @invalid_subview(%arg0 : memref<?x128xi8, 1>) {
665+
%0 = memref.alloc() :memref<1xf32>
666+
// expected-error@+1 {{expected offsets rank to match the number of dynamic offsets (0 vs 1)}}
667+
"memref.subview"(%0) <{operandSegmentSizes = array<i32: 1, 0, 0, 0>, static_offsets = array<i64: -9223372036854775808>, static_sizes = array<i64: 1>, static_strides = array<i64: 1>}> : (memref<1xf32>) -> memref<1xf32, strided<[1], offset: ?>>
668+
return
669+
}
670+
671+
// -----
672+
661673
func.func @invalid_subview(%arg0 : index, %arg1 : index, %arg2 : index) {
662674
%0 = memref.alloc() : memref<8x16x4xf32>
663675
// expected-error@+1 {{expected mixed sizes rank to match mixed strides rank (3 vs 2) so the rank of the result type is well-formed}}

0 commit comments

Comments
 (0)