-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Initializing structs with Option fields set to None
produces non-optimal assembly
#104290
Comments
@rustbot label +A-codegen +I-slow |
I investigated this issue a bit a few weeks ago but never got around to reporting it. It reproduces with #include <cstdint>
struct WithPadding {
uint8_t a;
uint16_t b;
};
void foo(WithPadding* p) {
*p = {1, 2}; // Two `mov`s
}
void bar(WithPadding* p) {
WithPadding t = {1, 2};
*p = t; // One `mov`
} AFAICT the issue is that early on in the optimization pipeline LLVM sees Here is a smaller Rust repro (https://godbolt.org/z/xohrPs1rT): pub fn with_hole(x: &mut [Option<u8>; 2]) {
*x = [None, Some(2)]; // Two `mov`s
}
pub fn one_word(x: &mut [Option<u8>; 2]) {
*x = [Some(1), Some(2)]; // One `mov`
} |
The two issues are
The second issue can be easily fixed, but inserting a |
In 1.83, these now generate the same code, with 8 repeated |
I'm not sure if this is the same or related - I saw unexpected poor performance in my application when initializing a large array of
I would hope that both cases compile to memset. |
Treat undef bytes as equal to any other byte Basically since `undef` can be any byte, it can also be the byte(s) that are in the non-undef parts of a value. So we can just treat the `undef` at not being there and only look at the initialized bytes and memset over them fixes rust-lang#104290 based on rust-lang#135258
Treat undef bytes as equal to any other byte Basically since `undef` can be any byte, it can also be the byte(s) that are in the non-undef parts of a value. So we can just treat the `undef` at not being there and only look at the initialized bytes and memset over them fixes rust-lang#104290 based on rust-lang#135258
codegen: store ScalarPair via memset when one side is undef and the other side can be memset Basically since `undef` can be any byte, it can also be the byte(s) that are in the non-undef parts of a value. So we can just treat the `undef` at not being there and only look at the initialized bytes and memset over them fixes rust-lang#104290 based on rust-lang#135258
Given a struct
S
like this:Initializing this struct with all fields set to
None
, gives non-optimal assembly code, as LLVM doesn't combine the stores into a memset, because theu8
fields within theOption
fields are not set. Initializing all fields toSome(0)
and then overwriting them withNone
gives optimal results.Gives
The text was updated successfully, but these errors were encountered: