@@ -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