Missed optimization: bounds checking if index is both subtracted and divided #134704
Open
Description
Take this code:
#[no_mangle]
pub fn example(arr: &[u32]) -> u32 {
let mut result = 0;
for i in 1..arr.len() {
result = arr[(i - 1) / 2];
}
result
}
If there was only a subtraction, the bounds check would be removed. Same if there was only a division (or a right shift).
But if there are both, it isn't:
example_1:
xor eax, eax
cmp rsi, 2
jb .LBB0_5
lea rcx, [rsi - 1]
xor edx, edx
.LBB0_2:
mov rax, rdx
shr rax
cmp rax, rsi
jae .LBB0_6
inc rdx
cmp rcx, rdx
jne .LBB0_2
mov eax, dword ptr [rdi + 4*rax]
.LBB0_5:
ret
.LBB0_6:
push rax
lea rdx, [rip + .L__unnamed_1]
mov rdi, rax
call qword ptr [rip + core::panicking::panic_bounds_check::he3703b517476def5@GOTPCREL]
Adding unsafe {assert_unchecked((i - 1) / 2 < i)};
fixes the issue.