-
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
See through aggregates in GVN #116270
See through aggregates in GVN #116270
Conversation
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri |
Can you point at where the logic is that realizes this principle? |
☔ The latest upstream changes (presumably #115025) made this pull request unmergeable. Please resolve the merge conflicts. |
40a50a7
to
503bdf8
Compare
503bdf8
to
b7b90b5
Compare
@@ -450,6 +450,50 @@ pub fn intern_const_alloc_recursive< | |||
Ok(()) | |||
} | |||
|
|||
/// Intern `ret`, checking it references no other allocation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Intern `ret`, checking it references no other allocation. | |
/// Intern `ret`, checking it references no other allocation. | |
/// The interned allocation will be marked as immutable. |
// Do not try interning a value that contains provenance. | ||
if alloc_ref.has_provenance() { | ||
throw_inval!(ConstPropNonsense) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd almost prefer if this was removed and we'd get an ICE if the check below ever fails -- the caller should ensure there is no provenance, and if it fails to do so we probably want to know (rather than silently failing to const-prop).
|
||
// Everything failed: create a new allocation to hold the data. | ||
let alloc_id = | ||
ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest, false)).ok()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This path should be unreachable now? Why is there a fallback path here? I can't see why we'd ever want to copy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
op
could be an immediate scalar pair. That wouldn't be caught by the scalar path, nor the mplace path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems nicer to have a 3-way match than a series of fallbacks, then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For scalars, we may want to encode them in MIR as a ConstValue::Scalar
, even if the interpreter backs it by a MPlace
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sure. What I dislike is to have this look like "try A; try B; try C", I'd much rather have a very clear case distinction showing when we use which case. In particular since the code currently completely mixes up checks that are actually needed and errors that can never happen and certainly shouldn't lead to a fallback.
So you can do something like
- first check
if let Abi::Scalar(abi::Scalar::Initialized { .. }) = op.layout.abi
. In that case always use ConstValue::Scalar, never fall back to anything else, with a comment explaining why we are doing this. - otherwise match on
op.as_mplace_or_imm()
, and if you have an mplace use the fast path, otherwise the copy, with a comment explaining this can happen for ScalarPair and ideally we'd have a more efficient representation for them but currently we don't (Cc Further possibilities for mir::Constant cleanup #115877)
b7b90b5
to
0bc44f7
Compare
☔ The latest upstream changes (presumably #113915) made this pull request unmergeable. Please resolve the merge conflicts. |
return Some(fields[f.as_usize()]); | ||
} else if let Value::Projection(outer_value, ProjectionElem::Downcast(_, read_variant)) = self.get(value) | ||
&& let Value::Aggregate(_, written_variant, fields) = self.get(*outer_value) | ||
&& written_variant == read_variant |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be violated? Could we just assert that they are equal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot happen from surface rust, as MIR is built such as a switch on the discriminant dominates the downcasts.
Reading reference chapter on enums and RFC 2195, I understand that accessing the wrong variant is not UB if the enum has repr
. So it's not impossible for a series of MIR opts to generate a downcast to an inactive variant. IIUC, miri does not check the variant either.
This can definitely happen from custom MIR. I'd rather silently fail to optimize (which is safe) than ICE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot happen from surface rust, as MIR is built such as a switch on the discriminant dominates the downcasts.
Reading reference chapter on enums and RFC 2195, I understand that accessing the wrong variant is not UB if the enum hasrepr
. So it's not impossible for a series of MIR opts to generate a downcast to an inactive variant.
this could be copied verbatim as a comment on the ==
expression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More pragmatically, this pass is not aware of control-flow. We could have:
_1 = None
_2 = discriminant(_1)
SwitchInt(_2) -> [0: bb1, otherwise: bb2]
bb1:
// stuff
bb2:
_3 = (_1 as Some).0
// stuff
We must not ICE for the assignment to _3
.
r=me after rebase |
0bc44f7
to
50448d1
Compare
@bors r=oli-obk |
@bors rollup=never for bisectability |
let alloc_ref = ecx.get_ptr_alloc(mplace.ptr(), size, align).ok()??; | ||
// Do not try interning a value that contains provenance. | ||
if alloc_ref.has_provenance() { | ||
return None; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems nicer to let intern_const_alloc_for_constprop
do this check, which naturally has access to the allocation anyway.
It's a bug if this ever fails, right? GVN doesn't do stuff on pointers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely need to handle some pointers. For instance when accessing a static to read from it.
What we cannot do is write pointers in the resulting MIR, because codegen does not respect identity of alloc-id in a across crates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But here this hasn't about "handling" pointers, it's about the constants that are actually tracked as "numbered" expressions and written back into the MIR, right? Can those ever contain pointers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you change your mind from #116270 (comment)? I can revert ac4572f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The practical issue I have is this one:
static A: fn() = || {};
// In another crate.
fn foo() -> fn() {
A
}
// In another crate.
fn bar() {
assert_eq!(A, foo());
}
Consider:
A
is at addressalloc1
;*alloc1
is the pointeralloc2
;- if the opt writes
alloc2
in the MIR forfoo
, the assertion inbar
may fail because codegen does not guarantee equality of fn pointers, which is a miscompilation.
On the other hand, for
static B: &'static &'static u8 = &&63;
fn blah() -> u8 {
**A
}
We definitely want to optimize blah
to return 63.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They can contain pointers when being numbered, but will not be written back if they do.
Okay, that was my wrong assumption then. So for **A
to be turned into 63, we need to number A
and *A
?
However, wouldn't we want to also optimize *A
to be a pointer directly into the allocation that contains &63
? That should also be sound, right? The issue isn't pointers in general, it's pointers created by certain operations: consts, and fn-item-to-fn-ptr coercions. So the more principled approach seems to be to never number fn-item-to-fn-ptr coercions, and when encountering a const to check whether it contains any provenance before numbering it. Once we do that any provenance we still number is fine?
Though I'm not entirely sure about statics with weak linkage. So maybe the point is you want to make a wide berth around this entire problem area even if that's unnecessarily conservative?
Or is the point you want to number **A
even when A
is a const rather than a static, and that requires numbering A
? So, the principled approach would be to mark some numbered values as "cannot be written back due to ptr non-determinism".
Either way this needs comments in the code that explain the why and what.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fundamentally, the problem is introducing more non-determinism. So when we write back we must not write back something that could have non-deterministic choice where there was no non-deterministic choice before.
What are the actually non-deterministic operations? An unevaluated constant can have non-determinism, so we can never replace x
by C
. However, we can replace x
by the result obtained from evaluating C
! An evaluated constant doesn't have extra non-determinism in general. So is this one even a problem for GVN, does GVN track unevaluated constants symbolically? If no, there should probably be a comment somewhere explaining why that would be a problem.
And then there's function pointers. Those are nasty indeed since even the same evaluated result can lead to different values at runtime, I think. The way to protect against that, I think, is to never number a value that contains provenance that points to a function allocation (or a vtable allocation... I'm not sure if we currently mark them as "address insignificant" but it seems like a reasonable thing to do).
If we do that, then we ensure that bad values never enter the GVN system, and then everything that we do number can be put back into the program, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I found an example of erroneous merging of constants.
fn opaque<T>(x: T) -> T { x }
#[custom_mir(dialect="analysis")]
fn foo() -> (bool, bool) {
mir!(
let au: u128;
let bu: u128;
let cu: u128;
let du: u128;
let c: &str;
let d: &str;
{
let a = ("a",);
Call(au = transmute::<_, u128>(a.0), bb1)
}
bb1 = {
Call(c = opaque(a.0), bb2)
}
bb2 = {
Call(cu = transmute::<_, u128>(c), bb3)
}
bb3 = {
let b = "a";
Call(bu = transmute::<_, u128>(b), bb4)
}
bb4 = {
Call(d = opaque(b), bb5)
}
bb5 = {
Call(du = transmute::<_, u128>(d), bb6)
}
bb6 = {
let direct = au == bu;
let indirect = cu == du;
RET = (direct, indirect);
Return()
}
)
}
Normally, both direct
and indirect
hold the same value. The current implementation merges au
and bu
, so direct
is always true, but fails to merge a.0
and b
so cu
and du
may be different. Miri fails when enabling GVN on this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So specifically what is happening here is numbering of unevaluated consts, with subsequent duplication of the non-determinism that arises from their evaluation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. We give the same VnIndex to a.0
and b
, although miri/codegen is allowed to give them different AllocIds. The latest push adds a disambiguation mechanism for non-deterministic constants.
0547a62
to
c79e3e5
Compare
c79e3e5
to
8561618
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=oli-obk,me with some last comment fixes and squashing the history a bit.
I'm not at all happy with the amount of hacks here. Our const infrastructure is just not ready for the kind of heavy lifting this pass does. But I guess that shouldn't block experimenting with the GVN pass... it just makes reviewing (and writing) such passes so much more painful. I'd rather not spend many more hours reviewing similar changes, instead we should clean up the const infrastructure such that these reviews become simpler.
Co-authored-by: Ralf Jung <post@ralfj.de>
@bors r=oli-obk,RalfJung |
☀️ Test successful - checks-actions |
Finished benchmarking commit (83c9732): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 635.492s -> 633.735s (-0.28%) |
74: Automated pull from upstream `master` r=tshepang a=github-actions[bot] This PR pulls the following changes from the upstream repository: * rust-lang/rust#117363 * rust-lang/rust#116405 * rust-lang/rust#117415 * rust-lang/rust#117414 * rust-lang/rust#117411 * rust-lang/rust#117403 * rust-lang/rust#117398 * rust-lang/rust#117396 * rust-lang/rust#117389 * rust-lang/rust#116862 * rust-lang/rust#117405 * rust-lang/rust#117395 * rust-lang/rust#117390 * rust-lang/rust#117383 * rust-lang/rust#117376 * rust-lang/rust#117370 * rust-lang/rust#117357 * rust-lang/rust#117356 * rust-lang/rust#117317 * rust-lang/rust#117132 * rust-lang/rust#117068 * rust-lang/rust#112463 * rust-lang/rust#117267 * rust-lang/rust#116939 * rust-lang/rust#117387 * rust-lang/rust#117385 * rust-lang/rust#117382 * rust-lang/rust#117371 * rust-lang/rust#117365 * rust-lang/rust#117350 * rust-lang/rust#117205 * rust-lang/rust#117177 * rust-lang/rust#117147 * rust-lang/rust#116485 * rust-lang/rust#117328 * rust-lang/rust#117332 * rust-lang/rust#117089 * rust-lang/rust#116733 * rust-lang/rust#116889 * rust-lang/rust#116270 * rust-lang/rust#117354 * rust-lang/rust#117337 * rust-lang/rust#117312 * rust-lang/rust#117082 * rust-lang/rust#117043 * rust-lang/rust#115968 * rust-lang/rust#117336 * rust-lang/rust#117325 * rust-lang/rust#117322 * rust-lang/rust#117259 * rust-lang/rust#117170 * rust-lang/rust#117335 * rust-lang/rust#117319 * rust-lang/rust#117316 * rust-lang/rust#117311 * rust-lang/rust#117162 * rust-lang/rust#115773 * rust-lang/rust#116447 * rust-lang/rust#117149 * rust-lang/rust#116240 * rust-lang/rust#117123 * rust-lang/rust#81746 * rust-lang/rust#117038 * rust-lang/rust#116609 * rust-lang/rust#117309 * rust-lang/rust#117277 * rust-lang/rust#117268 * rust-lang/rust#117256 * rust-lang/rust#117025 * rust-lang/rust#116945 * rust-lang/rust#116816 * rust-lang/rust#116739 * rust-lang/rust#116534 * rust-lang/rust#117253 * rust-lang/rust#117302 * rust-lang/rust#117197 * rust-lang/rust#116471 * rust-lang/rust#117294 * rust-lang/rust#117287 * rust-lang/rust#117281 * rust-lang/rust#117270 * rust-lang/rust#117247 * rust-lang/rust#117246 * rust-lang/rust#117212 * rust-lang/rust#116834 * rust-lang/rust#103208 * rust-lang/rust#117166 * rust-lang/rust#116751 * rust-lang/rust#116858 * rust-lang/rust#117272 * rust-lang/rust#117266 * rust-lang/rust#117262 * rust-lang/rust#117241 * rust-lang/rust#117240 * rust-lang/rust#116868 * rust-lang/rust#114998 * rust-lang/rust#116205 * rust-lang/rust#117260 * rust-lang/rust#116035 * rust-lang/rust#113183 * rust-lang/rust#117249 * rust-lang/rust#117243 * rust-lang/rust#117188 * rust-lang/rust#117114 * rust-lang/rust#117106 * rust-lang/rust#117032 * rust-lang/rust#116968 * rust-lang/rust#116581 * rust-lang/rust#117228 * rust-lang/rust#117221 * rust-lang/rust#117214 * rust-lang/rust#117207 * rust-lang/rust#117202 * rust-lang/rust#117194 * rust-lang/rust#117143 * rust-lang/rust#117095 * rust-lang/rust#116905 * rust-lang/rust#117171 * rust-lang/rust#113262 * rust-lang/rust#112875 * rust-lang/rust#116983 * rust-lang/rust#117148 * rust-lang/rust#117115 * rust-lang/rust#116818 * rust-lang/rust#115872 * rust-lang/rust#117193 * rust-lang/rust#117175 * rust-lang/rust#117009 * rust-lang/rust#117008 * rust-lang/rust#116931 * rust-lang/rust#116553 * rust-lang/rust#116401 * rust-lang/rust#117180 * rust-lang/rust#117173 * rust-lang/rust#117163 * rust-lang/rust#117159 * rust-lang/rust#117154 * rust-lang/rust#117152 * rust-lang/rust#117141 * rust-lang/rust#117111 * rust-lang/rust#117172 * rust-lang/rust#117168 * rust-lang/rust#117160 * rust-lang/rust#117158 * rust-lang/rust#117150 * rust-lang/rust#117136 * rust-lang/rust#117133 * rust-lang/rust#116801 * rust-lang/rust#117165 * rust-lang/rust#117113 * rust-lang/rust#117102 * rust-lang/rust#117076 * rust-lang/rust#116236 * rust-lang/rust#116993 * rust-lang/rust#117139 * rust-lang/rust#116482 * rust-lang/rust#115796 * rust-lang/rust#117135 * rust-lang/rust#117127 * rust-lang/rust#117010 * rust-lang/rust#116943 * rust-lang/rust#116841 * rust-lang/rust#116792 * rust-lang/rust#116714 * rust-lang/rust#116396 * rust-lang/rust#116094 * rust-lang/rust#117126 * rust-lang/rust#117105 * rust-lang/rust#117093 * rust-lang/rust#117092 * rust-lang/rust#117091 * rust-lang/rust#117081 * rust-lang/rust#116773 * rust-lang/rust#117124 * rust-lang/rust#116461 * rust-lang/rust#116435 * rust-lang/rust#116319 * rust-lang/rust#116238 * rust-lang/rust#116998 * rust-lang/rust#116300 * rust-lang/rust#117103 * rust-lang/rust#117086 * rust-lang/rust#117074 * rust-lang/rust#117070 * rust-lang/rust#117046 * rust-lang/rust#116859 * rust-lang/rust#107159 * rust-lang/rust#116033 * rust-lang/rust#107009 * rust-lang/rust#117087 * rust-lang/rust#117073 * rust-lang/rust#117064 * rust-lang/rust#117040 * rust-lang/rust#116978 * rust-lang/rust#116960 * rust-lang/rust#116837 * rust-lang/rust#116835 * rust-lang/rust#116849 * rust-lang/rust#117071 * rust-lang/rust#117069 * rust-lang/rust#117051 * rust-lang/rust#117049 * rust-lang/rust#117044 * rust-lang/rust#117042 * rust-lang/rust#105666 * rust-lang/rust#116606 * rust-lang/rust#117066 * rust-lang/rust#115324 * rust-lang/rust#117062 * rust-lang/rust#117000 * rust-lang/rust#117007 * rust-lang/rust#117018 * rust-lang/rust#116256 * rust-lang/rust#117041 * rust-lang/rust#117037 * rust-lang/rust#117034 * rust-lang/rust#116989 * rust-lang/rust#116985 * rust-lang/rust#116950 * rust-lang/rust#116956 * rust-lang/rust#116932 * rust-lang/rust#117031 * rust-lang/rust#117030 * rust-lang/rust#117028 * rust-lang/rust#117026 * rust-lang/rust#116992 * rust-lang/rust#116981 * rust-lang/rust#116955 * rust-lang/rust#116928 * rust-lang/rust#116312 * rust-lang/rust#116368 * rust-lang/rust#116922 * rust-lang/rust#117021 * rust-lang/rust#117020 * rust-lang/rust#117019 * rust-lang/rust#116975 * rust-lang/rust#106601 * rust-lang/rust#116734 * rust-lang/rust#117013 * rust-lang/rust#116995 * rust-lang/rust#116990 * rust-lang/rust#116974 * rust-lang/rust#116964 * rust-lang/rust#116961 * rust-lang/rust#116917 * rust-lang/rust#116911 * rust-lang/rust#114521 * rust-lang/rust#117011 * rust-lang/rust#116958 * rust-lang/rust#116951 * rust-lang/rust#116966 * rust-lang/rust#116965 * rust-lang/rust#116962 * rust-lang/rust#116946 * rust-lang/rust#116899 * rust-lang/rust#116785 * rust-lang/rust#116838 * rust-lang/rust#116875 * rust-lang/rust#116874 * rust-lang/rust#115214 * rust-lang/rust#116810 * rust-lang/rust#116940 * rust-lang/rust#116921 * rust-lang/rust#116906 * rust-lang/rust#116896 * rust-lang/rust#116650 * rust-lang/rust#116132 * rust-lang/rust#116037 * rust-lang/rust#116923 * rust-lang/rust#116912 * rust-lang/rust#116908 * rust-lang/rust#116883 * rust-lang/rust#116829 * rust-lang/rust#116795 * rust-lang/rust#116761 * rust-lang/rust#116663 * rust-lang/rust#114534 * rust-lang/rust#116402 * rust-lang/rust#116493 * rust-lang/rust#116046 * rust-lang/rust#116887 * rust-lang/rust#116885 * rust-lang/rust#116879 * rust-lang/rust#116870 * rust-lang/rust#116865 * rust-lang/rust#116856 * rust-lang/rust#116812 * rust-lang/rust#116815 * rust-lang/rust#116814 * rust-lang/rust#116713 * rust-lang/rust#116830 Co-authored-by: Matthias Krüger <matthias.krueger@famsik.de> Co-authored-by: antoyo <antoyo@users.noreply.github.com> Co-authored-by: Antoni Boucher <bouanto@zoho.com> Co-authored-by: bors <bors@rust-lang.org> Co-authored-by: Esteban Küber <esteban@kuber.com.ar> Co-authored-by: Kjetil Kjeka <kjetilkjeka@gmail.com> Co-authored-by: clubby789 <jamie@hill-daniel.co.uk> Co-authored-by: okaneco <47607823+okaneco@users.noreply.github.com> Co-authored-by: David Tolnay <dtolnay@gmail.com> Co-authored-by: Nadrieril <nadrieril+git@gmail.com> Co-authored-by: Celina G. Val <celinval@amazon.com> Co-authored-by: Ralf Jung <post@ralfj.de> Co-authored-by: Zalathar <Zalathar@users.noreply.github.com> Co-authored-by: Havard Eidnes <he@NetBSD.org> Co-authored-by: Jacob Pratt <jacob@jhpratt.dev> Co-authored-by: Kjetil Kjeka <kjetil@muybridge.com>
74: Automated pull from upstream `master` r=tshepang a=github-actions[bot] This PR pulls the following changes from the upstream repository: * rust-lang/rust#117363 * rust-lang/rust#116405 * rust-lang/rust#117415 * rust-lang/rust#117414 * rust-lang/rust#117411 * rust-lang/rust#117403 * rust-lang/rust#117398 * rust-lang/rust#117396 * rust-lang/rust#117389 * rust-lang/rust#116862 * rust-lang/rust#117405 * rust-lang/rust#117395 * rust-lang/rust#117390 * rust-lang/rust#117383 * rust-lang/rust#117376 * rust-lang/rust#117370 * rust-lang/rust#117357 * rust-lang/rust#117356 * rust-lang/rust#117317 * rust-lang/rust#117132 * rust-lang/rust#117068 * rust-lang/rust#112463 * rust-lang/rust#117267 * rust-lang/rust#116939 * rust-lang/rust#117387 * rust-lang/rust#117385 * rust-lang/rust#117382 * rust-lang/rust#117371 * rust-lang/rust#117365 * rust-lang/rust#117350 * rust-lang/rust#117205 * rust-lang/rust#117177 * rust-lang/rust#117147 * rust-lang/rust#116485 * rust-lang/rust#117328 * rust-lang/rust#117332 * rust-lang/rust#117089 * rust-lang/rust#116733 * rust-lang/rust#116889 * rust-lang/rust#116270 * rust-lang/rust#117354 * rust-lang/rust#117337 * rust-lang/rust#117312 * rust-lang/rust#117082 * rust-lang/rust#117043 * rust-lang/rust#115968 * rust-lang/rust#117336 * rust-lang/rust#117325 * rust-lang/rust#117322 * rust-lang/rust#117259 * rust-lang/rust#117170 * rust-lang/rust#117335 * rust-lang/rust#117319 * rust-lang/rust#117316 * rust-lang/rust#117311 * rust-lang/rust#117162 * rust-lang/rust#115773 * rust-lang/rust#116447 * rust-lang/rust#117149 * rust-lang/rust#116240 * rust-lang/rust#117123 * rust-lang/rust#81746 * rust-lang/rust#117038 * rust-lang/rust#116609 * rust-lang/rust#117309 * rust-lang/rust#117277 * rust-lang/rust#117268 * rust-lang/rust#117256 * rust-lang/rust#117025 * rust-lang/rust#116945 * rust-lang/rust#116816 * rust-lang/rust#116739 * rust-lang/rust#116534 * rust-lang/rust#117253 * rust-lang/rust#117302 * rust-lang/rust#117197 * rust-lang/rust#116471 * rust-lang/rust#117294 * rust-lang/rust#117287 * rust-lang/rust#117281 * rust-lang/rust#117270 * rust-lang/rust#117247 * rust-lang/rust#117246 * rust-lang/rust#117212 * rust-lang/rust#116834 * rust-lang/rust#103208 * rust-lang/rust#117166 * rust-lang/rust#116751 * rust-lang/rust#116858 * rust-lang/rust#117272 * rust-lang/rust#117266 * rust-lang/rust#117262 * rust-lang/rust#117241 * rust-lang/rust#117240 * rust-lang/rust#116868 * rust-lang/rust#114998 * rust-lang/rust#116205 * rust-lang/rust#117260 * rust-lang/rust#116035 * rust-lang/rust#113183 * rust-lang/rust#117249 * rust-lang/rust#117243 * rust-lang/rust#117188 * rust-lang/rust#117114 * rust-lang/rust#117106 * rust-lang/rust#117032 * rust-lang/rust#116968 * rust-lang/rust#116581 * rust-lang/rust#117228 * rust-lang/rust#117221 * rust-lang/rust#117214 * rust-lang/rust#117207 * rust-lang/rust#117202 * rust-lang/rust#117194 * rust-lang/rust#117143 * rust-lang/rust#117095 * rust-lang/rust#116905 * rust-lang/rust#117171 * rust-lang/rust#113262 * rust-lang/rust#112875 * rust-lang/rust#116983 * rust-lang/rust#117148 * rust-lang/rust#117115 * rust-lang/rust#116818 * rust-lang/rust#115872 * rust-lang/rust#117193 * rust-lang/rust#117175 * rust-lang/rust#117009 * rust-lang/rust#117008 * rust-lang/rust#116931 * rust-lang/rust#116553 * rust-lang/rust#116401 * rust-lang/rust#117180 * rust-lang/rust#117173 * rust-lang/rust#117163 * rust-lang/rust#117159 * rust-lang/rust#117154 * rust-lang/rust#117152 * rust-lang/rust#117141 * rust-lang/rust#117111 * rust-lang/rust#117172 * rust-lang/rust#117168 * rust-lang/rust#117160 * rust-lang/rust#117158 * rust-lang/rust#117150 * rust-lang/rust#117136 * rust-lang/rust#117133 * rust-lang/rust#116801 * rust-lang/rust#117165 * rust-lang/rust#117113 * rust-lang/rust#117102 * rust-lang/rust#117076 * rust-lang/rust#116236 * rust-lang/rust#116993 * rust-lang/rust#117139 * rust-lang/rust#116482 * rust-lang/rust#115796 * rust-lang/rust#117135 * rust-lang/rust#117127 * rust-lang/rust#117010 * rust-lang/rust#116943 * rust-lang/rust#116841 * rust-lang/rust#116792 * rust-lang/rust#116714 * rust-lang/rust#116396 * rust-lang/rust#116094 * rust-lang/rust#117126 * rust-lang/rust#117105 * rust-lang/rust#117093 * rust-lang/rust#117092 * rust-lang/rust#117091 * rust-lang/rust#117081 * rust-lang/rust#116773 * rust-lang/rust#117124 * rust-lang/rust#116461 * rust-lang/rust#116435 * rust-lang/rust#116319 * rust-lang/rust#116238 * rust-lang/rust#116998 * rust-lang/rust#116300 * rust-lang/rust#117103 * rust-lang/rust#117086 * rust-lang/rust#117074 * rust-lang/rust#117070 * rust-lang/rust#117046 * rust-lang/rust#116859 * rust-lang/rust#107159 * rust-lang/rust#116033 * rust-lang/rust#107009 * rust-lang/rust#117087 * rust-lang/rust#117073 * rust-lang/rust#117064 * rust-lang/rust#117040 * rust-lang/rust#116978 * rust-lang/rust#116960 * rust-lang/rust#116837 * rust-lang/rust#116835 * rust-lang/rust#116849 * rust-lang/rust#117071 * rust-lang/rust#117069 * rust-lang/rust#117051 * rust-lang/rust#117049 * rust-lang/rust#117044 * rust-lang/rust#117042 * rust-lang/rust#105666 * rust-lang/rust#116606 * rust-lang/rust#117066 * rust-lang/rust#115324 * rust-lang/rust#117062 * rust-lang/rust#117000 * rust-lang/rust#117007 * rust-lang/rust#117018 * rust-lang/rust#116256 * rust-lang/rust#117041 * rust-lang/rust#117037 * rust-lang/rust#117034 * rust-lang/rust#116989 * rust-lang/rust#116985 * rust-lang/rust#116950 * rust-lang/rust#116956 * rust-lang/rust#116932 * rust-lang/rust#117031 * rust-lang/rust#117030 * rust-lang/rust#117028 * rust-lang/rust#117026 * rust-lang/rust#116992 * rust-lang/rust#116981 * rust-lang/rust#116955 * rust-lang/rust#116928 * rust-lang/rust#116312 * rust-lang/rust#116368 * rust-lang/rust#116922 * rust-lang/rust#117021 * rust-lang/rust#117020 * rust-lang/rust#117019 * rust-lang/rust#116975 * rust-lang/rust#106601 * rust-lang/rust#116734 * rust-lang/rust#117013 * rust-lang/rust#116995 * rust-lang/rust#116990 * rust-lang/rust#116974 * rust-lang/rust#116964 * rust-lang/rust#116961 * rust-lang/rust#116917 * rust-lang/rust#116911 * rust-lang/rust#114521 * rust-lang/rust#117011 * rust-lang/rust#116958 * rust-lang/rust#116951 * rust-lang/rust#116966 * rust-lang/rust#116965 * rust-lang/rust#116962 * rust-lang/rust#116946 * rust-lang/rust#116899 * rust-lang/rust#116785 * rust-lang/rust#116838 * rust-lang/rust#116875 * rust-lang/rust#116874 * rust-lang/rust#115214 * rust-lang/rust#116810 * rust-lang/rust#116940 * rust-lang/rust#116921 * rust-lang/rust#116906 * rust-lang/rust#116896 * rust-lang/rust#116650 * rust-lang/rust#116132 * rust-lang/rust#116037 * rust-lang/rust#116923 * rust-lang/rust#116912 * rust-lang/rust#116908 * rust-lang/rust#116883 * rust-lang/rust#116829 * rust-lang/rust#116795 * rust-lang/rust#116761 * rust-lang/rust#116663 * rust-lang/rust#114534 * rust-lang/rust#116402 * rust-lang/rust#116493 * rust-lang/rust#116046 * rust-lang/rust#116887 * rust-lang/rust#116885 * rust-lang/rust#116879 * rust-lang/rust#116870 * rust-lang/rust#116865 * rust-lang/rust#116856 * rust-lang/rust#116812 * rust-lang/rust#116815 * rust-lang/rust#116814 * rust-lang/rust#116713 * rust-lang/rust#116830 Co-authored-by: antoyo <antoyo@users.noreply.github.com> Co-authored-by: Antoni Boucher <bouanto@zoho.com> Co-authored-by: bors <bors@rust-lang.org> Co-authored-by: Esteban Küber <esteban@kuber.com.ar> Co-authored-by: Kjetil Kjeka <kjetilkjeka@gmail.com> Co-authored-by: clubby789 <jamie@hill-daniel.co.uk> Co-authored-by: okaneco <47607823+okaneco@users.noreply.github.com> Co-authored-by: David Tolnay <dtolnay@gmail.com> Co-authored-by: Nadrieril <nadrieril+git@gmail.com> Co-authored-by: Celina G. Val <celinval@amazon.com> Co-authored-by: Ralf Jung <post@ralfj.de> Co-authored-by: Zalathar <Zalathar@users.noreply.github.com> Co-authored-by: Havard Eidnes <he@NetBSD.org> Co-authored-by: Jacob Pratt <jacob@jhpratt.dev> Co-authored-by: Kjetil Kjeka <kjetil@muybridge.com> Co-authored-by: Matthias Krüger <matthias.krueger@famsik.de>
This PR is extracted from #111344
The first 2 commit are cleanups to avoid repeated work. I propose to stop removing useless assignments as part of this pass, and let a later
SimplifyLocals
do it. This makes tests easier to read (among others).The next 3 commits add a constant folding mechanism to the GVN pass, presented in #116012.
This pass is designed to only use global allocations, to avoid any risk of accidental modification of the stored state.The following commits implement opportunistic simplifications, in particular:
MyStruct { x: a }.x
gets replaced bya
, works with enums too;[a, b][0]
becomesa
;[a; N][x]
becomesa
;Fixes rust-lang/miri#3090
r? @oli-obk