Skip to content

Commit 42ad82b

Browse files
authored
[mlir][tosa] Add verifier check for Slice Op (#135853)
Add verifier check for Slice Op to make sure input1 and output have same ranks. Added test in verifier.mlir Also moved existing slice verifier tests in invalid.mlir to verfier.mlir Signed-off-by: Tai Ly <[email protected]>
1 parent 41c1a7b commit 42ad82b

File tree

3 files changed

+61
-43
lines changed

3 files changed

+61
-43
lines changed

mlir/lib/Dialect/Tosa/IR/TosaOps.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,19 +1446,26 @@ LogicalResult tosa::SliceOp::verify() {
14461446
/* outType = */ getOutput().getType())
14471447
.failed())
14481448
return failure();
1449-
auto inputType = llvm::dyn_cast<RankedTensorType>(getInput1().getType());
1450-
if (!inputType)
1451-
return success();
14521449

1453-
auto startShapeRank =
1454-
llvm::cast<tosa::shapeType>(getStart().getType()).getRank();
1455-
if (inputType.getRank() != startShapeRank)
1456-
return emitOpError("length of start is not equal to rank of input shape");
1450+
const ShapeAdaptor inputShape(getInput1().getType());
1451+
if (inputShape.hasRank()) {
1452+
const auto inputRank = inputShape.getRank();
1453+
const ShapeAdaptor outputShape(getOutput().getType());
1454+
if (outputShape.hasRank() && inputRank != outputShape.getRank())
1455+
return emitOpError(
1456+
"expect input1 and output to have the same ranks, got ")
1457+
<< inputRank << " and " << outputShape.getRank();
1458+
1459+
const auto startShapeRank =
1460+
llvm::cast<tosa::shapeType>(getStart().getType()).getRank();
1461+
if (inputRank != startShapeRank)
1462+
return emitOpError("length of start is not equal to rank of input shape");
14571463

1458-
auto sizeShapeRank =
1459-
llvm::cast<tosa::shapeType>(getSize().getType()).getRank();
1460-
if (inputType.getRank() != sizeShapeRank)
1461-
return emitOpError("length of size is not equal to rank of input shape");
1464+
const auto sizeShapeRank =
1465+
llvm::cast<tosa::shapeType>(getSize().getType()).getRank();
1466+
if (inputRank != sizeShapeRank)
1467+
return emitOpError("length of size is not equal to rank of input shape");
1468+
}
14621469

14631470
return success();
14641471
}

