-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missed optimization opportunity when Vec::push follows Vec::pop #114334
Comments
I think there are two issues here:
The first issue can be fixed by adding https://godbolt.org/z/b5sc6T7ze (c++ reproducer, so it's not directly visible that the constraint elimination pass got improved) |
Thanks for investigating! Unfortunately your code is equivalent to this Rust code which gets correctly optimized (https://godbolt.org/z/s4ansTsaG): pub fn noop(v: &mut Vec<()>) {
if let Some(x) = v.pop() {
v.push(x)
}
} I'm not proficient in C++ but I'll try to find an example closer to Rust. |
This gets correctly optimized, I'll try a PR to add the assume to #![feature(core_intrinsics)]
use std::intrinsics::assume;
fn pop<T>(v: &mut Vec<T>) -> Option<T> {
let res = v.pop();
if res.is_some() {
unsafe {assume(v.len() < v.capacity());}
}
res
}
pub fn noop(v: &mut Vec<u8>) {
let tmp = pop(v);
match tmp {
Some(x) => v.push(x),
None => ()
}
} |
Just ran into #105156 which seems similar |
Also #82801 |
Add invariant to Vec::pop that len < cap if pop successful Fixes: rust-lang#114334
…cap, r=<try> Add invariant to VecDeque::pop_* that len < cap if pop successful Similar to rust-lang#114370 for VecDeque instead of Vec. I initially come from rust-itertools/itertools#899 where we noticed that `pop_front;push_back;` was slower than expected so `@scottmcm` suggested I file an issue which lead to https://internals.rust-lang.org/t/vecdeque-pop-front-push-back/20483 where **kornel** mentionned rust-lang#114334 (fixed by rust-lang#114370). This is my first time with codegen tests, I based the test on what was done for Vec.
…e_cap, r=Nilstrieb Add invariant to VecDeque::pop_* that len < cap if pop successful Similar to rust-lang#114370 for VecDeque instead of Vec. I initially come from rust-itertools/itertools#899 where we noticed that `pop_front;push_back;` was slower than expected so `@scottmcm` suggested I file an issue which lead to https://internals.rust-lang.org/t/vecdeque-pop-front-push-back/20483 where **kornel** mentionned rust-lang#114334 (fixed by rust-lang#114370). This is my first time with codegen tests, I based the test on what was done for Vec.
…e_cap, r=Nilstrieb Add invariant to VecDeque::pop_* that len < cap if pop successful Similar to rust-lang#114370 for VecDeque instead of Vec. I initially come from rust-itertools/itertools#899 where we noticed that `pop_front;push_back;` was slower than expected so `@scottmcm` suggested I file an issue which lead to https://internals.rust-lang.org/t/vecdeque-pop-front-push-back/20483 where **kornel** mentionned rust-lang#114334 (fixed by rust-lang#114370). This is my first time with codegen tests, I based the test on what was done for Vec.
Rollup merge of rust-lang#123089 - Philippe-Cholet:vecdeque_pop_assume_cap, r=Nilstrieb Add invariant to VecDeque::pop_* that len < cap if pop successful Similar to rust-lang#114370 for VecDeque instead of Vec. I initially come from rust-itertools/itertools#899 where we noticed that `pop_front;push_back;` was slower than expected so `@scottmcm` suggested I file an issue which lead to https://internals.rust-lang.org/t/vecdeque-pop-front-push-back/20483 where **kornel** mentionned rust-lang#114334 (fixed by rust-lang#114370). This is my first time with codegen tests, I based the test on what was done for Vec.
The following code
should be optimized to a no-op afaict, but instead gives:
(this is true on stable, beta and nightly).
I think a blocking point here is that rustc/LLVM do not manage to infer the invariant:
Note that the version with added asserts for this invariant removes the useless conditional call to
reserve_for_push
but instead gets useless calls to assert failure code.The text was updated successfully, but these errors were encountered: