Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion mlir/lib/Dialect/Utils/StaticValueUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,16 @@ bool isEqualConstantIntOrValueArray(ArrayRef<OpFoldResult> ofrs1,
return true;
}

/// Return a vector of OpFoldResults with the same size a staticValues, but all
/// Return a vector of OpFoldResults with the same size as staticValues, but all
/// elements for which ShapedType::isDynamic is true, will be replaced by
/// dynamicValues.
SmallVector<OpFoldResult> getMixedValues(ArrayRef<int64_t> staticValues,
ValueRange dynamicValues,
MLIRContext *context) {
assert(dynamicValues.size() == static_cast<size_t>(llvm::count_if(
staticValues, ShapedType::isDynamic)) &&
"expected the rank of dynamic values to match the number of "
"values known to be dynamic");
SmallVector<OpFoldResult> res;
res.reserve(staticValues.size());
unsigned numDynamic = 0;
Expand Down
26 changes: 26 additions & 0 deletions mlir/lib/Interfaces/ViewLikeInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,32 @@ SliceBoundsVerificationResult mlir::verifyInBoundsSlice(

LogicalResult
mlir::detail::verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) {
// A dynamic size is represented as ShapedType::kDynamic in `static_sizes`.
// Its corresponding Value appears in `sizes`. Thus, the number of dynamic
// dimensions in `static_sizes` must equal the rank of `sizes`.
// The same applies to strides and offsets.
size_t numDynamicDims =
llvm::count_if(op.getStaticSizes(), ShapedType::isDynamic);
if (op.getSizes().size() != numDynamicDims) {
return op->emitError("expected the number of 'sizes' to match the number "
"of dynamic entries in 'static_sizes' (")
<< op.getSizes().size() << " vs " << numDynamicDims << ")";
}
size_t numDynamicStrides =
llvm::count_if(op.getStaticStrides(), ShapedType::isDynamic);
if (op.getStrides().size() != numDynamicStrides) {
return op->emitError("expected the number of 'strides' to match the number "
"of dynamic entries in 'static_strides' (")
<< op.getStrides().size() << " vs " << numDynamicStrides << ")";
}
size_t numDynamicOffsets =
llvm::count_if(op.getStaticOffsets(), ShapedType::isDynamic);
if (op.getOffsets().size() != numDynamicOffsets) {
return op->emitError("expected the number of 'offsets' to match the number "
"of dynamic entries in 'static_offsets' (")
<< op.getOffsets().size() << " vs " << numDynamicOffsets << ")";
}

std::array<unsigned, 3> maxRanks = op.getArrayAttrMaxRanks();
// Offsets can come in 2 flavors:
// 1. Either single entry (when maxRanks == 1).
Expand Down
12 changes: 12 additions & 0 deletions mlir/test/Dialect/MemRef/invalid.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,18 @@ func.func @invalid_subview(%arg0 : index, %arg1 : index, %arg2 : index) {

// -----

// This test is not written in the op's assembly format, to reproduce a mismatch
// between the rank of static_offsets and the number of Values sent as the
// dynamic offsets.
func.func @invalid_subview(%arg0 : memref<?x128xi8, 1>) {
%0 = memref.alloc() :memref<1xf32>
// expected-error@+1 {{expected the number of 'offsets' to match the number of dynamic entries in 'static_offsets' (0 vs 1)}}
"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: ?>>
return
}

// -----

func.func @invalid_subview(%arg0 : index, %arg1 : index, %arg2 : index) {
%0 = memref.alloc() : memref<8x16x4xf32>
// 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}}
Expand Down
Loading