-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[mlir][llvm] Add zeroinitializer constant #65508
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
Conversation
This patch adds support for the zeroinitializer constant to LLVM dialect. It's meant to simplify zero-initialization of aggregate types in MLIR, although it can also be used with non-aggregate types.
The LLVM Dialect in MLIR, which the `mlir-llvm` team is supposed to provide notifications for, is 98% not nested in a directory called LLVM but rather LLVMIR. The former only contains some tests. This should make PRs such as llvm#65508 add the team as codeowner.
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 the very thorough testing!
I would nevertheless suggest to reduce the test set a bit :). After removing the typed pointers some tests will not have a lot of value (e.g. the function pointer test). Additionally, you do not need to check every type in the context of a global and in the context of a function.
After all we are mostly testing an LLVM function (if I understand correctly):
llvm::Constant::getNullValue($_resultType)
plus the type conversion applied to convert the result type. This type conversion should already be tested though.
I would suggest to keep some tests with global variables and some tests in the context of the function and using different types for all of them. Having some more complex aggregate type for sure is nice as well.
mlir/test/Target/LLVMIR/llvmir.mlir
Outdated
} | ||
// CHECK: @zero_struct = linkonce global { i32, double, i8 } zeroinitializer | ||
|
||
llvm.mlir.global linkonce @zero_ptr() : !llvm.ptr<i32> { |
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.
Can you avoid typed pointers and instead always use opaque pointers (opaque pointers don't have an element type and look as follows:
llvm.mlir.global linkonce @zero_ptr() : !llvm.ptr<i32> { | |
llvm.mlir.global linkonce @zero_ptr() : !llvm.ptr { |
LLVM does not have typed pointers anymore and MLIR is in a transition phase:
https://discourse.llvm.org/t/rfc-switching-the-llvm-dialect-and-dialect-lowerings-to-opaque-pointers/68179
We would thus like to avoid any new uses of typed pointers.
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.
Oh, nice. Wasn't aware of that. Typed pointers removed!
mlir/test/Target/LLVMIR/llvmir.mlir
Outdated
%local_integer = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr<i32> | ||
%1 = llvm.mlir.zero : i32 | ||
llvm.store %1, %local_integer : !llvm.ptr<i32> | ||
// CHECK: %[[#V1:]] = alloca i32, i64 1, align 4 | ||
// CHECK: store i32 0, ptr %[[#V1]], align 4 |
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.
%local_integer = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr<i32> | |
%1 = llvm.mlir.zero : i32 | |
llvm.store %1, %local_integer : !llvm.ptr<i32> | |
// CHECK: %[[#V1:]] = alloca i32, i64 1, align 4 | |
// CHECK: store i32 0, ptr %[[#V1]], align 4 | |
// CHECK: %[[#V1:]] = alloca i32, i64 1, align 4 | |
%local_integer = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr<i32> | |
%1 = llvm.mlir.zero : i32 | |
// CHECK: store i32 0, ptr %[[#V1]], align 4 | |
llvm.store %1, %local_integer : !llvm.ptr<i32> |
ultra nit: We usually prefer to put a file check comment right above the statement it matches. This interspersed view is a bit easier to read especially for larger tests.
One last comment. You may want to do add a short roundtrip test to test printing and parsing, similar to this one:
|
Thanks for the review!
I've reduced quite a bit (down to 2 tests only) since there was a lot of redundancy. |
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 the changes!
LGTM
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.
LGTM.
How does this relate to llvm.mlir.null
? Can we also initialize pointers with llvm.mlir.zero
and remove llvm.mlir.null
in favor of the more general operation?
} | ||
|
||
llvm.func @zeroinit_complex_local_aggregate() { | ||
// CHECK: %[[#VAR:]] = alloca [1000 x { i32, [3 x { double, <4 x ptr>, [2 x ptr] }], [6 x ptr] }], i64 1, align 32 |
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'm curious, how does %[[#VAR:]]
work? Usually, we are using %[[#VAR:.*]]
to capture the name.
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.
It's called FileCheck Numeric Substitution Blocks! The #
prefix enables it. It can be used to check more complex numeric relations, but it can also check basic numeric equalities.
That is a good point! I think that would be a nice cleanup that probably can be done in a follow up revision. |
The
Yes! On the builder side, it should behave exactly the same, since |
The LLVM Dialect in MLIR, which the `mlir-llvm` team is supposed to provide notifications for, is 98% not nested in a directory called LLVM but rather LLVMIR. The former only contains some tests. This should make PRs such as #65508 add the team as codeowner.
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.
@sitio-couto do you need one of use to merge this PR for you?
@zero9178 yes, please. It should auto-rebase without conflicts, but I can also rebase it manually if necessary. |
No worries, all good! I also tested it locally ontop of HEAD before merging |
This revision replaces the LLVM dialect NullOp by the recently introduced ZeroOp. The ZeroOp is more generic in the sense that it represents zero values of any LLVM type rather than null pointers only. This is a follow to llvm#65508
This revision replaces the LLVM dialect NullOp by the recently introduced ZeroOp. The ZeroOp is more generic in the sense that it represents zero values of any LLVM type rather than null pointers only. This is a follow to llvm#65508
This revision replaces the LLVM dialect NullOp by the recently introduced ZeroOp. The ZeroOp is more generic in the sense that it represents zero values of any LLVM type rather than null pointers only. This is a follow to #65508
This is not standard but is vastly expected by existing code. This was implemented by https://reviews.llvm.org/D149877 for simple scalars, but MLIR lacked a generic way to deal with aggregate types (arrays and derived type). Support was recently added in llvm#65508. Leverage it to zero initialize all types.
) This is not standard but is vastly expected by existing code. This was implemented by https://reviews.llvm.org/D149877 for simple scalars, but MLIR lacked a generic way to deal with aggregate types (arrays and derived type). Support was recently added in #65508. Leverage it to zero initialize all types.
…m#67693) This is not standard but is vastly expected by existing code. This was implemented by https://reviews.llvm.org/D149877 for simple scalars, but MLIR lacked a generic way to deal with aggregate types (arrays and derived type). Support was recently added in llvm#65508. Leverage it to zero initialize all types.
The LLVM Dialect in MLIR, which the `mlir-llvm` team is supposed to provide notifications for, is 98% not nested in a directory called LLVM but rather LLVMIR. The former only contains some tests. This should make PRs such as llvm/llvm-project#65508 add the team as codeowner.
This patch adds support for the zeroinitializer constant to LLVM dialect. It's meant to simplify zero-initialization of aggregate types in MLIR, although it can also be used with non-aggregate types.