rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.76k stars 12.65k forks source link

Redundant instructions involving indexing with `bool`s #123216

Open alion02 opened 6 months ago

alion02 commented 6 months ago

I tried this code:

fn f(a: u32, b: bool, c: bool, d: &mut [u128; 2]) {
    let mut a = a & 1 != 0;
    if b {
        a ^= c;
        d[0] |= 1;
    }
    d[a as usize] |= 1;
}

It compiles to the following assembly:

f:
        test    esi, esi
        je      .LBB0_1
        xor     dil, dl
        or      byte ptr [rcx], 1
        jmp     .LBB0_3
.LBB0_1:
        and     dil, 1
.LBB0_3:
        movzx   eax, dil
        and     eax, 1
        shl     eax, 4
        or      byte ptr [rcx + rax], 1
        ret

The jmp .LBB0_3 and and dil, 1 instructions are useless, because dil is moved to eax and anded with 1 there anyway, and dil is not used anywhere.

The output improves if you avoid using bools.

godbolt

Meta

rustc --version --verbose:

rustc 1.79.0-nightly (c9f8f3438 2024-03-27)
binary: rustc
commit-hash: c9f8f3438a8134a413aa5d4903e0196e44e37bbc
commit-date: 2024-03-27
host: x86_64-unknown-linux-gnu
release: 1.79.0-nightly
LLVM version: 18.1.2
Compiler returned: 0

@rustbot modify labels: -C-bug +C-optimization +A-codegen +A-LLVM +I-slow +I-heavy

clubby789 commented 4 days ago

This seems to be okay on current nightly:

f:
        test    esi, esi
        je      .LBB0_2
        xor     dil, dl
        or      byte ptr [rcx], 1
.LBB0_2:
        movzx   eax, dil
        and     eax, 1
        shl     eax, 4
        or      byte ptr [rcx + rax], 1
        ret