-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Unobservable vec, and arrays writes always always emit for size >= 3 #96497
Comments
For I believe we should be adding a (Note that For It appears to be failing here because we conditionally call For the simplified case of %6 = shl i64 %1, 2
%7 = icmp eq i64 %6, 0 This is doing something like The store is optimized out for Despite this, it's still not optimized out for |
Is there any way that LLVM could be informed unsafe {
if !(x.len() <= x.capacity()) {
std::hint::unreachable_unchecked();
}
} to |
Yeah, that would likely work, or equivalently |
I'm working on this, should be straightforward to use unchecked multiplication in that size calculation |
…rochenkov Use unchecked mul to compute slice sizes This allows LLVM to realize that `slice.len() > 0` iff `slice.len() * size_of::<T>() > 0`, allowing a branch on the latter to be folded into the former when dropping vecs and boxed slices, in some cases. Fixes (partially) rust-lang#96497
…rochenkov Use unchecked mul to compute slice sizes This allows LLVM to realize that `slice.len() > 0` iff `slice.len() * size_of::<T>() > 0`, allowing a branch on the latter to be folded into the former when dropping vecs and boxed slices, in some cases. Fixes (partially) rust-lang#96497
For the case of A more viable option would be to add an attribute to upstream LLVM, like However this is a bit less important now than when this issue was first opened, since MIR DSE is now able to remove dead stores in some cases, including the simple motivating case for This is still a problem when the argument is directly overwritten though (https://rust.godbolt.org/z/G3odYbq78), e.g. pub fn example_f(mut x: String) {
x = "foo".to_string(); // this still writes to memory in the caller's stack frame
} |
Ah, is this the only thing still inhibiting optimization of more complicated cases/situations regarding dead code / dead stores? It does seem correct that the lifetime of the argument copy has ended within the function, yet I saw it mentioned in the PR that inlining caused complications with that?
Ouch, well.. this does impact arrays of Move-only types too! I'd certainly consider it to be in the same vein of issue, e.g.: pub fn f(mut x: [Vec<u32>; 2]) {
// three drops are emit: x[0], x[0], x[1], and an allocation for the new vector
x[0] = vec![1, 2];
} Hopefully the developers working on LLVM can eventually get a working implementation of what is described in that discussion, good luck. |
@rustbot label A-LLVM |
#121298 adds But in order to improve this issue (i.e. to remove the stores to |
While revealing that dead
Vec<_>
writes always emit, to someone else, I decided to look into this for arrays.It seems that, for any
[T; N]
, such that T is not a ZST or enum with a single possible value, and 3 <= N, then array writes are always emit. This applies to allowing emitting redundant memcpys, memclrs, memfills, and all related operations.https://rust.godbolt.org/z/7vrT5xnxq
As for
Vec<T>
, as long as T isn't as described above, then unobservable writes and operations are usually emit.https://rust.godbolt.org/z/jhM75Mj5E
The text was updated successfully, but these errors were encountered: