rust-lang / rust-lang/rust

Missed optimization: comparing array to zero is not vectorized

Open
#142,710 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-LLVM C-bug C-optimization I-slow
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I compiled this code with -Copt-level=3 -Ctarget-cpu=raptorlake:

pub fn a0(x: [u8; 64]) -> bool {
    x == [0; 64]
}
pub fn b0(x: [u8; 64]) -> bool {
    x.iter().all(|&y| y == 0)
}

pub fn a1(x: [u8; 64]) -> bool {
    x == [255; 64]
}
pub fn b1(x: [u8; 64]) -> bool {
    x.iter().all(|&y| y == 255)
}

I expected all four functions to be vectorized. Instead, b0, a1, and b1 are vectorized, but a0 is not vectorized.

Generated assembly
example::a0::h0c5a938daa1dd8cf:
        mov     rax, qword ptr [rdi + 24]
        mov     rcx, qword ptr [rdi]
        mov     rdx, qword ptr [rdi + 16]
        or      rdx, qword ptr [rdi + 48]
        mov     rsi, qword ptr [rdi + 8]
        or      rcx, qword ptr [rdi + 32]
        or      rcx, rdx
        or      rax, qword ptr [rdi + 56]
        or      rsi, qword ptr [rdi + 40]
        or      rsi, rax
        or      rsi, rcx
        sete    al
        ret

example::b0::he89db7fcb6c0c0f1:
        vmovdqu ymm0, ymmword ptr [rdi + 32]
        vpor    ymm0, ymm0, ymmword ptr [rdi]
        vptest  ymm0, ymm0
        sete    al
        vzeroupper
        ret

example::a1::h00de82c55f406ff7:
        vmovdqu ymm0, ymmword ptr [rdi]
        vpand   ymm0, ymm0, ymmword ptr [rdi + 32]
        vpcmpeqd        ymm1, ymm1, ymm1
        vptest  ymm0, ymm1
        setb    al
        vzeroupper
        ret

example::b1::h06b133df359bb172:
        vmovdqu ymm0, ymmword ptr [rdi + 32]
        vpand   ymm0, ymm0, ymmword ptr [rdi]
        vpcmpeqd        ymm1, ymm1, ymm1
        vptest  ymm0, ymm1
        setb    al
        vzeroupper
        ret

Godbolt link

Meta

Rust 1.87.0 on Godbolt.

@rustbot labels +C-optimization

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the four functions from the issue with Rust 1.87.0, -Copt-level=3, and -Ctarget-cpu=raptorlake, then compare their output on Godbolt using the linked example. Trace the compiler path for array equality and zero-value comparisons; done means a0 receives vectorized output comparable to b0 while preserving the reported behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.