2019-06-20 02:21:41 +08:00
|
|
|
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
|
2018-06-25 00:10:36 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// Check different error cases.
|
|
|
|
// -----
|
2018-06-25 02:18:29 +08:00
|
|
|
|
2019-02-06 03:47:02 +08:00
|
|
|
func @illegaltype(i) // expected-error {{expected non-function type}}
|
2018-06-25 02:18:29 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-25 23:10:46 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @illegaltype() {
|
2019-06-26 07:06:13 +08:00
|
|
|
%0 = constant dense<0> : <vector 4 x f32> : vector<4 x f32> // expected-error {{expected non-function type}}
|
2018-11-10 13:24:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @nestedtensor(tensor<tensor<i8>>) -> () // expected-error {{invalid tensor element type}}
|
2018-06-25 02:18:29 +08:00
|
|
|
|
2018-12-12 05:49:43 +08:00
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @indexvector(vector<4 x index>) -> () // expected-error {{vector elements must be int or float type}}
|
2018-12-12 05:49:43 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-04 23:23:28 +08:00
|
|
|
// Everything is valid in a memref.
|
|
|
|
func @indexmemref(memref<? x index>) -> ()
|
2018-12-12 05:49:43 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @indextensor(tensor<4 x index>) -> () // expected-error {{invalid tensor element type}}
|
2018-12-12 05:49:43 +08:00
|
|
|
|
2018-07-17 00:45:22 +08:00
|
|
|
// -----
|
|
|
|
// Test no map in memref type.
|
2019-01-03 02:20:00 +08:00
|
|
|
func @memrefs(memref<2x4xi8, >) // expected-error {{expected list element}}
|
2018-07-17 00:45:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
// Test non-existent map in memref type.
|
2019-05-16 00:10:52 +08:00
|
|
|
func @memrefs(memref<2x4xi8, #map7>) // expected-error {{undefined symbol alias id 'map7'}}
|
2018-07-17 00:45:22 +08:00
|
|
|
|
|
|
|
// -----
|
2019-05-07 01:36:32 +08:00
|
|
|
// Test non affine map in memref type.
|
|
|
|
func @memrefs(memref<2x4xi8, i8>) // expected-error {{expected affine map in memref type}}
|
2018-07-17 00:45:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
// Test non-existent map in map composition of memref type.
|
|
|
|
#map0 = (d0, d1) -> (d0, d1)
|
|
|
|
|
2019-05-16 00:10:52 +08:00
|
|
|
func @memrefs(memref<2x4xi8, #map0, #map8>) // expected-error {{undefined symbol alias id 'map8'}}
|
2018-07-17 00:45:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
// Test multiple memory space error.
|
|
|
|
#map0 = (d0, d1) -> (d0, d1)
|
2019-01-03 02:20:00 +08:00
|
|
|
func @memrefs(memref<2x4xi8, #map0, 1, 2>) // expected-error {{multiple memory spaces specified in memref type}}
|
2018-07-17 00:45:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
// Test affine map after memory space.
|
|
|
|
#map0 = (d0, d1) -> (d0, d1)
|
|
|
|
#map1 = (d0, d1) -> (d0, d1)
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @memrefs(memref<2x4xi8, #map0, 1, #map1>) // expected-error {{affine map after memory space in memref type}}
|
2018-07-17 00:45:22 +08:00
|
|
|
|
2018-10-26 21:15:38 +08:00
|
|
|
// -----
|
|
|
|
// Test dimension mismatch between memref and layout map.
|
|
|
|
// The error must be emitted even for the trivial identity layout maps that are
|
|
|
|
// dropped in type creation.
|
|
|
|
#map0 = (d0, d1) -> (d0, d1)
|
2019-01-03 02:20:00 +08:00
|
|
|
func @memrefs(memref<42xi8, #map0>) // expected-error {{memref affine map dimension mismatch}}
|
2018-11-02 16:48:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
#map0 = (d0, d1) -> (d0, d1)
|
|
|
|
#map1 = (d0) -> (d0)
|
2019-01-03 02:20:00 +08:00
|
|
|
func @memrefs(memref<42x42xi8, #map0, #map1>) // expected-error {{memref affine map dimension mismatch}}
|
2018-10-26 21:15:38 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-25 23:10:46 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func missingsigil() -> (i1, index, f32) // expected-error {{expected a function identifier like}}
|
2018-06-25 02:18:29 +08:00
|
|
|
|
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-25 02:18:29 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @bad_branch() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb12:
|
|
|
|
br ^missing // expected-error {{reference to an undefined block}}
|
2018-06-25 02:18:29 +08:00
|
|
|
}
|
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-25 02:18:29 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @block_redef() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42:
|
2018-06-25 02:18:29 +08:00
|
|
|
return
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42: // expected-error {{redefinition of block '^bb42'}}
|
2018-06-25 23:10:46 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-25 23:10:46 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @no_terminator() { // expected-error {{block with no terminator}}
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb40:
|
2018-06-25 23:10:46 +08:00
|
|
|
return
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb41:
|
2018-12-30 05:36:59 +08:00
|
|
|
^bb42:
|
2018-06-25 02:18:29 +08:00
|
|
|
return
|
|
|
|
}
|
2018-06-29 08:02:32 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-29 08:02:32 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @block_no_rparen() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42 (%bb42 : i32: // expected-error {{expected ')' to end argument list}}
|
2018-07-23 06:45:24 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @block_arg_no_ssaid() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42 (i32): // expected-error {{expected SSA operand}}
|
2018-07-23 06:45:24 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @block_arg_no_type() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42 (%0): // expected-error {{expected ':' and type for SSA operand}}
|
2018-07-23 06:45:24 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @block_arg_no_close_paren() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42:
|
|
|
|
br ^bb2( // expected-error@+1 {{expected ')' to close argument list}}
|
2018-10-14 22:55:29 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @block_first_has_predecessor() {
|
2019-06-08 00:46:13 +08:00
|
|
|
// expected-error@-1 {{entry block of region may not have predecessors}}
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42:
|
|
|
|
br ^bb43
|
|
|
|
^bb43:
|
|
|
|
br ^bb42
|
2018-10-23 23:12:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-06-04 00:43:22 +08:00
|
|
|
func @empty() { // expected-error {{function must have a body}}
|
|
|
|
}
|
2018-06-29 08:02:32 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-29 08:02:32 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @no_return() {
|
2019-02-09 01:52:26 +08:00
|
|
|
%x = constant 0 : i32 // expected-error {{block with no terminator}}
|
2018-08-10 03:28:58 +08:00
|
|
|
}
|
2018-06-29 11:45:33 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-29 11:45:33 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
" // expected-error {{expected}}
|
2018-06-29 11:45:33 +08:00
|
|
|
"
|
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-29 11:45:33 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
" // expected-error {{expected}}
|
2018-06-29 11:45:33 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-29 11:45:33 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @bad_op_type() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb40:
|
2018-07-19 06:31:25 +08:00
|
|
|
"foo"() : i32 // expected-error {{expected function type}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @no_terminator() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb40:
|
2018-07-19 06:31:25 +08:00
|
|
|
"foo"() : ()->()
|
|
|
|
""() : ()->() // expected-error {{empty operation name is invalid}}
|
2018-06-29 11:45:33 +08:00
|
|
|
return
|
|
|
|
}
|
2018-06-30 13:08:05 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-06-30 13:08:05 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @illegaltype(i0) // expected-error {{invalid integer width}}
|
2018-06-30 13:08:05 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-07-04 08:51:28 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @malformed_for_percent() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for i = 1 to 10 { // expected-error {{expected SSA operand}}
|
2018-08-10 03:28:58 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @malformed_for_equal() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i 1 to 10 { // expected-error {{expected '='}}
|
2018-08-10 03:28:58 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @malformed_for_to() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 too 10 { // expected-error {{expected 'to' between bounds}}
|
2018-07-20 00:52:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @incomplete_for() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 step 2
|
2019-03-15 01:38:44 +08:00
|
|
|
} // expected-error {{expected '{' to begin a region}}
|
2018-06-30 13:08:05 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-07-04 08:51:28 +08:00
|
|
|
|
2019-02-28 09:58:09 +08:00
|
|
|
#map0 = (d0) -> (d0 floordiv 4)
|
|
|
|
|
|
|
|
func @reference_to_iv_in_bound() {
|
|
|
|
// expected-error@+1 {{operand use before it's defined}}
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i0 = #map0(%i0) to 10 {
|
2019-02-28 09:58:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @nonconstant_step(%1 : i32) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %2 = 1 to 5 step %1 { // expected-error {{expected non-function type}}
|
2018-07-20 00:52:39 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @for_negative_stride() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 step -1
|
2019-02-02 08:42:18 +08:00
|
|
|
} // expected-error@-1 {{expected step to be representable as a positive signed integer}}
|
2018-09-28 09:03:27 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-03-28 23:24:38 +08:00
|
|
|
func @non_operation() {
|
2018-07-26 02:15:20 +08:00
|
|
|
asd // expected-error {{custom op 'asd' is unknown}}
|
2018-07-04 08:51:28 +08:00
|
|
|
}
|
2018-07-05 11:45:39 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-07-05 11:45:39 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_conditional2() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if (i)[N] : (i >= ) // expected-error {{expected '== 0' or '>= 0' at end of affine constraint}}
|
2018-08-08 05:24:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_conditional3() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if (i)[N] : (i == 1) // expected-error {{expected '0' after '=='}}
|
2018-08-08 05:24:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_conditional4() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if (i)[N] : (i >= 2) // expected-error {{expected '0' after '>='}}
|
2018-08-08 05:24:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_conditional5() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if (i)[N] : (i <= 0 ) // expected-error {{expected '== 0' or '>= 0' at end of affine constraint}}
|
2018-08-08 05:24:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_conditional6() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if (i) : (i) // expected-error {{expected '== 0' or '>= 0' at end of affine constraint}}
|
2018-08-08 05:24:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
2019-03-25 11:35:07 +08:00
|
|
|
// TODO (support affine.if (1)?
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_conditional7() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if (i) : (1) // expected-error {{expected '== 0' or '>= 0' at end of affine constraint}}
|
2018-08-08 05:24:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
#map = (d0) -> (% // expected-error {{invalid SSA name}}
|
2018-07-12 04:26:23 +08:00
|
|
|
|
2018-07-15 14:06:24 +08:00
|
|
|
// -----
|
2018-07-19 23:35:28 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @test() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb40:
|
2018-07-21 00:28:54 +08:00
|
|
|
%1 = "foo"() : (i32)->i64 // expected-error {{expected 0 operand types but had 1}}
|
2018-07-19 23:35:28 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @redef() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42:
|
2019-06-26 10:06:06 +08:00
|
|
|
%x = "xxx"(){index = 0} : ()->i32 // expected-note {{previously defined here}}
|
|
|
|
%x = "xxx"(){index = 0} : ()->i32 // expected-error {{redefinition of SSA value '%x'}}
|
2018-07-19 23:35:28 +08:00
|
|
|
return
|
2018-07-20 00:52:39 +08:00
|
|
|
}
|
|
|
|
|
2018-07-21 09:41:34 +08:00
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @undef() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42:
|
2018-07-21 09:41:34 +08:00
|
|
|
%x = "xxx"(%y) : (i32)->i32 // expected-error {{use of undeclared SSA value}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-02-06 03:47:02 +08:00
|
|
|
func @malformed_type(%a : intt) { // expected-error {{expected non-function type}}
|
2018-07-20 00:52:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @resulterror() -> i32 {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42:
|
2019-03-03 10:03:03 +08:00
|
|
|
return // expected-error {{'std.return' op has 0 operands, but enclosing function returns 1}}
|
2018-07-22 05:32:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
2018-07-23 06:45:24 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @func_resulterror() -> i32 {
|
2019-03-03 10:03:03 +08:00
|
|
|
return // expected-error {{'std.return' op has 0 operands, but enclosing function returns 1}}
|
2018-08-10 03:28:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @argError() {
|
2019-05-14 02:43:17 +08:00
|
|
|
^bb1(%a: i64): // expected-note {{previously defined here}}
|
2018-12-30 03:32:37 +08:00
|
|
|
br ^bb2
|
|
|
|
^bb2(%a: i64): // expected-error{{redefinition of SSA value '%a'}}
|
2018-07-23 06:45:24 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @bbargMismatch(i32, f32) {
|
2019-06-04 00:43:22 +08:00
|
|
|
// expected-error @-1 {{first block of function must have 2 arguments to match function signature}}
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb42(%0: f32):
|
2018-07-23 06:45:24 +08:00
|
|
|
return
|
|
|
|
}
|
2018-07-23 23:42:19 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @br_mismatch() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-03-29 05:58:52 +08:00
|
|
|
%0:2 = "foo"() : () -> (i1, i17)
|
2018-09-07 11:56:12 +08:00
|
|
|
// expected-error @+1 {{branch has 2 operands, but target block has 1}}
|
2018-12-30 03:32:37 +08:00
|
|
|
br ^bb1(%0#1, %0#0 : i17, i1)
|
2018-07-23 23:42:19 +08:00
|
|
|
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb1(%x: i17):
|
2018-07-23 23:42:19 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-07-24 02:48:22 +08:00
|
|
|
// -----
|
|
|
|
|
|
|
|
// Test no nested vector.
|
2019-01-03 02:20:00 +08:00
|
|
|
func @vectors(vector<1 x vector<1xi32>>, vector<2x4xf32>)
|
2018-12-12 05:49:43 +08:00
|
|
|
// expected-error@-1 {{vector elements must be int or float type}}
|
Eliminate "primitive" types from being a thing, splitting them into FloatType
and OtherType. Other type is now the thing that holds AffineInt, Control,
eventually Resource, Variant, String, etc. FloatType holds the floating point
types, and allows convenient query of isa<FloatType>().
This fixes issues where we allowed control to be the element type of tensor,
memref, vector. At the same time, ban AffineInt from being an element of a
vector/memref/tensor as well since we don't need it.
I updated the spec to match this as well.
PiperOrigin-RevId: 206361942
2018-07-28 04:09:58 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @condbr_notbool() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-05-14 02:43:17 +08:00
|
|
|
%a = "foo"() : () -> i32 // expected-note {{prior use here}}
|
2019-06-25 08:51:44 +08:00
|
|
|
cond_br %a, ^bb0, ^bb0 // expected-error {{use of value '%a' expects different type than prior uses: 'i1' vs 'i32'}}
|
2018-11-16 04:32:21 +08:00
|
|
|
// expected-error@-1 {{expected condition type was boolean (i1)}}
|
2018-07-25 06:01:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @condbr_badtype() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2018-07-25 06:01:27 +08:00
|
|
|
%c = "foo"() : () -> i1
|
|
|
|
%a = "foo"() : () -> i32
|
2019-02-06 03:47:02 +08:00
|
|
|
cond_br %c, ^bb0(%a, %a : i32, ^bb0) // expected-error {{expected non-function type}}
|
2018-07-25 06:01:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @condbr_a_bb_is_not_a_type() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2018-07-25 06:01:27 +08:00
|
|
|
%c = "foo"() : () -> i1
|
|
|
|
%a = "foo"() : () -> i32
|
2018-12-30 03:32:37 +08:00
|
|
|
cond_br %c, ^bb0(%a, %a : i32, i32), i32 // expected-error {{expected block name}}
|
2018-07-25 06:01:27 +08:00
|
|
|
}
|
2018-07-27 09:09:20 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-10 04:28:30 +08:00
|
|
|
func @successors_in_non_terminator(%a : i32, %b : i32) {
|
2019-03-03 10:03:03 +08:00
|
|
|
%c = "std.addi"(%a, %b)[^bb1] : () -> () // expected-error {{successors in non-terminator}}
|
2019-01-10 04:28:30 +08:00
|
|
|
^bb1:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @undef() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2018-10-14 22:55:29 +08:00
|
|
|
%x = "xxx"(%y) : (i32)->i32 // expected-error {{use of undeclared SSA value name}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @undef() {
|
2019-01-02 23:00:07 +08:00
|
|
|
%x = "xxx"(%y) : (i32)->i32 // expected-error {{use of undeclared SSA value name}}
|
2018-07-27 09:09:20 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-07-31 06:18:10 +08:00
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @duplicate_induction_var() {
|
2019-05-09 01:29:50 +08:00
|
|
|
affine.for %i = 1 to 10 { // expected-note {{previously defined here}}
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 { // expected-error {{redefinition of SSA value '%i'}}
|
2018-07-31 06:18:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2018-08-06 12:12:29 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-06-04 00:43:22 +08:00
|
|
|
func @name_scope_failure() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2018-08-06 12:12:29 +08:00
|
|
|
}
|
2019-06-04 00:43:22 +08:00
|
|
|
"xxx"(%i) : (index)->() // expected-error {{use of undeclared SSA value name}}
|
2018-08-06 12:12:29 +08:00
|
|
|
return
|
|
|
|
}
|
2018-08-10 03:28:58 +08:00
|
|
|
|
2018-09-22 05:40:36 +08:00
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @dominance_failure() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2018-09-22 05:40:36 +08:00
|
|
|
"foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
|
2018-12-30 03:32:37 +08:00
|
|
|
br ^bb1
|
|
|
|
^bb1:
|
2018-09-27 22:43:44 +08:00
|
|
|
%x = "bar"() : () -> i32 // expected-note {{operand defined here}}
|
2018-09-22 05:40:36 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-10 03:28:58 +08:00
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @return_type_mismatch() -> i32 {
|
2018-08-10 03:28:58 +08:00
|
|
|
%0 = "foo"() : ()->f32
|
2019-05-25 10:22:00 +08:00
|
|
|
return %0 : f32 // expected-error {{type of return operand 0 ('f32') doesn't match function result type ('i32')}}
|
2018-08-10 03:28:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-02-09 01:52:26 +08:00
|
|
|
func @return_inside_loop() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 100 {
|
2019-03-27 20:11:58 +08:00
|
|
|
// expected-error@-1 {{op expects regions to end with 'affine.terminator'}}
|
|
|
|
// expected-note@-2 {{in custom textual format, the absence of terminator implies}}
|
2019-02-09 01:52:26 +08:00
|
|
|
return
|
2018-08-10 03:28:58 +08:00
|
|
|
}
|
2019-01-26 04:48:25 +08:00
|
|
|
return
|
2018-08-10 03:28:58 +08:00
|
|
|
}
|
2018-08-18 07:49:42 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @redef()
|
|
|
|
func @redef() // expected-error {{redefinition of function named 'redef'}}
|
2018-08-20 12:17:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @foo() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2018-08-20 12:17:22 +08:00
|
|
|
%x = constant @foo : (i32) -> () // expected-error {{reference to function with mismatched type}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @undefined_function() {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2018-08-20 12:17:22 +08:00
|
|
|
%x = constant @bar : (i32) -> () // expected-error {{reference to undefined function 'bar'}}
|
|
|
|
return
|
|
|
|
}
|
2018-08-25 14:38:14 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-02-06 03:47:02 +08:00
|
|
|
func @invalid_result_type() -> () -> () // expected-error {{expected a top level entity}}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2018-08-25 14:38:14 +08:00
|
|
|
#map1 = (i)[j] -> (i+j)
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @bound_symbol_mismatch(%N : index) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = #map1(%N) to 100 {
|
2019-02-02 08:42:18 +08:00
|
|
|
// expected-error@-1 {{symbol operand count and integer set symbol count must match}}
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
#map1 = (i)[j] -> (i+j)
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @bound_dim_mismatch(%N : index) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = #map1(%N, %N)[%N] to 100 {
|
2019-02-02 08:42:18 +08:00
|
|
|
// expected-error@-1 {{dim operand count and integer set dim count must match}}
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @large_bound() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 9223372036854775810 {
|
2019-02-02 08:42:18 +08:00
|
|
|
// expected-error@-1 {{integer constant out of range for attribute}}
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @max_in_upper_bound(%N : index) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to max (i)->(N, 100) { //expected-error {{expected non-function type}}
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @step_typo() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 100 step -- 1 { //expected-error {{expected constant integer}}
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_bound_map(%N : i32) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to (i)->(j)(%N) { //expected-error {{use of undeclared identifier}}
|
2018-08-25 14:38:14 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2018-08-29 06:26:20 +08:00
|
|
|
|
2019-01-15 01:45:09 +08:00
|
|
|
// -----
|
|
|
|
|
|
|
|
#set0 = (i)[N, M] : )i >= 0) // expected-error {{expected '(' at start of integer set constraint list}}
|
|
|
|
|
2018-08-29 06:26:20 +08:00
|
|
|
// -----
|
2018-10-26 09:33:42 +08:00
|
|
|
#set0 = (i)[N] : (i >= 0, N - i >= 0)
|
2018-08-29 06:26:20 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_operands1(%N : index) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if #set0(%i) {
|
2018-08-29 06:26:20 +08:00
|
|
|
// expected-error@-1 {{symbol operand count and integer set symbol count must match}}
|
|
|
|
|
|
|
|
// -----
|
2018-10-26 09:33:42 +08:00
|
|
|
#set0 = (i)[N] : (i >= 0, N - i >= 0)
|
2018-08-29 06:26:20 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_operands2(%N : index) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if #set0()[%N] {
|
2018-08-29 06:26:20 +08:00
|
|
|
// expected-error@-1 {{dim operand count and integer set dim count must match}}
|
|
|
|
|
|
|
|
// -----
|
2018-10-26 09:33:42 +08:00
|
|
|
#set0 = (i)[N] : (i >= 0, N - i >= 0)
|
2018-08-29 06:26:20 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @invalid_if_operands3(%N : index) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i = 1 to 10 {
|
2019-03-25 11:35:07 +08:00
|
|
|
affine.if #set0(%i)[%i] {
|
2019-01-29 13:23:53 +08:00
|
|
|
// expected-error@-1 {{operand cannot be used as a symbol}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2018-08-29 06:26:20 +08:00
|
|
|
|
2018-10-10 05:40:41 +08:00
|
|
|
// -----
|
|
|
|
// expected-error@+1 {{expected '"' in string literal}}
|
|
|
|
"J// -----
|
2019-01-03 02:20:00 +08:00
|
|
|
func @calls(%arg0: i32) {
|
2019-02-06 03:47:02 +08:00
|
|
|
// expected-error@+1 {{expected non-function type}}
|
2018-10-10 05:40:41 +08:00
|
|
|
%z = "casdasda"(%x) : (ppop32) -> i32
|
|
|
|
}
|
2018-10-14 22:55:29 +08:00
|
|
|
// -----
|
|
|
|
// expected-error@+2 {{expected SSA operand}}
|
2019-01-03 02:20:00 +08:00
|
|
|
func@n(){^b(
|
2018-10-14 22:55:29 +08:00
|
|
|
// -----
|
2018-10-19 04:54:44 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_non_tensor_type() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[4]> : i32} : () -> () // expected-error {{elements literal must be a ranked tensor or vector type}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_non_ranked() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[4]> : tensor<?xi32>} : () -> () // expected-error {{elements literal type must have static shape}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_shape_mismatch() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[4]> : tensor<5xi32>} : () -> () // expected-error {{inferred shape of elements literal ([1]) does not match type ([5])}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_invalid() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[4, [5]]> : tensor<2xi32>} : () -> () // expected-error {{tensor literal is invalid; ranks are not consistent between elements}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_badtoken() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[tf_opaque]> : tensor<1xi32>} : () -> () // expected-error {{expected element literal of primitive type}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_floattype1() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 07:06:13 +08:00
|
|
|
// expected-error@+1 {{expected integer elements, but parsed floating-point}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[4.0]> : tensor<1xi32>} : () -> ()
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-05 03:27:58 +08:00
|
|
|
func @elementsattr_floattype1() -> () {
|
|
|
|
^bb0:
|
2019-06-26 07:06:13 +08:00
|
|
|
// expected-error@+1 {{expected integer elements, but parsed floating-point}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<4.0> : tensor<i32>} : () -> ()
|
2019-01-05 03:27:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_floattype2() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 07:06:13 +08:00
|
|
|
// expected-error@+1 {{expected floating-point elements, but parsed integer}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[4]> : tensor<1xf32>} : () -> ()
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_toolarge1() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[777]> : tensor<1xi8>} : () -> () // expected-error {{integer constant out of range}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_toolarge2() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = dense<[-777]> : tensor<1xi8>} : () -> () // expected-error {{integer constant out of range}}
|
2018-10-19 04:54:44 +08:00
|
|
|
}
|
2018-10-24 04:44:04 +08:00
|
|
|
|
|
|
|
// -----
|
2019-01-15 05:18:34 +08:00
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_malformed_opaque() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = opaque<10, "0xQZz123"> : tensor<1xi8>} : () -> () // expected-error {{expected dialect namespace}}
|
2018-10-24 04:44:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @elementsattr_malformed_opaque1() -> () {
|
2018-12-30 03:32:37 +08:00
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = opaque<"", "0xQZz123"> : tensor<1xi8>} : () -> () // expected-error {{opaque string only contains hex digits}}
|
2019-02-12 14:51:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @elementsattr_malformed_opaque2() -> () {
|
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = opaque<"", "00abc"> : tensor<1xi8>} : () -> () // expected-error {{opaque string should start with '0x'}}
|
2019-02-12 14:51:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @elementsattr_malformed_opaque3() -> () {
|
|
|
|
^bb0:
|
2019-06-26 10:06:06 +08:00
|
|
|
"foo"(){bar = opaque<"t", "0xabc"> : tensor<1xi8>} : () -> () // expected-error {{no registered dialect with namespace 't'}}
|
2018-10-26 09:33:42 +08:00
|
|
|
}
|
2018-12-30 01:01:59 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @redundant_signature(%a : i32) -> () {
|
2019-06-04 00:43:22 +08:00
|
|
|
^bb0(%b : i32): // expected-error {{invalid block name in region with named arguments}}
|
2018-12-30 01:01:59 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @mixed_named_arguments(%a : i32,
|
2018-12-30 01:01:59 +08:00
|
|
|
f32) -> () {
|
|
|
|
// expected-error @-1 {{expected SSA identifier}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-03 02:20:00 +08:00
|
|
|
func @mixed_named_arguments(f32,
|
2018-12-30 01:01:59 +08:00
|
|
|
%a : i32) -> () { // expected-error {{expected type instead of SSA identifier}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-08 00:16:32 +08:00
|
|
|
// -----
|
|
|
|
|
|
|
|
// This used to crash the parser, but should just error out by interpreting
|
|
|
|
// `tensor` as operator rather than as a type.
|
|
|
|
func @f(f32) {
|
|
|
|
^bb0(%a : f32):
|
|
|
|
%18 = cmpi "slt", %idx, %idx : index
|
|
|
|
tensor<42 x index // expected-error {{custom op 'tensor' is unknown}}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-08 00:16:49 +08:00
|
|
|
// -----
|
|
|
|
|
|
|
|
func @f(%m : memref<?x?xf32>) {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i0 = 0 to 42 {
|
2019-01-08 00:16:49 +08:00
|
|
|
// expected-error@+1 {{operand #2 does not dominate this use}}
|
|
|
|
%x = load %m[%i0, %i1] : memref<?x?xf32>
|
|
|
|
}
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i1 = 0 to 42 {
|
2019-01-08 00:16:49 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2019-01-08 01:58:34 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-08 10:42:04 +08:00
|
|
|
func @dialect_type_empty_namespace(!<"">) -> () { // expected-error {{invalid type identifier}}
|
2019-01-08 01:58:34 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-05-16 00:10:52 +08:00
|
|
|
func @dialect_type_no_string_type_data(!foo<>) -> () { // expected-error {{expected string literal data in dialect symbol}}
|
2019-01-08 01:58:34 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-05-16 00:10:52 +08:00
|
|
|
func @dialect_type_missing_greater(!foo<"") -> () { // expected-error {{expected '>' in dialect symbol}}
|
2019-01-08 01:58:34 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-05-16 00:10:52 +08:00
|
|
|
func @type_alias_unknown(!unknown_alias) -> () { // expected-error {{undefined symbol alias id 'unknown_alias'}}
|
2019-01-08 01:58:34 +08:00
|
|
|
return
|
|
|
|
}
|
2019-01-08 10:42:04 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-04-06 10:36:42 +08:00
|
|
|
// expected-error @+1 {{type names with a '.' are reserved for dialect-defined names}}
|
|
|
|
!foo.bar = i32
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-01-08 10:42:04 +08:00
|
|
|
!missing_eq_alias type i32 // expected-error {{expected '=' in type alias definition}}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
!missing_kw_type_alias = i32 // expected-error {{expected 'type' in type alias definition}}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-02-06 03:47:02 +08:00
|
|
|
!missing_type_alias = type // expected-error@+2 {{expected non-function type}}
|
2019-01-08 10:42:04 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
!redef_alias = type i32
|
|
|
|
!redef_alias = type i32 // expected-error {{redefinition of type alias id 'redef_alias'}}
|
2019-01-12 01:03:34 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// Check ill-formed opaque tensor.
|
|
|
|
func @complex_loops() {
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i1 = 1 to 100 {
|
2019-01-12 01:03:34 +08:00
|
|
|
// expected-error @+1 {{expected '"' in string literal}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"opaqueIntTensor"(){bar = opaque<"", "0x686]> : tensor<2x1x4xi32>} : () -> ()
|
2019-01-12 02:30:40 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @mi() {
|
2019-04-02 01:01:47 +08:00
|
|
|
// expected-error @+1 {{expected element literal of primitive type}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"fooi64"(){bar = sparse<vector<1xi64>,[,[,1]
|
2019-01-12 03:23:15 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @invalid_tensor_literal() {
|
2019-04-02 01:01:47 +08:00
|
|
|
// expected-error @+1 {{expected 1-d tensor for values}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"foof16"(){bar = sparse<[[0, 0, 0]], [[-2.0]]> : vector<1x1x1xf16>} : () -> ()
|
2019-01-15 04:23:38 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @invalid_tensor_literal() {
|
2019-04-02 01:01:47 +08:00
|
|
|
// expected-error @+1 {{expected element literal of primitive type}}
|
2019-06-26 10:06:06 +08:00
|
|
|
"fooi16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0,, [[0, 0, 0]], [-2.0]> : tensor<2x2x2xi16>} : () -> ()
|
2019-01-15 05:56:59 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-02-02 16:07:30 +08:00
|
|
|
func @invalid_affine_structure() {
|
|
|
|
%c0 = constant 0 : index
|
2019-02-07 03:08:18 +08:00
|
|
|
%idx = affine.apply (d0, d1) (%c0, %c0) // expected-error {{expected '->' or ':'}}
|
2019-02-02 16:07:30 +08:00
|
|
|
return
|
|
|
|
}
|
2019-02-06 12:41:52 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @missing_for_max(%arg0: index, %arg1: index, %arg2: memref<100xf32>) {
|
|
|
|
// expected-error @+1 {{lower loop bound affine map with multiple results requires 'max' prefix}}
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i0 = ()[s]->(0,s-1)()[%arg0] to %arg1 {
|
2019-02-06 12:41:52 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @missing_for_min(%arg0: index, %arg1: index, %arg2: memref<100xf32>) {
|
|
|
|
// expected-error @+1 {{upper loop bound affine map with multiple results requires 'min' prefix}}
|
2019-03-26 01:14:34 +08:00
|
|
|
affine.for %i0 = %arg0 to ()[s]->(100,s+1)()[%arg1] {
|
2019-02-06 12:41:52 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2019-02-08 02:13:50 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{vector types must have positive constant sizes}}
|
|
|
|
func @zero_vector_type() -> vector<0xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{vector types must have positive constant sizes}}
|
|
|
|
func @zero_in_vector_type() -> vector<1x0xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected dimension size in vector type}}
|
|
|
|
func @negative_vector_size() -> vector<-1xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected non-function type}}
|
|
|
|
func @negative_in_vector_size() -> vector<1x-1xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected non-function type}}
|
|
|
|
func @negative_memref_size() -> memref<-1xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected non-function type}}
|
|
|
|
func @negative_in_memref_size() -> memref<1x-1xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected non-function type}}
|
|
|
|
func @negative_tensor_size() -> tensor<-1xi32>
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected non-function type}}
|
|
|
|
func @negative_in_tensor_size() -> tensor<1x-1xi32>
|
2019-02-27 02:07:27 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @invalid_nested_dominance() {
|
2019-05-06 16:40:13 +08:00
|
|
|
"foo.region"() ({
|
2019-02-27 02:07:27 +08:00
|
|
|
// expected-error @+1 {{operand #0 does not dominate this use}}
|
|
|
|
"foo.use" (%1) : (i32) -> ()
|
|
|
|
br ^bb2
|
|
|
|
|
|
|
|
^bb2:
|
|
|
|
// expected-note @+1 {{operand defined here}}
|
|
|
|
%1 = constant 0 : i32
|
|
|
|
"foo.yield" () : () -> ()
|
2019-05-06 16:40:13 +08:00
|
|
|
}) : () -> ()
|
2019-02-27 02:07:27 +08:00
|
|
|
return
|
|
|
|
}
|
2019-02-27 08:43:12 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-04-15 04:41:09 +08:00
|
|
|
// expected-error @+1 {{unbalanced ']' character in pretty dialect name}}
|
|
|
|
func @invalid_unknown_type_dialect_name() -> !invalid.dialect<!x@#]!@#>
|
2019-02-27 09:11:24 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{@ identifier expected to start with letter or '_'}}
|
|
|
|
func @$invalid_function_name()
|
2019-03-03 14:34:18 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{function arguments may only have dialect attributes}}
|
2019-06-26 10:06:06 +08:00
|
|
|
func @invalid_func_arg_attr(i1 {non_dialect_attr = 10})
|
2019-03-20 01:59:02 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected '<' in tuple type}}
|
|
|
|
func @invalid_tuple_missing_less(tuple i32>)
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected '>' in tuple type}}
|
|
|
|
func @invalid_tuple_missing_greater(tuple<i32)
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// Should not crash because of deletion order here.
|
|
|
|
func @invalid_region_dominance() {
|
|
|
|
"foo.use" (%1) : (i32) -> ()
|
2019-05-06 16:40:13 +08:00
|
|
|
"foo.region"() ({
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
%1 = constant 0 : i32 // This value is used outside of the region.
|
|
|
|
"foo.yield" () : () -> ()
|
2019-05-06 16:40:13 +08:00
|
|
|
}, {
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
// expected-error @+1 {{expected operation name in quotes}}
|
|
|
|
%2 = constant 1 i32 // Syntax error causes region deletion.
|
2019-05-06 16:40:13 +08:00
|
|
|
}) : () -> ()
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// Should not crash because of deletion order here.
|
|
|
|
func @invalid_region_block() {
|
|
|
|
"foo.branch"()[^bb2] : () -> () // Attempt to jump into the region.
|
|
|
|
|
|
|
|
^bb1:
|
2019-05-06 16:40:13 +08:00
|
|
|
"foo.region"() ({
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
^bb2:
|
|
|
|
"foo.yield"() : () -> ()
|
2019-05-06 16:40:13 +08:00
|
|
|
}, {
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
// expected-error @+1 {{expected operation name in quotes}}
|
|
|
|
%2 = constant 1 i32 // Syntax error causes region deletion.
|
2019-05-06 16:40:13 +08:00
|
|
|
}) : () -> ()
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// Should not crash because of deletion order here.
|
|
|
|
func @invalid_region_dominance() {
|
|
|
|
"foo.use" (%1) : (i32) -> ()
|
2019-05-06 16:40:13 +08:00
|
|
|
"foo.region"() ({
|
|
|
|
"foo.region"() ({
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
%1 = constant 0 : i32 // This value is used outside of the region.
|
|
|
|
"foo.yield" () : () -> ()
|
2019-05-06 16:40:13 +08:00
|
|
|
}) : () -> ()
|
|
|
|
}, {
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
// expected-error @+1 {{expected operation name in quotes}}
|
|
|
|
%2 = constant 1 i32 // Syntax error causes region deletion.
|
2019-05-06 16:40:13 +08:00
|
|
|
}) : () -> ()
|
Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent. It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions. It may be
necessary to work with the regions before the operation is created. In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions. Such regions are meant to own a list of
blocks and transfer them to other regions on demand.
Each instruction stores a fixed number of regions as trailing objects and has
ownership of them. This decreases the size of the Instruction object for the
common case of instructions without regions. Keep this behavior intact. To
allow some flexibility in construction, make OperationState store an owning
vector of regions. When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying. Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.
PiperOrigin-RevId: 240368183
2019-03-27 00:55:06 +08:00
|
|
|
return
|
|
|
|
}
|
2019-03-29 05:58:52 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-05-06 16:40:13 +08:00
|
|
|
func @unfinished_region_list() {
|
|
|
|
// expected-error@+1 {{expected ')' to end region list}}
|
|
|
|
"region"() ({},{},{} : () -> ()
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-03-29 05:58:52 +08:00
|
|
|
func @multi_result_missing_count() {
|
|
|
|
// expected-error@+1 {{expected integer number of results}}
|
|
|
|
%0: = "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @multi_result_zero_count() {
|
|
|
|
// expected-error@+1 {{expected named operation to have atleast 1 result}}
|
|
|
|
%0:0 = "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @multi_result_invalid_identifier() {
|
|
|
|
// expected-error@+1 {{expected valid ssa identifier}}
|
|
|
|
%0, = "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @multi_result_mismatch_count() {
|
2019-03-29 07:18:52 +08:00
|
|
|
// expected-error@+1 {{operation defines 2 results but was provided 1 to bind}}
|
2019-03-29 05:58:52 +08:00
|
|
|
%0:1 = "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @multi_result_mismatch_count() {
|
2019-03-29 07:18:52 +08:00
|
|
|
// expected-error@+1 {{operation defines 2 results but was provided 3 to bind}}
|
2019-03-29 05:58:52 +08:00
|
|
|
%0, %1, %3 = "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @no_result_with_name() {
|
|
|
|
// expected-error@+1 {{cannot name an operation with no results}}
|
|
|
|
%0 = "foo" () : () -> ()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @conflicting_names() {
|
2019-05-14 02:43:17 +08:00
|
|
|
// expected-note@+1 {{previously defined here}}
|
2019-03-29 05:58:52 +08:00
|
|
|
%foo, %bar = "foo" () : () -> (i32, i32)
|
|
|
|
|
|
|
|
// expected-error@+1 {{redefinition of SSA value '%bar'}}
|
|
|
|
%bar, %baz = "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
func @ssa_name_missing_eq() {
|
|
|
|
// expected-error@+1 {{expected '=' after SSA name}}
|
|
|
|
%0:2 "foo" () : () -> (i32, i32)
|
|
|
|
return
|
|
|
|
}
|
2019-03-30 13:23:34 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{invalid element type for complex}}
|
|
|
|
func @bad_complex(complex<memref<2x4xi8>>)
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected '<' in complex type}}
|
|
|
|
func @bad_complex(complex memref<2x4xi8>>)
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{expected '>' in complex type}}
|
|
|
|
func @bad_complex(complex<i32)
|
2019-05-28 23:57:38 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
// expected-error @+1 {{attribute names with a '.' are reserved for dialect-defined names}}
|
|
|
|
#foo.attr = i32
|
2019-06-04 00:43:22 +08:00
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-06-28 07:46:24 +08:00
|
|
|
// expected-error @+1 {{cannot parse type: i32 f32}}
|
|
|
|
func @bad_tuple(!spv.ptr<i32 f32, Uniform>)
|
|
|
|
|
|
|
|
// -----
|
|
|
|
|
2019-06-04 00:43:22 +08:00
|
|
|
func @invalid_region_dominance() {
|
|
|
|
"foo.region"() ({
|
|
|
|
// expected-error @+1 {{operand #0 does not dominate this use}}
|
|
|
|
"foo.use" (%def) : (i32) -> ()
|
|
|
|
"foo.yield" () : () -> ()
|
|
|
|
}, {
|
|
|
|
// expected-note @+1 {{operand defined here}}
|
|
|
|
%def = "foo.def" () : () -> i32
|
|
|
|
}) : () -> ()
|
|
|
|
return
|
|
|
|
}
|