Skip to content

Missed optimization with slice::get_unchecked followed by <slice as Index>::index at a lower index #116878

Closed
@zachs18

Description

@zachs18

I tried this code:

pub unsafe fn cannot_elide_bounds_check(s: &[u8]) -> u8 {
    let a = *s.get_unchecked(1);
    a + s[0]
}
pub unsafe fn can_elide_bounds_check(s: &[u8]) -> u8 {
    let a = *s.get(1).unwrap_unchecked();
    a + s[0]
}

Compile with -Copt-level=3 on godbolt.org (godbolt link)

I expected to see this happen: Both functions should compile to approximately the same thing, with no bounds check on the s[0] since the optimizer should be able to see that the slice is at least of length 2 due to the previous unchecked indexing.

example::can_elide_bounds_check:
        movzx   eax, byte ptr [rdi]
        add     al, byte ptr [rdi + 1]
        ret

Instead, this happened: cannot_elide_bounds_check contains a bounds check (only can_elide_bounds_check does not contain a bounds check).

example::cannot_elide_bounds_check:
        test    rsi, rsi
        je      .LBB0_2
        movzx   eax, byte ptr [rdi]
        add     al, byte ptr [rdi + 1]
        ret
.LBB0_2:
        push    rax
        lea     rdx, [rip + .L__unnamed_1]
        xor     edi, edi
        xor     esi, esi
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2

Meta

rustc stable (1.73.0), nightly (2023-10-17), and 1.58.0 (when Option::unwrap_unchecked was stabilized) all have approximately the same codegen.
rustc --version --verbose:

rustc 1.75.0-nightly (09df6108c 2023-10-17)
binary: rustc
commit-hash: 09df6108c84fdec400043d99d9ee232336fd5a9f
commit-date: 2023-10-17
host: x86_64-unknown-linux-gnu
release: 1.75.0-nightly
LLVM version: 17.0.2

(no backtrace)

@rustbot label +C-optimization -C-bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchT-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