@@ -980,7 +980,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
980980 }
981981 }
982982
983- if let Some ( place) = self . try_as_place ( copy_from_local_value, location) {
983+ // Allow introducing places with non-constant offsets, as those are still better than
984+ // reconstructing an aggregate.
985+ if let Some ( place) = self . try_as_place ( copy_from_local_value, location, true ) {
984986 if rvalue. ty ( self . local_decls , self . tcx ) == place. ty ( self . local_decls , self . tcx ) . ty {
985987 self . reused_locals . insert ( place. local ) ;
986988 * rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
@@ -1665,7 +1667,7 @@ impl<'tcx> VnState<'_, 'tcx> {
16651667 fn try_as_operand ( & mut self , index : VnIndex , location : Location ) -> Option < Operand < ' tcx > > {
16661668 if let Some ( const_) = self . try_as_constant ( index) {
16671669 Some ( Operand :: Constant ( Box :: new ( const_) ) )
1668- } else if let Some ( place) = self . try_as_place ( index, location) {
1670+ } else if let Some ( place) = self . try_as_place ( index, location, false ) {
16691671 self . reused_locals . insert ( place. local ) ;
16701672 Some ( Operand :: Copy ( place) )
16711673 } else {
@@ -1704,7 +1706,12 @@ impl<'tcx> VnState<'_, 'tcx> {
17041706 /// dominate `loc`. If you used this place, add its base local to `reused_locals` to remove
17051707 /// storage statements.
17061708 #[ instrument( level = "trace" , skip( self ) , ret) ]
1707- fn try_as_place ( & mut self , mut index : VnIndex , loc : Location ) -> Option < Place < ' tcx > > {
1709+ fn try_as_place (
1710+ & mut self ,
1711+ mut index : VnIndex ,
1712+ loc : Location ,
1713+ allow_complex_projection : bool ,
1714+ ) -> Option < Place < ' tcx > > {
17081715 let mut projection = SmallVec :: < [ PlaceElem < ' tcx > ; 1 ] > :: new ( ) ;
17091716 loop {
17101717 if let Some ( local) = self . try_as_local ( index, loc) {
@@ -1713,6 +1720,7 @@ impl<'tcx> VnState<'_, 'tcx> {
17131720 Place { local, projection : self . tcx . mk_place_elems ( projection. as_slice ( ) ) } ;
17141721 return Some ( place) ;
17151722 } else if let Value :: Projection ( pointer, proj) = * self . get ( index)
1723+ && ( allow_complex_projection || proj. is_stable_offset ( ) )
17161724 && let Some ( proj) = self . try_as_place_elem ( proj, loc)
17171725 {
17181726 projection. push ( proj) ;
@@ -1773,7 +1781,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
17731781 if let Some ( value) = value {
17741782 if let Some ( const_) = self . try_as_constant ( value) {
17751783 * rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( const_) ) ) ;
1776- } else if let Some ( place) = self . try_as_place ( value, location)
1784+ } else if let Some ( place) = self . try_as_place ( value, location, false )
17771785 && * rvalue != Rvalue :: Use ( Operand :: Move ( place) )
17781786 && * rvalue != Rvalue :: Use ( Operand :: Copy ( place) )
17791787 {
0 commit comments