mlir/test/Dialect/Tosa/invalid.mlir

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -660,28 +660,6 @@ func.func @test_variable_write_shape(%arg0: tensor<1x4x8xi8>) -> () {
660660

661661
// -----
662662

663-
func.func @test_slice_invalid_start() {
664-
%0 = tensor.empty() : tensor<4x31x31xf32>
665-
%start = tosa.const_shape {values = dense<[1, 1]> : tensor<2xindex>} : () -> !tosa.shape<2>
666-
%size = tosa.const_shape {values = dense<[1, 1, 1]> : tensor<3xindex>} : () -> !tosa.shape<3>
667-
// expected-error@+1 {{'tosa.slice' op length of start is not equal to rank of input shape}}
668-
%3 = tosa.slice %0, %start, %size : (tensor<4x31x31xf32>, !tosa.shape<2>, !tosa.shape<3>) -> tensor<*xf32>
669-
return
670-
}
671-
672-
// -----
673-
674-
func.func @test_slice_invalid_size() {
675-
%0 = tensor.empty() : tensor<4x31x31xf32>
676-
%start = tosa.const_shape {values = dense<[1, 1, 1]> : tensor<3xindex>} : () -> !tosa.shape<3>
677-
%size = tosa.const_shape {values = dense<[1]> : tensor<1xindex>} : () -> !tosa.shape<1>
678-
// expected-error@+1 {{'tosa.slice' op length of size is not equal to rank of input shape}}
679-
%3 = tosa.slice %0, %start, %size : (tensor<4x31x31xf32>, !tosa.shape<3>, !tosa.shape<1>) -> tensor<*xf32>
680-
return
681-
}
682-
683-
// -----
684-
685663
func.func @test_tile_invalid_multiples() {
686664
%0 = tensor.empty() : tensor<4x31x31xf32>
687665
%cst = tosa.const_shape { values = dense<1> : tensor<1xindex> } : () -> !tosa.shape<1>
@@ -1938,16 +1916,6 @@ func.func @test_scalar_reverse(%arg0: tensor<f32>) -> tensor<f32> {
19381916

19391917
// -----
19401918

1941-
func.func @test_scalar_slice(%arg0: tensor<f32>) -> tensor<f32> {
1942-
%0 = tosa.const_shape {values = dense<[]> : tensor<0xindex>} : () -> !tosa.shape<0>
1943-
%1 = tosa.const_shape {values = dense<[]> : tensor<0xindex>} : () -> !tosa.shape<0>
1944-
// expected-error@+1 {{'tosa.slice' op operand #0 must be tosa-conformant tensor of at least rank 1, but got 'tensor<f32>'}}
1945-
%2 = tosa.slice %arg0, %0, %1 : (tensor<f32>, !tosa.shape<0>, !tosa.shape<0>) -> tensor<f32>
1946-
return %2 : tensor<f32>
1947-
}
1948-
1949-
// -----
1950-
19511919
func.func @test_scalar_tile(%arg0: tensor<f32>) -> tensor<*xf32> {
19521920
%cst = tosa.const_shape { values = dense<[]> : tensor<0xindex> } : () -> !tosa.shape<0>
19531921
// expected-error@+1 {{'tosa.tile' op operand #0 must be tosa-conformant tensor of at least rank 1, but got 'tensor<f32>'}}

mlir/test/Dialect/Tosa/verifier.mlir

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,46 @@ func.func @test_scalar_output_transpose(%arg0: tensor<*xf32>) -> tensor<f32> {
124124
%1 = tosa.transpose %arg0 {perms = array<i32: 2, 0, 1>} : (tensor<*xf32>) -> tensor<f32>
125125
return %1 : tensor<f32>
126126
}
127+
128+
// -----
129+
130+
func.func @test_slice_invalid_output_rank() {
131+
%0 = tensor.empty() : tensor<4x31x31xf32>
132+
%start = tosa.const_shape {values = dense<[1, 1]> : tensor<2xindex>} : () -> !tosa.shape<2>
133+
%size = tosa.const_shape {values = dense<[1, 1, 1]> : tensor<3xindex>} : () -> !tosa.shape<3>
134+
// expected-error@+1 {{'tosa.slice' op expect input1 and output to have the same ranks, got 3 and 4}}
135+
%3 = tosa.slice %0, %start, %size : (tensor<4x31x31xf32>, !tosa.shape<2>, !tosa.shape<3>) -> tensor<?x?x?x?xf32>
136+
return
137+
}
138+
139+
// -----
140+
141+
func.func @test_slice_invalid_start() {
142+
%0 = tensor.empty() : tensor<4x31x31xf32>
143+
%start = tosa.const_shape {values = dense<[1, 1]> : tensor<2xindex>} : () -> !tosa.shape<2>
144+
%size = tosa.const_shape {values = dense<[1, 1, 1]> : tensor<3xindex>} : () -> !tosa.shape<3>
145+
// expected-error@+1 {{'tosa.slice' op length of start is not equal to rank of input shape}}
146+
%3 = tosa.slice %0, %start, %size : (tensor<4x31x31xf32>, !tosa.shape<2>, !tosa.shape<3>) -> tensor<*xf32>
147+
return
148+
}
149+
150+
// -----
151+
152+
func.func @test_slice_invalid_size() {
153+
%0 = tensor.empty() : tensor<4x31x31xf32>
154+
%start = tosa.const_shape {values = dense<[1, 1, 1]> : tensor<3xindex>} : () -> !tosa.shape<3>
155+
%size = tosa.const_shape {values = dense<[1]> : tensor<1xindex>} : () -> !tosa.shape<1>
156+
// expected-error@+1 {{'tosa.slice' op length of size is not equal to rank of input shape}}
157+
%3 = tosa.slice %0, %start, %size : (tensor<4x31x31xf32>, !tosa.shape<3>, !tosa.shape<1>) -> tensor<*xf32>
158+
return
159+
}
160+
161+
// -----
162+
163+
func.func @test_scalar_slice(%arg0: tensor<f32>) -> tensor<f32> {
164+
%0 = tosa.const_shape {values = dense<[]> : tensor<0xindex>} : () -> !tosa.shape<0>
165+
%1 = tosa.const_shape {values = dense<[]> : tensor<0xindex>} : () -> !tosa.shape<0>
166+
// expected-error@+1 {{'tosa.slice' op operand #0 must be tosa-conformant tensor of at least rank 1, but got 'tensor<f32>'}}
167+
%2 = tosa.slice %arg0, %0, %1 : (tensor<f32>, !tosa.shape<0>, !tosa.shape<0>) -> tensor<f32>
168+
return %2 : tensor<f32>
169+
}

0 commit comments

Comments
 (0)