@@ -836,6 +836,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
836836#[ instrument( level = "trace" , skip( self ) , ret) ]
837837fn simplify_rvalue (
838838& mut self ,
839+ lhs : & Place < ' tcx > ,
839840rvalue : & mut Rvalue < ' tcx > ,
840841location : Location ,
841842) -> Option < VnIndex > {
@@ -855,7 +856,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
855856Value :: Repeat ( op, amount)
856857}
857858Rvalue :: NullaryOp ( op, ty) => Value :: NullaryOp ( op, ty) ,
858- Rvalue :: Aggregate ( ..) => return self . simplify_aggregate ( rvalue, location) ,
859+ Rvalue :: Aggregate ( ..) => return self . simplify_aggregate ( lhs , rvalue, location) ,
859860Rvalue :: Ref ( _, borrow_kind, ref mut place) => {
860861self . simplify_place_projection ( place, location) ;
861862return Some ( self . new_pointer ( * place, AddressKind :: Ref ( borrow_kind) ) ) ;
@@ -943,6 +944,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
943944
944945fn simplify_aggregate_to_copy (
945946& mut self ,
947+ lhs : & Place < ' tcx > ,
946948rvalue : & mut Rvalue < ' tcx > ,
947949location : Location ,
948950fields : & [ VnIndex ] ,
@@ -982,19 +984,24 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
982984
983985// Allow introducing places with non-constant offsets, as those are still better than
984986// reconstructing an aggregate.
985- if let Some ( place) = self . try_as_place ( copy_from_local_value, location, true ) {
986- if rvalue. ty ( self . local_decls , self . tcx ) == place. ty ( self . local_decls , self . tcx ) . ty {
987+ if let Some ( place) = self . try_as_place ( copy_from_local_value, location, true )
988+ && rvalue. ty ( self . local_decls , self . tcx ) == place. ty ( self . local_decls , self . tcx ) . ty
989+ {
990+ // Avoid creating `*a = copy (*b)`, as they might be aliases resulting in overlapping assignments.
991+ // FIXME: This also avoids any kind of projection, not just derefs. We can add allowed projections.
992+ if lhs. as_local ( ) . is_some ( ) {
987993self . reused_locals . insert ( place. local ) ;
988994* rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
989- return Some ( copy_from_local_value) ;
990995}
996+ return Some ( copy_from_local_value) ;
991997}
992998
993999None
9941000}
9951001
9961002fn simplify_aggregate (
9971003& mut self ,
1004+ lhs : & Place < ' tcx > ,
9981005rvalue : & mut Rvalue < ' tcx > ,
9991006location : Location ,
10001007) -> Option < VnIndex > {
@@ -1090,7 +1097,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10901097
10911098if let AggregateTy :: Def ( _, _) = ty
10921099 && let Some ( value) =
1093- self . simplify_aggregate_to_copy ( rvalue, location, & fields, variant_index)
1100+ self . simplify_aggregate_to_copy ( lhs , rvalue, location, & fields, variant_index)
10941101{
10951102return Some ( value) ;
10961103}
@@ -1765,7 +1772,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
17651772if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
17661773self . simplify_place_projection ( lhs, location) ;
17671774
1768- let value = self . simplify_rvalue ( rvalue, location) ;
1775+ let value = self . simplify_rvalue ( lhs , rvalue, location) ;
17691776let value = if let Some ( local) = lhs. as_local ( )
17701777 && self . ssa . is_ssa ( local)
17711778// FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
0 commit comments