Closed
Description
I tried this code:
#[repr(C)]
pub enum E {
A,
}
pub fn index(x: &[u32; 3], ind: E) -> u32{
x[ind as usize]
}
I expected to see this happen: no bounds check
Instead, this happened (with -C opt-level=3
)
example::index:
push rax
mov rax, rdi
mov edi, esi
cmp esi, 2
ja .LBB0_2
mov eax, dword ptr [rax + 4*rdi]
pop rcx
ret
.LBB0_2:
lea rdx, [rip + .L__unnamed_1]
mov esi, 3
call qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
ud2
However adding more variants to the enum makes the bound check go away:
#[repr(C)]
pub enum E {
A,
B,
}
pub fn index(x: &[u32; 3], ind: E) -> u32{
x[ind as usize]
}
generates:
example::index:
mov eax, esi
mov eax, dword ptr [rdi + 4*rax]
ret
Here's a godbolt link to play around further: https://rust.godbolt.org/z/dK9e1z
The MIR of the two cases is identical, but the llvm IR in ZST case is lacking @llvm.assume
, which I assume (heh!) leads to the bounds check being preserved. (However i don't actually understand LLVM, I'm just reading the diff...)
Meta
rustc 1.50.0
This sounds very closely related to #13926, but I'm not actually sure if it is. Please reroute as appropriate.