// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -verify-diagnostics
// Check different error cases.
func.func @bad_branch() {
^bb12:
cf.br ^missing // expected-error {{reference to an undefined block}}
}
// -----
func.func @block_redef() {
^bb42:
return
^bb42: // expected-error {{redefinition of block '^bb42'}}
return
}
// -----
func.func @no_terminator() { // expected-error {{empty block: expect at least a terminator}}
^bb40:
return
^bb41:
^bb42:
return
}
// -----
func.func @block_no_rparen() {
^bb42 (%bb42 : i32: // expected-error {{expected ')'}}
return
}
// -----
func.func @block_arg_no_ssaid() {
^bb42 (i32): // expected-error {{expected SSA operand}}
return
}
// -----
func.func @block_arg_no_type() {
^bb42 (%0): // expected-error {{expected ':' and type for SSA operand}}
return
}
// -----
func.func @block_arg_no_close_paren() {
^bb42:
cf.br ^bb2( // expected-error {{expected ':'}}
return
}
// -----
func.func @block_first_has_predecessor() {
// expected-error@-1 {{entry block of region may not have predecessors}}
^bb42:
cf.br ^bb43
^bb43:
cf.br ^bb42
}
// -----
func.func @no_return() {
%x = arith.constant 0 : i32
%y = arith.constant 1 : i32 // expected-error {{block with no terminator}}
}
// -----
func.func @no_terminator() {
cf.br ^bb1
^bb1:
%x = arith.constant 0 : i32
%y = arith.constant 1 : i32 // expected-error {{block with no terminator}}
}
// -----
func.func @no_block_arg_enclosing_parens() {
^bb %x: i32 : // expected-error {{expected ':' after block name}}
return
}
// -----
func.func @bad_op_type() {
^bb40:
"foo"() : i32 // expected-error {{expected function type}}
return
}
// -----
func.func @no_terminator() {
^bb40:
"foo"() : ()->()
""() : ()->() // expected-error {{empty operation name is invalid}}
return
}
// -----
func.func @non_operation() {
test.asd // expected-error {{custom op 'test.asd' is unknown}}
}
// -----
func.func @unknown_dialect_operation() {
// expected-error@below {{Dialect `foo' not found for custom op 'foo.asd'}}
// expected-note-re@below {{Registered dialects:{{.*}} test{{.*}}}}
foo.asd
}
// -----
func.func @non_operation() {
// expected-error@+1 {{custom op 'asd' is unknown (tried 'func.asd' as well)}}
asd
}
// -----
func.func @test() {
^bb40:
%1 = "foo"() : (i32)->i64 // expected-error {{expected 0 operand types but had 1}}
return
}
// -----
func.func @redef() {
^bb42:
%x = "xxx"(){index = 0} : ()->i32 // expected-note {{previously defined here}}
%x = "xxx"(){index = 0} : ()->i32 // expected-error {{redefinition of SSA value '%x'}}
return
}
// -----
func.func @undef() {
^bb42:
%x = "xxx"(%y) : (i32)->i32 // expected-error {{use of undeclared SSA value}}
return
}
// -----
func.func @malformed_type(%a : intt) { // expected-error {{expected non-function type}}
}
// -----
func.func @argError() {
^bb1(%a: i64): // expected-note {{previously defined here}}
cf.br ^bb2
^bb2(%a: i64): // expected-error{{redefinition of SSA value '%a'}}
return
}
// -----
func.func @br_mismatch() {
^bb0:
%0:2 = "foo"() : () -> (i1, i17)
// expected-error @+1 {{branch has 2 operands for successor #0, but target block has 1}}
cf.br ^bb1(%0#1, %0#0 : i17, i1)
^bb1(%x: i17):
return
}
// -----
func.func @succ_arg_type_mismatch() {
^bb0:
%0 = "getBool"() : () -> i1
// expected-error @+1 {{type mismatch for bb argument #0 of successor #0}}
cf.br ^bb1(%0 : i1)
^bb1(%x: i32):
return
}
// -----
func.func @condbr_notbool() {
^bb0:
%a = "foo"() : () -> i32 // expected-note {{prior use here}}
cf.cond_br %a, ^bb0, ^bb0 // expected-error {{use of value '%a' expects different type than prior uses: 'i1' vs 'i32'}}
}
// -----
func.func @condbr_badtype() {
^bb0:
%c = "foo"() : () -> i1
%a = "foo"() : () -> i32
cf.cond_br %c, ^bb0(%a, %a : i32, ^bb0) // expected-error {{expected non-function type}}
}
// -----
func.func @condbr_a_bb_is_not_a_type() {
^bb0:
%c = "foo"() : () -> i1
%a = "foo"() : () -> i32
cf.cond_br %c, ^bb0(%a, %a : i32, i32), i32 // expected-error {{expected block name}}
}
// -----
func.func @successors_in_non_terminator(%a : i32, %b : i32) {
%c = "arith.addi"(%a, %b)[^bb1] : () -> () // expected-error {{successors in non-terminator}}
^bb1:
return
}
// -----
func.func @undef() {
^bb0:
%x = "xxx"(%y) : (i32)->i32 // expected-error {{use of undeclared SSA value name}}
return
}
// -----
func.func @undef() {
%x = "xxx"(%y) : (i32)->i32 // expected-error {{use of undeclared SSA value name}}
return
}
// -----
func.func @duplicate_induction_var() {
affine.for %i = 1 to 10 { // expected-note {{previously referenced here}}
affine.for %i = 1 to 10 { // expected-error {{region entry argument '%i' is already in use}}
}
}
return
}
// -----
func.func @name_scope_failure() {
affine.for %i = 1 to 10 {
}
"xxx"(%i) : (index)->() // expected-error {{use of undeclared SSA value name}}
return
}
// -----
func.func @dominance_failure() {
^bb0:
"foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
cf.br ^bb1
^bb1:
%x = "bar"() : () -> i32 // expected-note {{operand defined here (op in the same region)}}
return
}
// -----
func.func @dominance_failure() {
^bb0:
"foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
%x = "bar"() : () -> i32 // expected-note {{operand defined here (op in the same block)}}
cf.br ^bb1
^bb1:
return
}
// -----
func.func @dominance_failure() {
"foo"() ({
"foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
}) : () -> ()
%x = "bar"() : () -> i32 // expected-note {{operand defined here (op in a parent region)}}
return
}
// -----
func.func @dominance_failure() { // expected-note {{operand defined as a block argument (block #1 in the same region)}}
^bb0:
cf.br ^bb1(%x : i32) // expected-error {{operand #0 does not dominate this use}}
^bb1(%x : i32):
return
}
// -----
func.func @dominance_failure() { // expected-note {{operand defined as a block argument (block #1 in a parent region)}}
^bb0:
%f = "foo"() ({
"foo"(%x) : (i32) -> () // expected-error {{operand #0 does not dominate this use}}
}) : () -> (i32)
cf.br ^bb1(%f : i32)
^bb1(%x : i32):
return
}
// -----
// expected-error@+1 {{expected three consecutive dots for an ellipsis}}
func.func @malformed_ellipsis_one(.)
// -----
// expected-error@+1 {{expected three consecutive dots for an ellipsis}}
func.func @malformed_ellipsis_two(..)
// -----
func.func private @redef() // expected-note {{see existing symbol definition here}}
func.func private @redef() // expected-error {{redefinition of symbol named 'redef'}}
// -----
func.func @calls(%arg0: i32) {
// expected-error@+1 {{expected non-function type}}
%z = "casdasda"(%x) : (ppop32) -> i32
}
// -----
// expected-error@+1 {{expected SSA operand}}
func.func @n(){^b(
// -----
// This used to crash the parser, but should just error out by interpreting
// `tensor` as operator rather than as a type.
func.func @f(f32) {
^bb0(%a : f32):
%18 = arith.cmpi slt, %idx, %idx : index
tensor<42 x index // expected-error {{custom op 'tensor' is unknown (tried 'func.tensor' as well)}}
return
}
// -----
func.func @f(%m : memref<?x?xf32>) {
affine.for %i0 = 0 to 42 {
// expected-note@+1 {{previously referenced here}}
%x = memref.load %m[%i0, %i1] : memref<?x?xf32>
}
// expected-error@+1 {{region entry argument '%i1' is already in use}}
affine.for %i1 = 0 to 42 {
}
return
}
// -----
func.func @dialect_type_empty_namespace(!<"">) -> () { // expected-error {{invalid type identifier}}
return
}
// -----
func.func @dialect_type_missing_greater(!foo<) -> () { // expected-error {{unbalanced '<' character in pretty dialect name}}
return
// -----
func.func @type_alias_unknown(!unknown_alias) -> () { // expected-error {{undefined symbol alias id 'unknown_alias'}}
return
}
// -----
// expected-error @+1 {{type names with a '.' are reserved for dialect-defined names}}
!foo.bar = i32
// -----
!missing_eq_alias i32 // expected-error {{expected '=' in type alias definition}}
// -----
!missing_type_alias = // expected-error {{expected non-function type}}
// -----
!redef_alias = i32
!redef_alias = i32 // expected-error {{redefinition of type alias id 'redef_alias'}}
// -----
func.func @invalid_nested_dominance() {
"test.ssacfg_region"() ({
// expected-error @+1 {{operand #0 does not dominate this use}}
"foo.use" (%1) : (i32) -> ()
cf.br ^bb2
^bb2:
// expected-note @+1 {{operand defined here}}
%1 = arith.constant 0 : i32
"foo.yield" () : () -> ()
}) : () -> ()
return
}
// -----
// expected-error @+1 {{unbalanced '<' character in pretty dialect name}}
func.func @invalid_unknown_type_dialect_name() -> !invalid.dialect<!x@#]!@#>
// -----
// expected-error @+1 {{expected '<' in tuple type}}
func.func @invalid_tuple_missing_less(tuple i32>)
// -----
// expected-error @+1 {{expected '>' in tuple type}}
func.func @invalid_tuple_missing_greater(tuple<i32)
// -----
// Should not crash because of deletion order here.
func.func @invalid_region_dominance() {
"foo.use" (%1) : (i32) -> ()
"foo.region"() ({
%1 = arith.constant 0 : i32 // This value is used outside of the region.
"foo.yield" () : () -> ()
}, {
// expected-error @+1 {{expected operation name in quotes}}
%2 = arith.constant 1 i32 // Syntax error causes region deletion.
}) : () -> ()
return
}
// -----
// Should not crash because of deletion order here.
func.func @invalid_region_block() {
"foo.branch"()[^bb2] : () -> () // Attempt to jump into the region.
^bb1:
"foo.region"() ({
^bb2:
"foo.yield"() : () -> ()
}, {
// expected-error @+1 {{expected operation name in quotes}}
%2 = arith.constant 1 i32 // Syntax error causes region deletion.
}) : () -> ()
}
// -----
// Should not crash because of deletion order here.
func.func @invalid_region_dominance() {
"foo.use" (%1) : (i32) -> ()
"foo.region"() ({
"foo.region"() ({
%1 = arith.constant 0 : i32 // This value is used outside of the region.
"foo.yield" () : () -> ()
}) : () -> ()
}, {
// expected-error @+1 {{expected operation name in quotes}}
%2 = arith.constant 1 i32 // Syntax error causes region deletion.
}) : () -> ()
return
}
// -----
func.func @unfinished_region_list() {
// expected-error@+1 {{expected ')' to end region list}}
"region"() ({},{},{} : () -> ()
}
// -----
func.func @multi_result_missing_count() {
// expected-error@+1 {{expected integer number of results}}
%0: = "foo" () : () -> (i32, i32)
return
}
// -----
func.func @multi_result_zero_count() {
// expected-error@+1 {{expected named operation to have at least 1 result}}
%0:0 = "foo" () : () -> (i32, i32)
return
}
// -----
func.func @multi_result_invalid_identifier() {
// expected-error@+1 {{expected valid ssa identifier}}
%0, = "foo" () : () -> (i32, i32)
return
}
// -----
func.func @multi_result_mismatch_count() {
// expected-error@+1 {{operation defines 2 results but was provided 1 to bind}}
%0:1 = "foo" () : () -> (i32, i32)
return
}
// -----
func.func @multi_result_mismatch_count() {
// expected-error@+1 {{operation defines 2 results but was provided 3 to bind}}
%0, %1, %3 = "foo" () : () -> (i32, i32)
return
}
// -----
func.func @no_result_with_name() {
// expected-error@+1 {{cannot name an operation with no results}}
%0 = "foo" () : () -> ()
return
}
// -----
func.func @conflicting_names() {
// expected-note@+1 {{previously defined here}}
%foo, %bar = "foo" () : () -> (i32, i32)
// expected-error@+1 {{redefinition of SSA value '%bar'}}
%bar, %baz = "foo" () : () -> (i32, i32)
return
}
// -----
func.func @ssa_name_missing_eq() {
// expected-error@+1 {{expected '=' after SSA name}}
%0:2 "foo" () : () -> (i32, i32)
return
}
// -----
// expected-error @+1 {{attribute names with a '.' are reserved for dialect-defined names}}
#foo.attr = i32
// -----
func.func @invalid_region_dominance() {
"test.ssacfg_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
}
// -----
func.func @invalid_region_dominance() {
// expected-note @+1 {{operand defined here}}
%def = "test.ssacfg_region"() ({
// expected-error @+1 {{operand #0 does not dominate this use}}
"foo.use" (%def) : (i32) -> ()
"foo.yield" () : () -> ()
}) : () -> (i32)
return
}
// -----
// expected-error @+1 {{unbalanced '<' character in pretty dialect name}}
func.func @bad_arrow(%arg : !unreg.ptr<(i32)->)
// -----
func.func @forward_reference_type_check() -> (i8) {
cf.br ^bb2
^bb1:
// expected-note @+1 {{previously used here with type 'i8'}}
return %1 : i8
^bb2:
// expected-error @+1 {{definition of SSA value '%1#0' has type 'f32'}}
%1 = "bar"() : () -> (f32)
cf.br ^bb1
}
// -----
func.func @dominance_error_in_unreachable_op() -> i1 {
%c = arith.constant false
return %c : i1
^bb0:
"test.ssacfg_region" () ({ // unreachable
^bb1:
// expected-error @+1 {{operand #0 does not dominate this use}}
%2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)
cf.br ^bb4
^bb2:
cf.br ^bb2
^bb4:
%1 = "foo"() : ()->i64 // expected-note {{operand defined here}}
}) : () -> ()
return %c : i1
}
// -----
func.func @invalid_region_dominance_with_dominance_free_regions() {
test.graph_region {
"foo.use" (%1) : (i32) -> ()
"foo.region"() ({
%1 = arith.constant 0 : i32 // This value is used outside of the region.
"foo.yield" () : () -> ()
}, {
// expected-error @+1 {{expected operation name in quotes}}
%2 = arith.constant 1 i32 // Syntax error causes region deletion.
}) : () -> ()
}
return
}
// -----
// expected-error@+1 {{expected valid attribute name}}
"t"(){""}
// -----
// This makes sure we emit an error at the end of the correct line, the : is
// expected at the end of foo, not on the return line.
func.func @error_at_end_of_line() {
// expected-error@+1 {{expected ':' followed by operation type}}
%0 = "foo"()
return
}
// -----
// This makes sure we emit an error at the end of the correct line, the : is
// expected at the end of foo, not on the return line.
func.func @error_at_end_of_line() {
%0 = "foo"()
// expected-error@-1 {{expected ':' followed by operation type}}
// This is a comment and so is the thing above.
return
}
// -----
// This makes sure we emit an error at the end of the correct line, the : is
// expected at the end of foo, not on the return line.
// This shows that it backs up to before the comment.
func.func @error_at_end_of_line() {
%0 = "foo"() // expected-error {{expected ':' followed by operation type}}
return
}
// -----
@foo // expected-error {{expected operation name in quotes}}