Skip to content

[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

Merged
merged 3 commits into from
Sep 8, 2023

Conversation

sitio-couto
Copy link
Contributor

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.

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.
@sitio-couto sitio-couto requested a review from a team as a code owner September 6, 2023 17:52
@github-actions github-actions bot added the mlir label Sep 6, 2023
zero9178 added a commit to zero9178/llvm-project that referenced this pull request Sep 6, 2023
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.
Copy link
Contributor

@gysit gysit left a 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.

}
// CHECK: @zero_struct = linkonce global { i32, double, i8 } zeroinitializer

llvm.mlir.global linkonce @zero_ptr() : !llvm.ptr<i32> {
Copy link
Contributor

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:

Suggested change
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.

Copy link
Contributor Author

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!

Comment on lines 2360 to 2364
%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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%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.

@gysit
Copy link
Contributor

gysit commented Sep 6, 2023

One last comment. You may want to do add a short roundtrip test to test printing and parsing, similar to this one:

%0 = llvm.mlir.null : !llvm.ptr

@sitio-couto
Copy link
Contributor Author

Thanks for the review!

I would nevertheless suggest to reduce the test set a bit :)

I've reduced quite a bit (down to 2 tests only) since there was a lot of redundancy.

Copy link
Contributor

@gysit gysit left a 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

Copy link
Member

@ftynse ftynse left a 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
Copy link
Member

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.

Copy link
Contributor Author

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.

@gysit
Copy link
Contributor

gysit commented Sep 7, 2023

Can we also initialize pointers with llvm.mlir.zero and remove llvm.mlir.null in favor of the more general operation?

That is a good point! I think that would be a nice cleanup that probably can be done in a follow up revision.

@sitio-couto
Copy link
Contributor Author

How does this relate to llvm.mlir.null?

The llvm.mlir.zero is essentially more generic. It can work with most LLVM types (aggregate or not) as far as I tested.

Can we also initialize pointers with llvm.mlir.zero and remove llvm.mlir.null in favor of the more general operation?

Yes! On the builder side, it should behave exactly the same, since llvm::Constant::getNullValue will call llvm::ConstantPointerNull::get. But since llvm.mlir.null implies a pointer (e.g. return type is always a pointer), there might be API calls and passes that will have to be updated to work with the more generic llvm.mlir.zero op.

zero9178 added a commit that referenced this pull request Sep 7, 2023
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.
Copy link
Member

@zero9178 zero9178 left a 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?

@sitio-couto
Copy link
Contributor Author

Do you need one of us to merge this PR for you?

@zero9178 yes, please. It should auto-rebase without conflicts, but I can also rebase it manually if necessary.

@zero9178 zero9178 merged commit 01192a0 into llvm:main Sep 8, 2023
@zero9178
Copy link
Member

zero9178 commented Sep 8, 2023

Do you need one of us 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

gysit added a commit to gysit/llvm-project that referenced this pull request Sep 22, 2023
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
jeanPerier pushed a commit to jeanPerier/llvm-project that referenced this pull request Sep 25, 2023
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
gysit added a commit that referenced this pull request Sep 25, 2023
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
jeanPerier added a commit to jeanPerier/llvm-project that referenced this pull request Sep 28, 2023
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.
jeanPerier added a commit that referenced this pull request Sep 29, 2023
)

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.
legrosbuffle pushed a commit to legrosbuffle/llvm-project that referenced this pull request Sep 29, 2023
…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.
qihangkong pushed a commit to rvgpu/llvm that referenced this pull request Apr 18, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants