@@ -980,7 +980,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
980
980
}
981
981
}
982
982
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 ) {
984
986
if rvalue. ty ( self . local_decls , self . tcx ) == place. ty ( self . local_decls , self . tcx ) . ty {
985
987
self . reused_locals . insert ( place. local ) ;
986
988
* rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
@@ -1665,7 +1667,7 @@ impl<'tcx> VnState<'_, 'tcx> {
1665
1667
fn try_as_operand ( & mut self , index : VnIndex , location : Location ) -> Option < Operand < ' tcx > > {
1666
1668
if let Some ( const_) = self . try_as_constant ( index) {
1667
1669
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 ) {
1669
1671
self . reused_locals . insert ( place. local ) ;
1670
1672
Some ( Operand :: Copy ( place) )
1671
1673
} else {
@@ -1704,7 +1706,12 @@ impl<'tcx> VnState<'_, 'tcx> {
1704
1706
/// dominate `loc`. If you used this place, add its base local to `reused_locals` to remove
1705
1707
/// storage statements.
1706
1708
#[ 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 > > {
1708
1715
let mut projection = SmallVec :: < [ PlaceElem < ' tcx > ; 1 ] > :: new ( ) ;
1709
1716
loop {
1710
1717
if let Some ( local) = self . try_as_local ( index, loc) {
@@ -1713,6 +1720,7 @@ impl<'tcx> VnState<'_, 'tcx> {
1713
1720
Place { local, projection : self . tcx . mk_place_elems ( projection. as_slice ( ) ) } ;
1714
1721
return Some ( place) ;
1715
1722
} else if let Value :: Projection ( pointer, proj) = * self . get ( index)
1723
+ && ( allow_complex_projection || proj. is_stable_offset ( ) )
1716
1724
&& let Some ( proj) = self . try_as_place_elem ( proj, loc)
1717
1725
{
1718
1726
projection. push ( proj) ;
@@ -1773,7 +1781,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1773
1781
if let Some ( value) = value {
1774
1782
if let Some ( const_) = self . try_as_constant ( value) {
1775
1783
* 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 )
1777
1785
&& * rvalue != Rvalue :: Use ( Operand :: Move ( place) )
1778
1786
&& * rvalue != Rvalue :: Use ( Operand :: Copy ( place) )
1779
1787
{
0 commit comments