Closed
Description
While playing around with some complex numbers (structures with two f64
s), 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.
Minimal repro (also on play.rust-lang.org):
#[repr(align(16))]
pub struct Complex {
real: f64,
imag: f64,
}
pub struct Compound {
a: Complex,
}
pub fn load_unaligned(cmp: Compound) -> f64 {
let Complex { real, imag } = cmp.a;
(real * real) + (imag * imag)
}
pub fn load_aligned(cmp: Compound) -> f64 {
let cmp = cmp;
let Complex { real, imag } = cmp.a;
(real * real) + (imag * imag)
}
While the functions look nearly the same, the disassembly differs:
playground::load_unaligned:
; unaligned loads
movupd xmm1, xmmword ptr [rdi]
mulpd xmm1, xmm1
movapd xmm0, xmm1
movhlps xmm0, xmm0
addsd xmm0, xmm1
ret
playground::load_aligned:
; this one generates faster, aligned loads:
movapd xmm1, xmmword ptr [rdi]
mulpd xmm1, xmm1
movapd xmm0, xmm1
movhlps xmm0, xmm0
addsd xmm0, xmm1
ret
This bug occurs on stable 1.28, beta and nightly.