@@ -836,6 +836,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
836
836
#[ instrument( level = "trace" , skip( self ) , ret) ]
837
837
fn simplify_rvalue (
838
838
& mut self ,
839
+ lhs : & Place < ' tcx > ,
839
840
rvalue : & mut Rvalue < ' tcx > ,
840
841
location : Location ,
841
842
) -> Option < VnIndex > {
@@ -855,7 +856,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
855
856
Value :: Repeat ( op, amount)
856
857
}
857
858
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) ,
859
860
Rvalue :: Ref ( _, borrow_kind, ref mut place) => {
860
861
self . simplify_place_projection ( place, location) ;
861
862
return Some ( self . new_pointer ( * place, AddressKind :: Ref ( borrow_kind) ) ) ;
@@ -943,6 +944,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
943
944
944
945
fn simplify_aggregate_to_copy (
945
946
& mut self ,
947
+ lhs : & Place < ' tcx > ,
946
948
rvalue : & mut Rvalue < ' tcx > ,
947
949
location : Location ,
948
950
fields : & [ VnIndex ] ,
@@ -982,19 +984,23 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
982
984
983
985
// Allow introducing places with non-constant offsets, as those are still better than
984
986
// 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
+ if lhs. as_local ( ) . is_some ( ) {
987
992
self . reused_locals . insert ( place. local ) ;
988
993
* rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
989
- return Some ( copy_from_local_value) ;
990
994
}
995
+ return Some ( copy_from_local_value) ;
991
996
}
992
997
993
998
None
994
999
}
995
1000
996
1001
fn simplify_aggregate (
997
1002
& mut self ,
1003
+ lhs : & Place < ' tcx > ,
998
1004
rvalue : & mut Rvalue < ' tcx > ,
999
1005
location : Location ,
1000
1006
) -> Option < VnIndex > {
@@ -1090,7 +1096,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1090
1096
1091
1097
if let AggregateTy :: Def ( _, _) = ty
1092
1098
&& let Some ( value) =
1093
- self . simplify_aggregate_to_copy ( rvalue, location, & fields, variant_index)
1099
+ self . simplify_aggregate_to_copy ( lhs , rvalue, location, & fields, variant_index)
1094
1100
{
1095
1101
return Some ( value) ;
1096
1102
}
@@ -1765,7 +1771,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1765
1771
if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
1766
1772
self . simplify_place_projection ( lhs, location) ;
1767
1773
1768
- let value = self . simplify_rvalue ( rvalue, location) ;
1774
+ let value = self . simplify_rvalue ( lhs , rvalue, location) ;
1769
1775
let value = if let Some ( local) = lhs. as_local ( )
1770
1776
&& self . ssa . is_ssa ( local)
1771
1777
// FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
0 commit comments