@@ -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,24 @@ 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
+ // FIXME: This also avoids any kind of projection, not just derefs. We can add allowed projections.
992
+ if lhs. as_local ( ) . is_some ( ) {
987
993
self . reused_locals . insert ( place. local ) ;
988
994
* rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
989
- return Some ( copy_from_local_value) ;
990
995
}
996
+ return Some ( copy_from_local_value) ;
991
997
}
992
998
993
999
None
994
1000
}
995
1001
996
1002
fn simplify_aggregate (
997
1003
& mut self ,
1004
+ lhs : & Place < ' tcx > ,
998
1005
rvalue : & mut Rvalue < ' tcx > ,
999
1006
location : Location ,
1000
1007
) -> Option < VnIndex > {
@@ -1090,7 +1097,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1090
1097
1091
1098
if let AggregateTy :: Def ( _, _) = ty
1092
1099
&& 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)
1094
1101
{
1095
1102
return Some ( value) ;
1096
1103
}
@@ -1765,7 +1772,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1765
1772
if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
1766
1773
self . simplify_place_projection ( lhs, location) ;
1767
1774
1768
- let value = self . simplify_rvalue ( rvalue, location) ;
1775
+ let value = self . simplify_rvalue ( lhs , rvalue, location) ;
1769
1776
let value = if let Some ( local) = lhs. as_local ( )
1770
1777
&& self . ssa . is_ssa ( local)
1771
1778
// FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
0 commit comments