Previously, they would only only verify `isa<DictionaryAttr>` on such attrs which resulted in crashes down the line from code assuming that the verifier was doing the more thorough check introduced in this patch. The key change here is for StructAttr to use `CPred<"$_self.isa<" # name # ">()">` instead of `isa<DictionaryAttr>`. To test this, introduce struct attrs to the test dialect. Previously, StructAttr was only being tested by unittests/, which didn't verify how StructAttr interacted with ODS. Differential Revision: https://reviews.llvm.org/D78975
560 lines
16 KiB
MLIR
560 lines
16 KiB
MLIR
// RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test integer attributes
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @int_attrs_pass() {
|
|
"test.int_attrs"() {
|
|
// CHECK: any_i32_attr = 5 : ui32
|
|
any_i32_attr = 5 : ui32,
|
|
// CHECK-SAME: index_attr = 8 : index
|
|
index_attr = 8 : index,
|
|
// CHECK-SAME: si32_attr = 7 : si32
|
|
si32_attr = 7 : si32,
|
|
// CHECK-SAME: ui32_attr = 6 : ui32
|
|
ui32_attr = 6 : ui32
|
|
} : () -> ()
|
|
|
|
"test.int_attrs"() {
|
|
// CHECK: any_i32_attr = 5 : si32
|
|
any_i32_attr = 5 : si32,
|
|
index_attr = 8 : index,
|
|
si32_attr = 7 : si32,
|
|
ui32_attr = 6 : ui32
|
|
} : () -> ()
|
|
|
|
"test.int_attrs"() {
|
|
// CHECK: any_i32_attr = 5 : i32
|
|
any_i32_attr = 5 : i32,
|
|
index_attr = 8 : index,
|
|
si32_attr = 7 : si32,
|
|
ui32_attr = 6 : ui32
|
|
} : () -> ()
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Check that the maximum and minimum integer attribute values are
|
|
// representable and preserved during a round-trip.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @int_attrs_pass() {
|
|
"test.in_range_attrs"() {
|
|
// CHECK: attr_00 = -128 : i8
|
|
attr_00 = -128 : i8,
|
|
// CHECK-SAME: attr_01 = 127 : i8
|
|
attr_01 = 127 : i8,
|
|
// CHECK-SAME: attr_02 = -128 : si8
|
|
attr_02 = -128 : si8,
|
|
// CHECK-SAME: attr_03 = 127 : si8
|
|
attr_03 = 127 : si8,
|
|
// CHECK-SAME: attr_04 = 255 : ui8
|
|
attr_04 = 255 : ui8,
|
|
// CHECK-SAME: attr_05 = -32768 : i16
|
|
attr_05 = -32768 : i16,
|
|
// CHECK-SAME: attr_06 = 32767 : i16
|
|
attr_06 = 32767 : i16,
|
|
// CHECK-SAME: attr_07 = -32768 : si16
|
|
attr_07 = -32768 : si16,
|
|
// CHECK-SAME: attr_08 = 32767 : si16
|
|
attr_08 = 32767 : si16,
|
|
// CHECK-SAME: attr_09 = 65535 : ui16
|
|
attr_09 = 65535 : ui16,
|
|
// CHECK-SAME: attr_10 = -2147483647 : i32
|
|
attr_10 = -2147483647 : i32,
|
|
// CHECK-SAME: attr_11 = 2147483646 : i32
|
|
attr_11 = 2147483646 : i32,
|
|
// CHECK-SAME: attr_12 = -2147483647 : si32
|
|
attr_12 = -2147483647 : si32,
|
|
// CHECK-SAME: attr_13 = 2147483646 : si32
|
|
attr_13 = 2147483646 : si32,
|
|
// CHECK-SAME: attr_14 = 4294967295 : ui32
|
|
attr_14 = 4294967295 : ui32,
|
|
// CHECK-SAME: attr_15 = -9223372036854775808 : i64
|
|
attr_15 = -9223372036854775808 : i64,
|
|
// CHECK-SAME: attr_16 = 9223372036854775807 : i64
|
|
attr_16 = 9223372036854775807 : i64,
|
|
// CHECK-SAME: attr_17 = -9223372036854775808 : si64
|
|
attr_17 = -9223372036854775808 : si64,
|
|
// CHECK-SAME: attr_18 = 9223372036854775807 : si64
|
|
attr_18 = 9223372036854775807 : si64,
|
|
// CHECK-SAME: attr_19 = 18446744073709551615 : ui64
|
|
attr_19 = 18446744073709551615 : ui64,
|
|
// CHECK-SAME: attr_20 = 1 : ui1
|
|
attr_20 = 1 : ui1,
|
|
// CHECK-SAME: attr_21 = -1 : si1
|
|
attr_21 = -1 : si1,
|
|
// CHECK-SAME: attr_22 = 79228162514264337593543950335 : ui96
|
|
attr_22 = 79228162514264337593543950335 : ui96,
|
|
// CHECK-SAME: attr_23 = -39614081257132168796771975168 : si96
|
|
attr_23 = -39614081257132168796771975168 : si96
|
|
} : () -> ()
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Check that positive values larger than 2^n-1 for signless integers
|
|
// are mapped to their negative signed counterpart. This behaviour is
|
|
// undocumented in the language specification, but it is what the
|
|
// parser currently does.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @int_attrs_pass() {
|
|
"test.i8_attr"() {
|
|
// CHECK: attr_00 = -1 : i8
|
|
attr_00 = 255 : i8,
|
|
// CHECK-SAME: attr_01 = -1 : i16
|
|
attr_01 = 65535 : i16,
|
|
// CHECK-SAME: attr_02 = -1 : i32
|
|
attr_02 = 4294967295 : i32,
|
|
// CHECK-SAME: attr_03 = -1 : i64
|
|
attr_03 = 18446744073709551615 : i64
|
|
} : () -> ()
|
|
return
|
|
}
|
|
// -----
|
|
|
|
|
|
func @wrong_int_attrs_signedness_fail() {
|
|
// expected-error @+1 {{'si32_attr' failed to satisfy constraint: 32-bit signed integer attribute}}
|
|
"test.int_attrs"() {
|
|
any_i32_attr = 5 : i32,
|
|
index_attr = 8 : index,
|
|
si32_attr = 7 : ui32,
|
|
ui32_attr = 6 : ui32
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_int_attrs_signedness_fail() {
|
|
// expected-error @+1 {{'ui32_attr' failed to satisfy constraint: 32-bit unsigned integer attribute}}
|
|
"test.int_attrs"() {
|
|
any_i32_attr = 5 : i32,
|
|
index_attr = 8 : index,
|
|
si32_attr = 7 : si32,
|
|
ui32_attr = 6 : si32
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_int_attrs_type_fail() {
|
|
// expected-error @+1 {{'any_i32_attr' failed to satisfy constraint: 32-bit integer attribute}}
|
|
"test.int_attrs"() {
|
|
any_i32_attr = 5.0 : f32,
|
|
si32_attr = 7 : si32,
|
|
ui32_attr = 6 : ui32
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test Non-negative Int Attr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @non_negative_int_attr_pass() {
|
|
// CHECK: test.non_negative_int_attr
|
|
"test.non_negative_int_attr"() {i32attr = 5 : i32, i64attr = 10 : i64} : () -> ()
|
|
// CHECK: test.non_negative_int_attr
|
|
"test.non_negative_int_attr"() {i32attr = 0 : i32, i64attr = 0 : i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @negative_int_attr_fail() {
|
|
// expected-error @+1 {{'i32attr' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative}}
|
|
"test.non_negative_int_attr"() {i32attr = -5 : i32, i64attr = 10 : i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @negative_int_attr_fail() {
|
|
// expected-error @+1 {{'i64attr' failed to satisfy constraint: 64-bit signless integer attribute whose value is non-negative}}
|
|
"test.non_negative_int_attr"() {i32attr = 5 : i32, i64attr = -10 : i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test Positive Int Attr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @positive_int_attr_pass() {
|
|
// CHECK: test.positive_int_attr
|
|
"test.positive_int_attr"() {i32attr = 5 : i32, i64attr = 10 : i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @positive_int_attr_fail() {
|
|
// expected-error @+1 {{'i32attr' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive}}
|
|
"test.positive_int_attr"() {i32attr = 0 : i32, i64attr = 5: i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @positive_int_attr_fail() {
|
|
// expected-error @+1 {{'i64attr' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}}
|
|
"test.positive_int_attr"() {i32attr = 5 : i32, i64attr = 0: i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @positive_int_attr_fail() {
|
|
// expected-error @+1 {{'i32attr' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive}}
|
|
"test.positive_int_attr"() {i32attr = -10 : i32, i64attr = 5 : i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @positive_int_attr_fail() {
|
|
// expected-error @+1 {{'i64attr' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}}
|
|
"test.positive_int_attr"() {i32attr = 5 : i32, i64attr = -10 : i64} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test TypeArrayAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @correct_type_array_attr_pass() {
|
|
// CHECK: test.type_array_attr
|
|
"test.type_array_attr"() {attr = [i32, f32]} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @non_type_in_type_array_attr_fail() {
|
|
// expected-error @+1 {{'attr' failed to satisfy constraint: type array attribute}}
|
|
"test.type_array_attr"() {attr = [i32, 5 : i64]} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test StringAttr with custom type
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: func @string_attr_custom_type
|
|
func @string_attr_custom_type() {
|
|
// CHECK: "string_data" : !foo.string
|
|
test.string_attr_with_type "string_data" : !foo.string
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test StrEnumAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: func @allowed_cases_pass
|
|
func @allowed_cases_pass() {
|
|
// CHECK: test.str_enum_attr
|
|
%0 = "test.str_enum_attr"() {attr = "A"} : () -> i32
|
|
// CHECK: test.str_enum_attr
|
|
%1 = "test.str_enum_attr"() {attr = "B"} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @disallowed_case_fail() {
|
|
// expected-error @+1 {{allowed string cases: 'A', 'B'}}
|
|
%0 = "test.str_enum_attr"() {attr = 7: i32} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test I32EnumAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: func @allowed_cases_pass
|
|
func @allowed_cases_pass() {
|
|
// CHECK: test.i32_enum_attr
|
|
%0 = "test.i32_enum_attr"() {attr = 5: i32} : () -> i32
|
|
// CHECK: test.i32_enum_attr
|
|
%1 = "test.i32_enum_attr"() {attr = 10: i32} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @disallowed_case7_fail() {
|
|
// expected-error @+1 {{allowed 32-bit signless integer cases: 5, 10}}
|
|
%0 = "test.i32_enum_attr"() {attr = 7: i32} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @disallowed_case7_fail() {
|
|
// expected-error @+1 {{allowed 32-bit signless integer cases: 5, 10}}
|
|
%0 = "test.i32_enum_attr"() {attr = 5: i64} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test I64EnumAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: func @allowed_cases_pass
|
|
func @allowed_cases_pass() {
|
|
// CHECK: test.i64_enum_attr
|
|
%0 = "test.i64_enum_attr"() {attr = 5: i64} : () -> i32
|
|
// CHECK: test.i64_enum_attr
|
|
%1 = "test.i64_enum_attr"() {attr = 10: i64} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @disallowed_case7_fail() {
|
|
// expected-error @+1 {{allowed 64-bit signless integer cases: 5, 10}}
|
|
%0 = "test.i64_enum_attr"() {attr = 7: i64} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @disallowed_case7_fail() {
|
|
// expected-error @+1 {{allowed 64-bit signless integer cases: 5, 10}}
|
|
%0 = "test.i64_enum_attr"() {attr = 5: i32} : () -> i32
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test FloatElementsAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @correct_type_pass() {
|
|
"test.float_elements_attr"() {
|
|
// CHECK: scalar_f32_attr = dense<5.000000e+00> : tensor<2xf32>
|
|
// CHECK: tensor_f64_attr = dense<6.000000e+00> : tensor<4x8xf64>
|
|
scalar_f32_attr = dense<5.0> : tensor<2xf32>,
|
|
tensor_f64_attr = dense<6.0> : tensor<4x8xf64>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_element_type_pass() {
|
|
// expected-error @+1 {{failed to satisfy constraint: 32-bit float elements attribute of shape [2]}}
|
|
"test.float_elements_attr"() {
|
|
scalar_f32_attr = dense<5.0> : tensor<2xf64>,
|
|
tensor_f64_attr = dense<6.0> : tensor<4x8xf64>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @correct_type_pass() {
|
|
// expected-error @+1 {{failed to satisfy constraint: 64-bit float elements attribute of shape [4, 8]}}
|
|
"test.float_elements_attr"() {
|
|
scalar_f32_attr = dense<5.0> : tensor<2xf32>,
|
|
tensor_f64_attr = dense<6.0> : tensor<4xf64>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test StringElementsAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @simple_scalar_example() {
|
|
"test.string_elements_attr"() {
|
|
// CHECK: dense<"example">
|
|
scalar_string_attr = dense<"example"> : tensor<2x!unknown<"">>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @escape_string_example() {
|
|
"test.string_elements_attr"() {
|
|
// CHECK: dense<"new\0Aline">
|
|
scalar_string_attr = dense<"new\nline"> : tensor<2x!unknown<"">>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @simple_scalar_example() {
|
|
"test.string_elements_attr"() {
|
|
// CHECK: dense<["example1", "example2"]>
|
|
scalar_string_attr = dense<["example1", "example2"]> : tensor<2x!unknown<"">>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test SymbolRefAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @fn() { return }
|
|
|
|
// CHECK: test.symbol_ref_attr
|
|
"test.symbol_ref_attr"() {symbol = @fn} : () -> ()
|
|
|
|
// -----
|
|
|
|
// expected-error @+1 {{referencing to a 'FuncOp' symbol}}
|
|
"test.symbol_ref_attr"() {symbol = @foo} : () -> ()
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test IntElementsAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @correct_int_elements_attr_pass() {
|
|
"test.int_elements_attr"() {
|
|
// CHECK: any_i32_attr = dense<5> : tensor<1x2x3x4xui32>,
|
|
any_i32_attr = dense<5> : tensor<1x2x3x4xui32>,
|
|
i32_attr = dense<5> : tensor<6xi32>
|
|
} : () -> ()
|
|
|
|
"test.int_elements_attr"() {
|
|
// CHECK: any_i32_attr = dense<5> : tensor<1x2x3x4xsi32>,
|
|
any_i32_attr = dense<5> : tensor<1x2x3x4xsi32>,
|
|
i32_attr = dense<5> : tensor<6xi32>
|
|
} : () -> ()
|
|
|
|
"test.int_elements_attr"() {
|
|
// CHECK: any_i32_attr = dense<5> : tensor<1x2x3x4xi32>,
|
|
any_i32_attr = dense<5> : tensor<1x2x3x4xi32>,
|
|
i32_attr = dense<5> : tensor<6xi32>
|
|
} : () -> ()
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_int_elements_attr_type_fail() {
|
|
// expected-error @+1 {{'any_i32_attr' failed to satisfy constraint: 32-bit integer elements attribute}}
|
|
"test.int_elements_attr"() {
|
|
any_i32_attr = dense<5.0> : tensor<1x2x3x4xf32>,
|
|
i32_attr = dense<5> : tensor<6xi32>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_int_elements_attr_signedness_fail() {
|
|
// expected-error @+1 {{'i32_attr' failed to satisfy constraint: 32-bit signless integer elements attribute}}
|
|
"test.int_elements_attr"() {
|
|
any_i32_attr = dense<5> : tensor<1x2x3x4xi32>,
|
|
i32_attr = dense<5> : tensor<6xsi32>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test Ranked IntElementsAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
func @correct_type_pass() {
|
|
"test.ranked_int_elements_attr"() {
|
|
// CHECK: matrix_i64_attr = dense<6> : tensor<4x8xi64>
|
|
// CHECK: vector_i32_attr = dense<5> : tensor<2xi32>
|
|
matrix_i64_attr = dense<6> : tensor<4x8xi64>,
|
|
vector_i32_attr = dense<5> : tensor<2xi32>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_element_type_fail() {
|
|
// expected-error @+1 {{failed to satisfy constraint: 32-bit signless int elements attribute of shape [2]}}
|
|
"test.ranked_int_elements_attr"() {
|
|
matrix_i64_attr = dense<6> : tensor<4x8xi64>,
|
|
vector_i32_attr = dense<5> : tensor<2xi64>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_shape_fail() {
|
|
// expected-error @+1 {{failed to satisfy constraint: 64-bit signless int elements attribute of shape [4, 8]}}
|
|
"test.ranked_int_elements_attr"() {
|
|
matrix_i64_attr = dense<6> : tensor<4xi64>,
|
|
vector_i32_attr = dense<5> : tensor<2xi32>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @wrong_shape_fail() {
|
|
// expected-error @+1 {{failed to satisfy constraint: 32-bit signless int elements attribute of shape [2]}}
|
|
"test.ranked_int_elements_attr"() {
|
|
matrix_i64_attr = dense<6> : tensor<4x8xi64>,
|
|
vector_i32_attr = dense<5> : tensor<i32>
|
|
} : () -> ()
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Test StructAttr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// -----
|
|
|
|
func @missing_fields() {
|
|
// expected-error @+1 {{failed to satisfy constraint: DictionaryAttr with field(s): 'some_field', 'some_other_field' (each field having its own constraints)}}
|
|
"test.struct_attr"() {the_struct_attr = {}} : () -> ()
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
func @erroneous_fields() {
|
|
// expected-error @+1 {{failed to satisfy constraint: DictionaryAttr with field(s): 'some_field', 'some_other_field' (each field having its own constraints)}}
|
|
"test.struct_attr"() {the_struct_attr = {some_field = 1 : i8, some_other_field = 1}} : () -> ()
|
|
return
|
|
}
|
|
|