-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Semantics of StorageLive in loops #42371
Comments
I suppose a somewhat weaker interpretation would be for |
FYI, I implemented the above suggestion in Miri, and the test suite passes. Now that's not a whole lot of code on the grand scheme of things, but this does invoke some interesting unsafe code in Vec and the |
Accidental triage (because I forgot about this and just rediscovered the issue^^): the situation is unchanged. |
…sakis Clean up MIR drop generation * Don't assign twice to the destination of a `while` loop containing a `break` expression * Use `as_temp` to evaluate statement expression * Avoid consecutive `StorageLive`s for the condition of a `while` loop * Unify `return`, `break` and `continue` handling, and move it to `scopes.rs` * Make some of the `scopes.rs` internals private * Don't use `Place`s that are always `Local`s in MIR drop generation Closes #42371 Closes #61579 Closes #61731 Closes #61834 Closes #61910 Closes #62115
@matthewjasper I don't think this is fixed. I am still seeing already-live locals marked as live if I make Miri check for that. You can see that in this example: the MIR with your patch is Expand MIR
You can see that there is a |
In fact, MIR generation in that example does not seem to change at all with your PR. |
Note-mostly-to-self: the branch to make Miri check if this issue is resolved is at https://github.com/RalfJung/rust/tree/miri-storage-live. |
…=pnkfelix Sometimes generate storage statements for temporaries with type `!` Closes rust-lang#62165 cc rust-lang#42371
Alive2 is a tool to check LLVM optimizations correct, and it has to give an operational semantics to LLVM IR. What they do for lifetime.start/end is interesting:
This is close to what Miri does, except Miri re-assigns a new block ID and address each time the lifetime of a local ends and starts again. (Compiling from Miri to Alive2 semantics is correct but not the other way around, so we are good.) Also:
and
|
Hi, maybe a silly question - is there a reason that Rust emits I'm wondering whether it makes sense for LLVM to typecheck whether a program has lifetime intrinsics arranged within well-known patterns only. If the usage pattern was too complex, LLVM would already have given up using the pairs for optimization. |
You mean the other way around? It seems to be in bb1. I'm afraid I do not know why we emit |
The The MIR now has a |
Would be good to have the LangRef updated then... where can I read more about StackColoring?
Oh, nice! I'll try to see if I can now adjust |
|
I love the introduction^^
Seems like everyone is very sure what these things do... doesn't make me worried about LLVM as the foundation of Rust at all...^^ |
Currently this fails to evaluate many constants; I suspect that is related to @oli-obk's #78679. I'll try again once that landed. For future reference, this is the branch. |
(I'm not sure whether here is a good place to ask this, but) can Rust generate lifetime.start/end with non-zero offset? |
Syntactically, the Rust/MIR equivalent of these intrinsics can only be applied to locals, not to a part of a place/local. However, fixing #71416 might require adding offsets to dynamically-sized alloca to make sure the alignment is right. Not sure if there is a way to make the lifetime intrinsics still refer to the original alloca as opposed to the properly aligned ptr. |
Okay, I understood the issue. |
This code
compiles to
On every run through the loop,
StorageLive(_4)
is executed, and there is no matchingStorageDead
.The intended semantics of multiple
StorageLive
on the same location are unclear. However, evidence suggests that LLVM considers a variable dead before anyllvm.lifetime.start
, in particular, inllvm.lifetime.start; load; llvm.lifetime.start
, LLVM feels free to treat that load as yieldingundef
. The reference manual says so (however, it doesn't say anything aboutllvm.lifetime.start; load; llvm.lifetime.end; llvm.lifetime.start
being fine, so it seems incomplete), and @eddyb managed to actually obtain UB from a redundantllvm.lifetime.start
inPlaypen
If you comment out the
MyStorageLive
, this prints some a's. If you leave it in, nothing is printed.This suggests we should rather not permit "redundant"
StorageLive
, and hence the program at the beginning of this report should be translated such that_4
is marked live before the loop, rather than inside the loop.The text was updated successfully, but these errors were encountered: