Skip to content

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

@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