You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Rust generates unaligned loads when unpacking an aligned struct #54028
While playing around with some complex numbers (structures with two f64s), I noticed Rust was generating unaligned loads, so I added the #[repr(align(16))] parameter to them. But Rust was still generating unaligned operations.
I redeclared the parameter as a local variable, and it got fixed. It only seems to happen when using a pattern to unpack the fields of an aligned structure.
In the debug version of the LLVM IR, only the latter shows an explicit align 16. They both have dereferenceable(16) on the argument, but I think that's only size, not alignment.
Does it work as expected if instead of using #[repr(align(16))] you do this?
#[cfg(target_arch = "x86")]use std::arch::x86::__m128d as f64x2;#[cfg(target_arch = "x86_64")]use std::arch::x86_64::__m128d as f64x2;pubstructComplex{_dummy:[f64x2;0],real:f64,imag:f64,}
If so, then we could use vectors instead of integers for hinting higher alignments to LLVM, for both intra-struct/enum/union padding, and pointers without a LLVM pointee type.
I left a comment on #53998, about a potential change that would help here, I think. That is, we can be less conservative, and preserve knowledge of a higher alignment for struct field accesses.
cc @rust-lang/compiler Does anyone have opinions whether we should generate instructions with higher alignment, e.g. load f64 ... align 16, if we statically know that alignment is guaranteed, based on the field offset and the alignment of the struct? (e.g. offset 0 within 16-aligned struct)
We should strive to provide as much information to LLVM as possible. Telling LLVM about greatest alignment alignment of fields gives it extra information it can work with.
The interesting, and useful, scenario would be something like this:
#[repr(align(16))]
struct Foo {
// ...
field: PackedType, // Laid out at the offset 16.
}
#[packed] // so alignment = 1
struct PackedType { ... }
which would allow LLVM to use aligned SSE instructions for loading field.
Reacted by Gabriel Majeri, Eduard-Mihai Burtescu and Esteban Kuber
Activity
cuviper commentedon Sep 7, 2018
In the debug version of the LLVM IR, only the latter shows an explicit
align 16. They both havedereferenceable(16)on the argument, but I think that's only size, not alignment.GabrielMajeri commentedon Sep 8, 2018
I've been able to get an ever more minimal repro:
eddyb commentedon Sep 8, 2018
Does it work as expected if instead of using
#[repr(align(16))]you do this?If so, then we could use vectors instead of integers for hinting higher alignments to LLVM, for both intra-struct/enum/union padding, and pointers without a LLVM pointee type.
GabrielMajeri commentedon Sep 8, 2018
@eddyb No, unfortunately, still generates unaligned
movups(playground link for this version)eddyb commentedon Sep 8, 2018
I left a comment on #53998, about a potential change that would help here, I think. That is, we can be less conservative, and preserve knowledge of a higher alignment for struct field accesses.
cc @rust-lang/compiler Does anyone have opinions whether we should generate instructions with higher alignment, e.g.
load f64 ... align 16, if we statically know that alignment is guaranteed, based on the field offset and the alignment of the struct? (e.g. offset0within16-aligned struct)nagisa commentedon Sep 12, 2018
We should strive to provide as much information to LLVM as possible. Telling LLVM about greatest alignment alignment of fields gives it extra information it can work with.
The interesting, and useful, scenario would be something like this:
which would allow LLVM to use aligned SSE instructions for loading
field.Rely only on base alignment and offset for computing field alignment
Auto merge of #54547 - AstralSorcerer:issue-54028, r=eddyb