Commit 20de910
committed
Auto merge of #154341 - RalfJung:retag-on-typed-copy, r=oli-obk
Make retags an implicit part of typed copies
Ever since Stacked Borrows was first implemented in Miri, that was done with `Retag` statements: given a place (usually a local variable), those statements find all references stored inside the place and refresh their tags to ensure the aliasing requirements are upheld. However, this is a somewhat unsatisfying approach for multiple reasons:
- It leaves open the [question](rust-lang/unsafe-code-guidelines#371) of where to even put `Retag` statements. Over time, the AddRetag pass settled on one possible answer to this, but it wasn't very canonical.
- For assignments of the form `*ptr = expr`, if the assignment involves copying a reference, we probably want to do a retag -- but if we do a `Retag(*ptr)` as the next instruction, it can be non-trivial to argue that this even retags the right value, so we refrained from doing retags in that case. This has [come up](llvm/llvm-project#160913 (comment)) as a potential issue for Rust making better use of LLVM "captures" annotations. (That said, there might be [other ways](rust-lang/unsafe-code-guidelines#593 (comment)) to obtain this desired optimization.)
- Normal compilation avoids generating retags, but we still generate LLVM IR with `noalias`. What does that even mean? How do MIR optimization passes interact with retags? These are questions we have to figure out to make better use of aliasing information, but currently we can't even really ask such questions.
I think we should resolve all that by making retags part of what happens during a typed copy (a concept and interpreter infrastructure that did not exist yet when retags were initially introduced). Under this proposal, when executing a MIR assignment statement, what conceptually happens is as follows:
- We evaluate the LHS to a place.
- We evaluate the RHS to a value. This does a typed load from memory if needed, raising UB if memory does not contain a valid representation of the assignment's type.
- We walk that value, identify all references inside of it, and retag them. If this happens as part of passing a function argument, this is a protecting retag.
- We store (a representation of) the value into the place.
However, this semantics doesn't fully work: there's a mandatory MIR pass that turns expressions like `&mut ***ptr` into intermediate deref's. Those must *not* do any retags. So far this happened because the AddRetag pass did not add retags for assignments to deref temporaries, but that information is not recorded in cross-crate MIR. Therefore I instead added a field to `Rvalue::Use` to indicate whether this value should be retagged or not. A non-retagging copy seems like a sufficiently canonical primitive that we should be able to express it. Dealing with the fallout from that is a large chunk of the overall diff. (I also considered adding this field to `StatementKind::Assign` instead, but decided against that as we only actually need it for `Rvalue::Use`. I am not sure if this was the right call...)
This neatly answers the question of when retags should occur, and handles cases like `*ptr = expr`. It avoids traversing values twice in Miri. It makes codegen's use of `noalias` sound wrt the actual MIR that it is working on. It also gives us a target semantics to evaluate MIR opts against. However, I did not carefully check all MIR opts -- in particular, GVN needs a thorough look under the new semantics; it currently can turn alias-correct code into alias-incorrect code. (But this PR doesn't make things any worse for normal compilation where the retag indicator is anyway ignored.)
Another side-effect of this PR is that `-Zmiri-disable-validation` now also disables alias checking. It'd be nicer to keep them orthogonal but I find this an acceptable price to pay.
- [rustc benchmark results](#154341 (comment))
- [miri benchmark results](#154341 (comment))240 files changed
Lines changed: 1161 additions & 2520 deletions
File tree
- compiler
- rustc_borrowck/src
- diagnostics
- polonius/legacy
- type_check
- rustc_codegen_cranelift/src
- rustc_codegen_ssa/src/mir
- rustc_const_eval/src
- check_consts
- const_eval
- interpret
- rustc_interface/src
- rustc_middle/src
- mir
- interpret
- ty
- rustc_mir_build/src/builder
- custom/parse
- expr
- matches
- rustc_mir_dataflow/src
- impls
- move_paths
- rustc_mir_transform/src
- coroutine
- coverage
- shim
- rustc_public/src
- mir
- unstable/convert/stable
- rustc_session/src
- rustc_span/src
- rustc_ty_utils/src
- library
- alloc/src
- core/src/intrinsics
- src/tools
- clippy
- clippy_lints/src
- clippy_utils/src
- mir
- miri
- src
- bin
- borrow_tracker
- stacked_borrows
- tree_borrows
- tests
- fail
- both_borrows
- dangling_pointers
- function_calls
- provenance
- stacked_borrows
- tree_borrows/implicit_writes
- uninit
- validity
- pass
- both_borrows
- issues
- tests
- mir-opt
- building/custom
- dataflow-const-prop
- dead-store-elimination
- inline
- pre-codegen
- sroa
- ui-fulldeps/rustc_public
- ui/rustc_public-ir-print
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
578 | 578 | | |
579 | 579 | | |
580 | 580 | | |
581 | | - | |
582 | 581 | | |
583 | 582 | | |
584 | 583 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4325 | 4325 | | |
4326 | 4326 | | |
4327 | 4327 | | |
4328 | | - | |
| 4328 | + | |
4329 | 4329 | | |
4330 | 4330 | | |
4331 | 4331 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
875 | 875 | | |
876 | 876 | | |
877 | 877 | | |
878 | | - | |
| 878 | + | |
879 | 879 | | |
880 | 880 | | |
881 | 881 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
246 | | - | |
| 246 | + | |
247 | 247 | | |
248 | 248 | | |
249 | 249 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
125 | | - | |
| 125 | + | |
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| |||
Lines changed: 4 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1309 | 1309 | | |
1310 | 1310 | | |
1311 | 1311 | | |
1312 | | - | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
1313 | 1316 | | |
1314 | 1317 | | |
1315 | 1318 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
853 | 853 | | |
854 | 854 | | |
855 | 855 | | |
856 | | - | |
857 | 856 | | |
858 | 857 | | |
859 | 858 | | |
| |||
1540 | 1539 | | |
1541 | 1540 | | |
1542 | 1541 | | |
1543 | | - | |
| 1542 | + | |
1544 | 1543 | | |
1545 | 1544 | | |
1546 | 1545 | | |
| |||
1693 | 1692 | | |
1694 | 1693 | | |
1695 | 1694 | | |
1696 | | - | |
| 1695 | + | |
1697 | 1696 | | |
1698 | 1697 | | |
1699 | 1698 | | |
| |||
Lines changed: 1 addition & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
87 | 86 | | |
88 | 87 | | |
89 | 88 | | |
| |||
294 | 293 | | |
295 | 294 | | |
296 | 295 | | |
297 | | - | |
| 296 | + | |
298 | 297 | | |
299 | 298 | | |
300 | 299 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
697 | 697 | | |
698 | 698 | | |
699 | 699 | | |
700 | | - | |
701 | 700 | | |
702 | 701 | | |
703 | 702 | | |
| |||
1652 | 1651 | | |
1653 | 1652 | | |
1654 | 1653 | | |
1655 | | - | |
| 1654 | + | |
1656 | 1655 | | |
1657 | 1656 | | |
1658 | 1657 | | |
| |||
2215 | 2214 | | |
2216 | 2215 | | |
2217 | 2216 | | |
2218 | | - | |
2219 | | - | |
| 2217 | + | |
| 2218 | + | |
2220 | 2219 | | |
2221 | 2220 | | |
2222 | 2221 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
620 | 620 | | |
621 | 621 | | |
622 | 622 | | |
623 | | - | |
| 623 | + | |
624 | 624 | | |
625 | 625 | | |
626 | 626 | | |
| |||
909 | 909 | | |
910 | 910 | | |
911 | 911 | | |
912 | | - | |
913 | 912 | | |
914 | 913 | | |
915 | 914 | | |
| |||
0 commit comments