Skip to content

Rust generates unaligned loads when unpacking an aligned struct #54028

Closed
@GabrielMajeri

Description

@GabrielMajeri

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.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions