Open
Description
Compiler Explorer link: https://godbolt.org/z/KMTfY18Wf
I tried this code:
pub fn zero(d: &mut [Vec<i32>]) {
let n = d.len();
for i in 0..n {
assert!(d[i].len() == n);
for j in 0..n {
d[i][j] = 0;
}
}
}
With -C llvm-args=-enable-constraint-elimination
, I expected the bound checks to be optimized out as they're performed manually by assert!
. However, both assert and bound checks were present in the compiled code. The inner loop looks really dumb in terms of code generation:
.LBB0_5:
cmp rsi, rdx
je .LBB0_9
mov dword ptr [rcx + 4*rdx], 0
add rdx, 1
cmp rsi, rdx
jne .LBB0_5
rsi != rdx
is the loop invariant, but it's verified on each iteration.
At first I suspected the issue to be entirely on the LLVM side, but bound checks are omitted in equivalent C++ code (which is also present at the Compiler Explorer link), and the whole inner loop is replaced with a single memset
call.
Meta
rustc --version --verbose
:
rustc 1.58.0-nightly (a77da2d45 2021-11-19)
binary: rustc
commit-hash: a77da2d454e6caa227a85b16410b95f93495e7e0
commit-date: 2021-11-19
host: x86_64-unknown-linux-gnu
release: 1.58.0-nightly
LLVM version: 13.0.0