return op.emitOpError("requires a 'value' attribute");
auto type = op.getType();
- if (type.isa<IntegerType>() || type.isIndex()) {
- auto intAttr = value.dyn_cast<IntegerAttr>();
- if (!intAttr)
- return op.emitOpError(
- "requires 'value' to be an integer for an integer result type");
+ if (type != value.getType())
+ return op.emitOpError() << "requires attribute's type (" << value.getType()
+ << ") to match op's return type (" << type << ")";
+ if (type.isa<IndexType>())
+ return success();
+
+ if (auto intAttr = value.dyn_cast<IntegerAttr>()) {
// If the type has a known bitwidth we verify that the value can be
// represented with the given bitwidth.
- if (!type.isIndex()) {
- auto bitwidth = type.cast<IntegerType>().getWidth();
- auto intVal = intAttr.getValue();
- if (!intVal.isSignedIntN(bitwidth) && !intVal.isIntN(bitwidth))
- return op.emitOpError(
- "requires 'value' to be an integer within the range "
- "of the integer result type");
- }
+ auto bitwidth = type.cast<IntegerType>().getWidth();
+ auto intVal = intAttr.getValue();
+ if (!intVal.isSignedIntN(bitwidth) && !intVal.isIntN(bitwidth))
+ return op.emitOpError("requires 'value' to be an integer within the "
+ "range of the integer result type");
return success();
}
return success();
}
- if (value.getType() != type)
- return op.emitOpError("requires the type of the 'value' attribute to match "
- "that of the operation result");
-
return op.emitOpError(
"requires a result type that aligns with the 'value' attribute");
}
func @constant() {
^bb:
- %x = "std.constant"(){value: "xyz"} : () -> i32 // expected-error {{'std.constant' op requires 'value' to be an integer for an integer result type}}
+ %x = "std.constant"(){value: "xyz"} : () -> i32 // expected-error {{requires attribute's type (none) to match op's return type (i32)}}
return
}
func @constant_out_of_range() {
^bb:
- %x = "std.constant"(){value: 100} : () -> i1 // expected-error {{'std.constant' op requires 'value' to be an integer within the range of the integer result type}}
+ %x = "std.constant"(){value: 100} : () -> i1 // expected-error {{requires attribute's type (i64) to match op's return type (i1)}}
return
}
// -----
+func @constant_wrong_type() {
+^bb:
+ %x = "std.constant"(){value: 10.} : () -> f32 // expected-error {{requires attribute's type (f64) to match op's return type (f32)}}
+ return
+}
+
+// -----
func @affine_apply_no_map() {
^bb0:
- %i = "std.constant"() {value: 0} : () -> index
+ %i = constant 0 : index
%x = "affine.apply" (%i) { } : (index) -> (index) // expected-error {{'affine.apply' op requires an affine map}}
return
}
func @affine_apply_wrong_operand_count() {
^bb0:
- %i = "std.constant"() {value: 0} : () -> index
+ %i = constant 0 : index
%x = "affine.apply" (%i) {map: (d0, d1) -> ((d0 + 1), (d1 + 2))} : (index) -> (index) // expected-error {{'affine.apply' op operand count and affine map dimension and symbol count must match}}
return
}
func @affine_apply_wrong_result_count() {
^bb0:
- %i = "std.constant"() {value: 0} : () -> index
- %j = "std.constant"() {value: 1} : () -> index
+ %i = constant 0 : index
+ %j = constant 1 : index
%x = "affine.apply" (%i, %j) {map: (d0, d1) -> ((d0 + 1), (d1 + 2))} : (index,index) -> (index) // expected-error {{'affine.apply' op mapping must produce one value}}
return
}
func @bad_alloc_wrong_dynamic_dim_count() {
^bb0:
- %0 = "std.constant"() {value: 7} : () -> index
+ %0 = constant 7 : index
// Test alloc with wrong number of dynamic dimensions.
%1 = alloc(%0)[%1] : memref<2x4xf32, (d0, d1)[s0] -> ((d0 + s0), d1), 1> // expected-error {{custom op 'alloc' dimension operand count does not equal memref dynamic dimension count}}
return
func @bad_alloc_wrong_symbol_count() {
^bb0:
- %0 = "std.constant"() {value: 7} : () -> index
+ %0 = constant 7 : index
// Test alloc with wrong number of symbols
%1 = alloc(%0) : memref<2x?xf32, (d0, d1)[s0] -> ((d0 + s0), d1), 1> // expected-error {{operand count does not equal dimension plus symbol operand count}}
return
func @test_store_zero_results() {
^bb0:
%0 = alloc() : memref<1024x64xf32, (d0, d1) -> (d0, d1), 1>
- %1 = "std.constant"() {value: 0} : () -> index
- %2 = "std.constant"() {value: 1} : () -> index
+ %1 = constant 0 : index
+ %2 = constant 1 : index
%3 = load %0[%1, %2] : memref<1024x64xf32, (d0, d1) -> (d0, d1), 1>
// Test that store returns zero results.
%4 = store %3, %0[%1, %2] : memref<1024x64xf32, (d0, d1) -> (d0, d1), 1> // expected-error {{cannot name an operation with no results}}
// -----
-func @func_constant() {
- %x = "std.constant"(){value: "xyz"} : () -> i32 // expected-error {{'std.constant' op requires 'value' to be an integer for an integer result type}}
- return
-}
-
-// -----
-
-func @func_constant_out_of_range() {
- %x = "std.constant"(){value: 100} : () -> i1 // expected-error {{'std.constant' op requires 'value' to be an integer within the range of the integer result type}}
- return
-}
-
-// -----
-
func @calls(%arg0: i32) {
%x = call @calls() : () -> i32 // expected-error {{reference to function with mismatched type}}
return
// CHECK:matched: {{.*}} constant splat{{.*}} with shape ratio: 1, 3, 7, 2, 1
%cst_a = constant splat<vector<1x3x7x8x8xf32>, 1.000000e+00> : vector<1x3x7x8x8xf32>
// CHECK-NOT:matched: {{.*}} constant splat{{.*}} with shape ratio: 1, 3, 7, 1{{.*}}
- %cst_b = constant splat<vector<1x3x7x4x4xf32>, 1.000000e+00> : vector<1x3x7x8x8xf32>
+ %cst_b = constant splat<vector<1x3x7x4x4xf32>, 1.000000e+00> : vector<1x3x7x4x4xf32>
// TEST-3x4x5x8:matched: {{.*}} constant splat{{.*}} with shape ratio: 3, 2, 1, 4
%cst_c = constant splat<vector<3x4x5x8xf32>, 1.000000e+00> : vector<3x4x5x8xf32>
// TEST-3x4x4x8-NOT:matched: {{.*}} constant splat{{.*}} with shape ratio{{.*}}
%c42 = constant 42 : index
%9 = load %2[%c7, %c42] : memref<?x?xf32>
return %9 : f32
-}
\ No newline at end of file
+}