Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Only decide once whether to use a complex projection.
  • Loading branch information
cjgillot committed Oct 18, 2025
commit 8216f59bf8b79a017f47502ca0832a90aef63622
27 changes: 12 additions & 15 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {

match self.compute_place_value(*place, location) {
Ok(value) => {
if let Some(new_place) = self.try_as_place(value, location, true)
if let Some(new_place) = self.try_as_place(value, location, false)
&& (new_place.local != place.local
|| new_place.projection.len() < place.projection.len())
{
Expand Down Expand Up @@ -1026,7 +1026,6 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
#[instrument(level = "trace", skip(self), ret)]
fn simplify_rvalue(
&mut self,
lhs: &Place<'tcx>,
rvalue: &mut Rvalue<'tcx>,
location: Location,
) -> Option<VnIndex> {
Expand All @@ -1040,7 +1039,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
Value::Repeat(op, amount)
}
Rvalue::NullaryOp(op, ty) => Value::NullaryOp(op, ty),
Rvalue::Aggregate(..) => return self.simplify_aggregate(lhs, rvalue, location),
Rvalue::Aggregate(..) => return self.simplify_aggregate(rvalue, location),
Rvalue::Ref(_, borrow_kind, ref mut place) => {
self.simplify_place_projection(place, location);
return self.new_pointer(*place, AddressKind::Ref(borrow_kind));
Expand Down Expand Up @@ -1149,7 +1148,6 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {

fn simplify_aggregate(
&mut self,
lhs: &Place<'tcx>,
rvalue: &mut Rvalue<'tcx>,
location: Location,
) -> Option<VnIndex> {
Expand Down Expand Up @@ -1232,15 +1230,6 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
}

if let Some(value) = self.simplify_aggregate_to_copy(ty, variant_index, &fields) {
// Allow introducing places with non-constant offsets, as those are still better than
// reconstructing an aggregate. But avoid creating `*a = copy (*b)`, as they might be
// aliases resulting in overlapping assignments.
let allow_complex_projection =
lhs.projection[..].iter().all(PlaceElem::is_stable_offset);
if let Some(place) = self.try_as_place(value, location, allow_complex_projection) {
self.reused_locals.insert(place.local);
*rvalue = Rvalue::Use(Operand::Copy(place));
}
return Some(value);
}

Expand Down Expand Up @@ -1886,13 +1875,21 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
) {
self.simplify_place_projection(lhs, location);

let value = self.simplify_rvalue(lhs, rvalue, location);
let value = self.simplify_rvalue(rvalue, location);
if let Some(value) = value {
// Allow introducing places with non-constant offsets, as those are still better than
// reconstructing an aggregate. But avoid creating `*a = copy (*b)`, as they might be
// aliases resulting in overlapping assignments.
let allow_complex_projection =
lhs.projection[..].iter().all(PlaceElem::is_stable_offset);

if let Some(const_) = self.try_as_constant(value) {
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
} else if let Some(place) = self.try_as_place(value, location, false)
} else if let Some(place) = self.try_as_place(value, location, allow_complex_projection)
&& *rvalue != Rvalue::Use(Operand::Move(place))
&& *rvalue != Rvalue::Use(Operand::Copy(place))
// Avoid introducing overlapping assignments to the same local.
&& place.local != lhs.local
{
*rvalue = Rvalue::Use(Operand::Copy(place));
self.reused_locals.insert(place.local);
Expand Down