-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Store bools as i8 in scalar pairs #51566
Conversation
Rust `bool` mostly uses the LLVM `i1` type for immediate values, and `i8` for memory storage, including most aggregates. Scalar pairs were an exception, also using `i1`, but this can cause problems when it is accessed through a pointer to the pair. This patch changes to use the memory type for scalar pairs too. Function argument pairs (`PassMode::Pair`) pass their pieces like distinct direct arguments, so for this case we explicitly convert `bool` to an immediate `i1` type again. This way the function can still optimize knowing the valid `0..2` range of `bool` values. Previously, `bool`-like enum tags were excluded from scalar pairs, because the `i1` didn't optimize well. Now that we're using `i8`, optimization seems fine with this, at least for the repeat-trusted-len test that was reportedly problematic before.
So this already is more complicated than what I did, but if LLVM is still bad at it... might as well. However, this is still not enough: This should thankfully be easier nowadays, I believe part of why I didn't do it was the pre-miri LLVM constant creation. |
I wonder how hard it would be to teach SROA about |
@eddyb - Can you be more specific about what changes you'd like to see here? I'm not sure how to represent the difference you state between the sort-of "immediate" mode and the LLVM aggregate type. @nox Sure, upstream LLVM improvements would be great, but for a while at least we have to worry about some older LLVM too. (It might be about time to consider raising from 3.9 though -- maybe 5?) FWIW, that particular aarch64 GlobalIsel bug in #50516 was filed as LLVM bug 37393 and appears to be fixed in trunk, but I'm told that this would not be straightforward to backport. |
@cuviper |
OK, thanks, I'll see if I can figure that out. |
Marked as blocked on #51583. |
Store scalar pair bools as i8 in memory We represent `bool` as `i1` in a `ScalarPair`, unlike other aggregates, to optimize IR for checked operators and the like. With this patch, we still do so when the pair is an immediate value, but we use the `i8` memory type when the value is loaded or stored as an LLVM aggregate. So `(bool, bool)` looks like an `{ i1, i1 }` immediate, but `{ i8, i8 }` in memory. When a pair is a direct function argument, `PassMode::Pair`, it is still passed using the immediate `i1` type, but as a return value it will use the `i8` memory type. Also, `bool`-like` enum tags will now use scalar pairs when possible, where they were previously excluded due to optimization issues. Fixes #51516. Closes #51566. r? @eddyb cc @nox
Rust
bool
mostly uses the LLVMi1
type for immediate values, andi8
for memory storage, including most aggregates. Scalar pairs werean exception, also using
i1
, but this can cause problems when it isaccessed through a pointer to the pair. This patch changes to use the
memory type for scalar pairs too.
Function argument pairs (
PassMode::Pair
) pass their pieces likedistinct direct arguments, so for this case we explicitly convert
bool
to an immediate
i1
type again. This way the function can stilloptimize knowing the valid
0..2
range ofbool
values.Previously,
bool
-like enum tags were excluded from scalar pairs,because the
i1
didn't optimize well. Now that we're usingi8
,optimization seems fine with this, at least for the repeat-trusted-len
test that was reportedly problematic before.
Fixes #50516.
r? @eddyb