Skip to content

Rust should pass vectors by vector register #93490

Closed
@Miksel12

Description

@Miksel12

Rust currently doesn't pass vectors of floats by vector register.

This should be able to be passed by vector registers:

pub struct Stats { x: f32, y: f32, z: f32, q: f32  }


pub fn sum_rust(a: &Stats, b: &Stats) -> Stats {
    return Stats {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z, q: a.q + b.q };
}

But in Rust 1.47 it uses the stack:

example::sum_rust:
        mov     rax, rdi
        movups  xmm0, xmmword ptr [rsi]
        movups  xmm1, xmmword ptr [rdx]
        addps   xmm1, xmm0
        movups  xmmword ptr [rdi], xmm1
        ret

Post 1.47, it is packed into integer registers (see this issue: #85265):

example::sum_rust:
        movss   xmm0, dword ptr [rdi]
        movss   xmm1, dword ptr [rdi + 4]
        addss   xmm0, dword ptr [rsi]
        addss   xmm1, dword ptr [rsi + 4]
        movsd   xmm2, qword ptr [rdi + 8]
        movsd   xmm3, qword ptr [rsi + 8]
        addps   xmm3, xmm2
        movd    eax, xmm0
        movd    ecx, xmm1
        movd    esi, xmm3
        shufps  xmm3, xmm3, 229
        movd    edx, xmm3
        shl     rdx, 32
        or      rdx, rsi
        shl     rcx, 32
        or      rax, rcx
        ret

This issue should be fixed by #93405 and should bring it back to pre 1.48.
But ideally it should be optimized to:

example::sum_rust:
        addps   xmm1, xmm0
        ret

@dotdash mentions in #85265 that this is due to Rust not using the proper types on the LLVM IR level: #85265 (comment)

EDIT:
Clang is able to use this optimization in a similar case:

struct Foo
{
    float bar1;
    float bar2;
    float bar3;
    float bar4;
};

Foo sum_cpp(Foo foo1, Foo foo2)
{
    Foo foo3;
    foo3.bar1 = foo1.bar1 + foo2.bar1;
    foo3.bar2 = foo1.bar2 + foo2.bar2;
    foo3.bar3 = foo1.bar3 + foo2.bar3;
    foo3.bar4 = foo1.bar4 + foo2.bar4;
    return foo3;
}

Gets turned into:

sum_cpp(Foo, Foo):                       # @sum_cpp(Foo, Foo)
        addps   xmm0, xmm2
        addps   xmm1, xmm3
        ret

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions