Open
Description
I tried this code in compiler explorer (https://rust.godbolt.org/z/W35vT4osM):
pub fn push1(v: &mut Vec<u32>, x: u32) {
v.reserve(1);
v.push(x);
}
pub fn push2(v: &mut Vec<u32>, x: u32) {
v.reserve(2);
v.push(x);
v.push(x);
}
I expected the generated assembly to only check the capacity once, and reallocate if needed, and then write the value. Instead, for each push
there is another check of remaining capacity and potential call to reserve_for_push
.
Adding explicit assume
calls leads to much shorter code with only a single call to do_reserve_and_handle
.
pub fn push2_assume(v: &mut Vec<u32>, x: u32) {
v.reserve(2);
unsafe {
core::intrinsics::assume(v.len() < v.capacity());
}
v.push(x);
unsafe {
core::intrinsics::assume(v.len() < v.capacity());
}
v.push(x);
}
This seems similar to #82801 but that issue seems specific to the initial vector capacity and code for that case looks ok now.
Meta
rustc --version --verbose
:
rustc 1.67.0-nightly (e0098a5cc 2022-11-29)
binary: rustc
commit-hash: e0098a5cc3a87d857e597af824d0ce1ed1ad85e0
commit-date: 2022-11-29
host: x86_64-unknown-linux-gnu
release: 1.67.0-nightly
LLVM version: 15.0.4
Compiler returned: 0