@@ -836,6 +836,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
836836 #[ instrument( level = "trace" , skip( self ) , ret) ]
837837 fn simplify_rvalue (
838838 & mut self ,
839+ lhs : & Place < ' tcx > ,
839840 rvalue : & mut Rvalue < ' tcx > ,
840841 location : Location ,
841842 ) -> Option < VnIndex > {
@@ -855,7 +856,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
855856 Value :: Repeat ( op, amount)
856857 }
857858 Rvalue :: 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) ,
859860 Rvalue :: Ref ( _, borrow_kind, ref mut place) => {
860861 self . simplify_place_projection ( place, location) ;
861862 return Some ( self . new_pointer ( * place, AddressKind :: Ref ( borrow_kind) ) ) ;
@@ -943,6 +944,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
943944
944945 fn simplify_aggregate_to_copy (
945946 & mut self ,
947+ lhs : & Place < ' tcx > ,
946948 rvalue : & mut Rvalue < ' tcx > ,
947949 location : Location ,
948950 fields : & [ 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 ( ) {
987993 self . 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
993999 None
9941000 }
9951001
9961002 fn simplify_aggregate (
9971003 & mut self ,
1004+ lhs : & Place < ' tcx > ,
9981005 rvalue : & mut Rvalue < ' tcx > ,
9991006 location : Location ,
10001007 ) -> Option < VnIndex > {
@@ -1090,7 +1097,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10901097
10911098 if 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 {
10951102 return Some ( value) ;
10961103 }
@@ -1765,7 +1772,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
17651772 if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
17661773 self . simplify_place_projection ( lhs, location) ;
17671774
1768- let value = self . simplify_rvalue ( rvalue, location) ;
1775+ let value = self . simplify_rvalue ( lhs , rvalue, location) ;
17691776 let 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