affine.load/store: check for the right number of operands

Affine load and store operations take a variadic number of arguments, most of
which are interpreted as subscripts for the multi-dimensional memref they
access.  Add a verifier check that ensures the number of operands is equal to
the number affine remapping inputs if present and to the rank of the acessed
memref otherwise.  Although it is impossible to obtain such operations by
parsing the custom syntax, it is possible to construct them using the generic
syntax or programmatically.

PiperOrigin-RevId: 257605902
This commit is contained in:
Alex Zinenko 2019-07-11 07:42:51 -07:00 committed by jpienaar
parent 4bbfb749bb
commit 65da460c79
2 changed files with 74 additions and 0 deletions

View File

@ -1648,6 +1648,12 @@ LogicalResult AffineLoadOp::verify() {
if (map.getNumResults() != getMemRefType().getRank())
return emitOpError("affine.load affine map num results must equal"
" memref rank");
if (map.getNumInputs() != getNumOperands() - 1)
return emitOpError("expects as many subscripts as affine map inputs");
} else {
if (getMemRefType().getRank() != getNumOperands() - 1)
return emitOpError(
"expects the number of subscripts to be equal to memref rank");
}
for (auto *idx : getIndices())
@ -1734,7 +1740,14 @@ LogicalResult AffineStoreOp::verify() {
if (map.getNumResults() != getMemRefType().getRank())
return emitOpError("affine.store affine map num results must equal"
" memref rank");
if (map.getNumInputs() != getNumOperands() - 2)
return emitOpError("expects as many subscripts as affine map inputs");
} else {
if (getMemRefType().getRank() != getNumOperands() - 2)
return emitOpError(
"expects the number of subscripts to be equal to memref rank");
}
for (auto *idx : getIndices())
if (!idx->getType().isIndex())
return emitOpError("index to load must have 'index' type");

View File

@ -0,0 +1,61 @@
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
func @load_too_many_subscripts(%arg0: memref<?x?xf32>, %arg1: index, %arg2: index, %arg3: index) {
// expected-error@+1 {{expects the number of subscripts to be equal to memref rank}}
"affine.load"(%arg0, %arg1, %arg2, %arg3) : (memref<?x?xf32>, index, index, index) -> f32
}
// -----
func @load_too_many_subscripts_map(%arg0: memref<?x?xf32>, %arg1: index, %arg2: index, %arg3: index) {
// expected-error@+1 {{op expects as many subscripts as affine map inputs}}
"affine.load"(%arg0, %arg1, %arg2, %arg3)
{map = (i, j) -> (i, j) } : (memref<?x?xf32>, index, index, index) -> f32
}
// -----
func @load_too_few_subscripts(%arg0: memref<?x?xf32>, %arg1: index) {
// expected-error@+1 {{expects the number of subscripts to be equal to memref rank}}
"affine.load"(%arg0, %arg1) : (memref<?x?xf32>, index) -> f32
}
// -----
func @load_too_few_subscripts_map(%arg0: memref<?x?xf32>, %arg1: index) {
// expected-error@+1 {{op expects as many subscripts as affine map inputs}}
"affine.load"(%arg0, %arg1)
{map = (i, j) -> (i, j) } : (memref<?x?xf32>, index) -> f32
}
// -----
func @store_too_many_subscripts(%arg0: memref<?x?xf32>, %arg1: index, %arg2: index,
%arg3: index, %val: f32) {
// expected-error@+1 {{expects the number of subscripts to be equal to memref rank}}
"affine.store"(%val, %arg0, %arg1, %arg2, %arg3) : (f32, memref<?x?xf32>, index, index, index) -> ()
}
// -----
func @store_too_many_subscripts_map(%arg0: memref<?x?xf32>, %arg1: index, %arg2: index,
%arg3: index, %val: f32) {
// expected-error@+1 {{op expects as many subscripts as affine map inputs}}
"affine.store"(%val, %arg0, %arg1, %arg2, %arg3)
{map = (i, j) -> (i, j) } : (f32, memref<?x?xf32>, index, index, index) -> ()
}
// -----
func @store_too_few_subscripts(%arg0: memref<?x?xf32>, %arg1: index, %val: f32) {
// expected-error@+1 {{expects the number of subscripts to be equal to memref rank}}
"affine.store"(%val, %arg0, %arg1) : (f32, memref<?x?xf32>, index) -> ()
}
// -----
func @store_too_few_subscripts_map(%arg0: memref<?x?xf32>, %arg1: index, %val: f32) {
// expected-error@+1 {{op expects as many subscripts as affine map inputs}}
"affine.store"(%val, %arg0, %arg1)
{map = (i, j) -> (i, j) } : (f32, memref<?x?xf32>, index) -> ()
}