Closed
Description
pub fn f(l: &Vec<u64>) -> u64 {
let mut sum = 0;
for i in 0..l.len() {
sum += l[i]
}
sum
}
Compiles with -C opt-level=3 -C panic=abort to:
example::f:
mov rdx, qword ptr [rdi + 16]
test rdx, rdx
je .LBB0_1
mov rcx, qword ptr [rdi]
xor eax, eax
xor esi, esi
.LBB0_4:
cmp rdx, rsi
jbe .LBB0_5
add rax, qword ptr [rcx + 8*rsi]
inc rsi
cmp rsi, rdx
jb .LBB0_4
jmp .LBB0_2
.LBB0_1:
xor eax, eax
.LBB0_2:
ret
.LBB0_5:
push rbp
mov rbp, rsp
lea rdi, [rip + panic_bounds_check_loc.1]
call core::panicking::panic_bounds_check@PLT
ud2
It should be possible for the bounds check to be dropped.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
arielb1 commentedon Dec 21, 2017
This looks like a pass ordering issue - GVN is needed to simplify the double load, while IndVarSimplify is needed to eliminate the bounds check, while GVN occurs only after IndVarSimplify.
see e.g. http://lists.llvm.org/pipermail/llvm-dev/2013-October/067045.html
arielb1 commentedon Dec 21, 2017
Minimal example - I suppose the identical C code has the same problem.
Nothing but GVN can optimize loads across basic blocks, and nothing but indvars (I think) can fix up bounds checks.
Maybe there's another bounds check removal pass we can run later in the pipeline.
AndrewGaspar commentedon Dec 21, 2017
Assuming this is nightly, I believe I also ran into this regression. https://users.rust-lang.org/t/surprising-auto-vectorization-optimization-behavior/14537
alexcrichton commentedon Feb 10, 2018
I believe this was fixed by #47828