-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[mlir][llvm dialect] Verify element type of nested types #148975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[mlir][llvm dialect] Verify element type of nested types #148975
Conversation
@llvm/pr-subscribers-mlir Author: James Newling (newling) ChangesMove some tests from Target/LLVMIR/llvmir-invalid.mlir to Dialect/LLVMIR/invalid.mlir so that all tests of ConstantOp::verify() are in the same file. Full diff: https://github.com/llvm/llvm-project/pull/148975.diff 2 Files Affected:
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index bd1106e304c60..e5fe78c077314 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -439,6 +439,31 @@ llvm.func @scalable_vec_requires_splat() -> vector<[4]xf64> {
llvm.return %0 : vector<[4]xf64>
}
+
+// -----
+
+llvm.func @integer_with_float_type() -> f32 {
+ // expected-error @+1 {{expected integer type}}
+ %0 = llvm.mlir.constant(1 : index) : f32
+ llvm.return %0 : f32
+}
+
+// -----
+
+llvm.func @incompatible_float_attribute_type() -> f32 {
+ // expected-error @below{{expected float type of width 64}}
+ %cst = llvm.mlir.constant(1.0 : f64) : f32
+ llvm.return %cst : f32
+}
+
+// -----
+
+llvm.func @incompatible_integer_type_for_float_attr() -> i32 {
+ // expected-error @below{{expected integer type of width 16}}
+ %cst = llvm.mlir.constant(1.0 : f16) : i32
+ llvm.return %cst : i32
+}
+
// -----
func.func @insertvalue_non_llvm_type(%a : i32, %b : i32) {
diff --git a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
index a8ef401fff27e..6c7a218d0676e 100644
--- a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
@@ -55,30 +55,6 @@ llvm.func @struct_wrong_attribute_element_type() -> !llvm.struct<(f64, f64)> {
// -----
-llvm.func @integer_with_float_type() -> f32 {
- // expected-error @+1 {{expected integer type}}
- %0 = llvm.mlir.constant(1 : index) : f32
- llvm.return %0 : f32
-}
-
-// -----
-
-llvm.func @incompatible_float_attribute_type() -> f32 {
- // expected-error @below{{expected float type of width 64}}
- %cst = llvm.mlir.constant(1.0 : f64) : f32
- llvm.return %cst : f32
-}
-
-// -----
-
-llvm.func @incompatible_integer_type_for_float_attr() -> i32 {
- // expected-error @below{{expected integer type of width 16}}
- %cst = llvm.mlir.constant(1.0 : f16) : i32
- llvm.return %cst : i32
-}
-
-// -----
-
// expected-error @below{{LLVM attribute 'readonly' does not expect a value}}
llvm.func @passthrough_unexpected_value() attributes {passthrough = [["readonly", "42"]]}
|
@llvm/pr-subscribers-mlir-llvm Author: James Newling (newling) ChangesMove some tests from Target/LLVMIR/llvmir-invalid.mlir to Dialect/LLVMIR/invalid.mlir so that all tests of ConstantOp::verify() are in the same file. Full diff: https://github.com/llvm/llvm-project/pull/148975.diff 2 Files Affected:
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index bd1106e304c60..e5fe78c077314 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -439,6 +439,31 @@ llvm.func @scalable_vec_requires_splat() -> vector<[4]xf64> {
llvm.return %0 : vector<[4]xf64>
}
+
+// -----
+
+llvm.func @integer_with_float_type() -> f32 {
+ // expected-error @+1 {{expected integer type}}
+ %0 = llvm.mlir.constant(1 : index) : f32
+ llvm.return %0 : f32
+}
+
+// -----
+
+llvm.func @incompatible_float_attribute_type() -> f32 {
+ // expected-error @below{{expected float type of width 64}}
+ %cst = llvm.mlir.constant(1.0 : f64) : f32
+ llvm.return %cst : f32
+}
+
+// -----
+
+llvm.func @incompatible_integer_type_for_float_attr() -> i32 {
+ // expected-error @below{{expected integer type of width 16}}
+ %cst = llvm.mlir.constant(1.0 : f16) : i32
+ llvm.return %cst : i32
+}
+
// -----
func.func @insertvalue_non_llvm_type(%a : i32, %b : i32) {
diff --git a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
index a8ef401fff27e..6c7a218d0676e 100644
--- a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
@@ -55,30 +55,6 @@ llvm.func @struct_wrong_attribute_element_type() -> !llvm.struct<(f64, f64)> {
// -----
-llvm.func @integer_with_float_type() -> f32 {
- // expected-error @+1 {{expected integer type}}
- %0 = llvm.mlir.constant(1 : index) : f32
- llvm.return %0 : f32
-}
-
-// -----
-
-llvm.func @incompatible_float_attribute_type() -> f32 {
- // expected-error @below{{expected float type of width 64}}
- %cst = llvm.mlir.constant(1.0 : f64) : f32
- llvm.return %cst : f32
-}
-
-// -----
-
-llvm.func @incompatible_integer_type_for_float_attr() -> i32 {
- // expected-error @below{{expected integer type of width 16}}
- %cst = llvm.mlir.constant(1.0 : f16) : i32
- llvm.return %cst : i32
-}
-
-// -----
-
// expected-error @below{{LLVM attribute 'readonly' does not expect a value}}
llvm.func @passthrough_unexpected_value() attributes {passthrough = [["readonly", "42"]]}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for improving the verifiers!
I have added some small nit comments but otherwise looks good to go.
type = arrayType.getElementType(); | ||
if (auto vecType = dyn_cast<VectorType>(type)) | ||
return vecType.getElementType(); | ||
if (auto tenType = dyn_cast<TensorType>(type)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: the TensorType can be dropped. It is not a compatible LLVM type (see isCompatibleOuterType
) and since ConstantOp returns an LLVM type there should be no tensors here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the following fail to verify?
%0 = llvm.mlir.constant(dense<[1.0, 1.0]> : tensor<2xf64>) : vector<2xf64>
It currently roundtrips without issue.
Maybe what is confusing here is that I'm using this method to test both the attribute's element type as well the constant op's result's element type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have expected that we use:
%0 = llvm.mlir.constant(dense<[1.0, 1.0]> : vector<2xf64>) : vector<2xf64>
But if the tensor type shows up in the wild on the attribute then we can keep your version of the code.
if (!constantElementType.isInteger(floatWidth)) { | ||
return emitOpError() << "expected integer type of width " << floatWidth; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!constantElementType.isInteger(floatWidth)) { | |
return emitOpError() << "expected integer type of width " << floatWidth; | |
} | |
if (!constantElementType.isInteger(floatWidth)) | |
return emitOpError() << "expected integer type of width " << floatWidth; |
nit: for single line ifs we usually drop the braces
if (auto floatType = dyn_cast<FloatType>(attrElmType)) { | ||
return verifyFloatSemantics(floatType.getFloatSemantics(), resultElmType); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (auto floatType = dyn_cast<FloatType>(attrElmType)) { | |
return verifyFloatSemantics(floatType.getFloatSemantics(), resultElmType); | |
} | |
if (auto floatType = dyn_cast<FloatType>(attrElmType)) | |
return verifyFloatSemantics(floatType.getFloatSemantics(), resultElmType); |
nit: Same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a leftover?
llvm.return %0 : !llvm.struct<(f64, f64)> | ||
} | ||
|
||
// ----- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// ----- |
nit: one split can be dropped
// ----- | ||
|
||
llvm.func @int_attr_requires_int_type() -> f32 { | ||
// expected-error @+1 {{expected integer type}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// expected-error @+1 {{expected integer type}} | |
// expected-error @below {{expected integer type}} |
ulta nit: can you use below everywhere in the moved tests? It is preferred over @+1
@gysit Thank you for reviewing this! I think I have addressed your comments. The one I'm not sure about is the removal of TensorType from the new static function, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing the comment!
LGTM modulo some leftover nit.
I did one more search and realized that the tensor type is also used for llvm.array constants. That is actually a somewhat justified use case. Let's keep your current version of the code then!
if (auto floatType = dyn_cast<FloatType>(attrElmType)) { | ||
return verifyFloatSemantics(floatType.getFloatSemantics(), resultElmType); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a leftover?
Before this PR, this was valid
but this was not:
because only scalar types were checked for compatibility, not the element types of nested types.
Another additional check that this PR adds is to verify the float semantics. Before this PR,
was considered valid (because bf16 and f16 both have 16 bits), but with this PR it is not considered valid.
This PR also moves all tests on the verifier of the llvm constant op into a single file.
The total number of tests with this PR increases by 3.
To summarize the state after this PR. Valid:
Invalid:
Valid:
and identical valid/invalid cases for the scalar cases.