-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Fields should not alias Vec content. #71354
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
Comments
I think this would require making the The currently proposed aliasing model is Stacked Borrows, but so far it cannot handle |
There's the additional challenge that LLVM currently lacks a sound encoding (other than dropping the aliasing information entirely) of "scoped" noalias information other than |
AFAICT, example::foo:
push rax
mov rcx, qword ptr [rdi + 16]
cmp rcx, 3
jb .LBB5_2
mov rdx, qword ptr [rdi]
mov rax, qword ptr [rdx + 8*rcx - 8]
lea rsi, [rcx - 2]
mov qword ptr [rdi + 16], rsi
add rax, qword ptr [rdx + 8*rcx - 16]
pop rcx
ret
.LBB5_2:
call std::panicking::begin_panic
ud2 |
You're right, it does help. But AFAICT this is because it establishes that nothing can alias the Vec's fields. That doesn't help when the Vec isn't stored behind a mutable reference (e.g. it's a local and its address escapes) or if you need to know |
I remember discussing |
yeah it's been a longstanding issue but aiui there aren't any interesting insights beyond "yep sure would be nice if we could tell llvm about it". |
Here's an example of multiple vectors preventing optimization: pub fn foo(v: &mut Vec<usize>, k: &mut Vec<usize>) -> usize {
assert!(v.len() > 2 && k.len() > 2);
v[0] += 1;
k[0] += 1;
v[0] += 1;
k[0]
} and a local Vec who's address escapes: #[inline(never)]
fn black_box<T>(x: T) {
unsafe { std::ptr::read_volatile(&x); }
}
pub fn foo() -> usize {
let v = vec![1];
black_box(&v);
v[0]
} Neither is as optimized as Rust allows. |
I tried this code ( https://rust.godbolt.org/z/GuvQi9 ), which mutates a field while reading the content of a buffer.
Here the assertion is capable of removing the branches which are within the
pop
function, to make a branch-less function apart from the assertion code:However, the generated code still contains a spill of the
len
field of the vector for each pop-ed value which is used. The reason is that LLVM does not know whether the read type can alias or not the field which is being written to. This aliasing reason is inconsistent with the fact that thelen
field from which the value which is written back to memory is aliased in thercx
register.I would have expected the generated code to contain a single update of the
len
field, instead of 2.Testing with
-C opt-level=3
does not change the result.Meta
Tested with both
rustc --version --verbose
:and
edit: remove the
-Zmutable_noalias
as this seems to optimize this minimized test case. #71354 (comment)The text was updated successfully, but these errors were encountered: