@@ -71,7 +71,7 @@ ObjectAllocator::ObjectAllocator(Compiler* comp)
7171// 
7272bool  ObjectAllocator::IsTrackedType (var_types type)
7373{
74-     const  bool  isTrackableScalar = (type == TYP_REF) || (genActualType (type) == TYP_I_IMPL) || ( type == TYP_BYREF);
74+     const  bool  isTrackableScalar = (type == TYP_REF) || (type == TYP_BYREF);
7575    return  isTrackableScalar;
7676}
7777
@@ -1579,12 +1579,19 @@ bool ObjectAllocator::CanLclVarEscapeViaParentStack(ArrayStack<GenTree*>* parent
15791579
15801580        switch  (parent->OperGet ())
15811581        {
1582-             //  Update the connection graph if we are storing to a local.
1583-             //  For all other stores we mark the local as escaping.
15841582            case  GT_STORE_LCL_VAR:
15851583            {
1586-                 //  Add an edge to the connection graph.
15871584                const  unsigned  int  dstLclNum = parent->AsLclVar ()->GetLclNum ();
1585+ 
1586+                 //  If we're not tracking stores to this local, the value
1587+                 //  does not escape.
1588+                 if  (!IsTrackedLocal (dstLclNum))
1589+                 {
1590+                     canLclVarEscapeViaParentStack = false ;
1591+                     break ;
1592+                 }
1593+ 
1594+                 //  Add an edge to the connection graph.
15881595                const  unsigned  int  srcLclNum = lclNum;
15891596
15901597                AddConnGraphEdge (dstLclNum, srcLclNum);
@@ -1626,13 +1633,25 @@ bool ObjectAllocator::CanLclVarEscapeViaParentStack(ArrayStack<GenTree*>* parent
16261633            case  GT_COLON:
16271634            case  GT_QMARK:
16281635            case  GT_ADD:
1629-             case  GT_SUB:
16301636            case  GT_FIELD_ADDR:
16311637                //  Check whether the local escapes via its grandparent.
16321638                ++parentIndex;
16331639                keepChecking = true ;
16341640                break ;
16351641
1642+             case  GT_SUB:
1643+                 //  Sub of two GC refs is no longer a GC ref.
1644+                 if  (!parent->TypeIs (TYP_BYREF, TYP_REF))
1645+                 {
1646+                     canLclVarEscapeViaParentStack = false ;
1647+                     break ;
1648+                 }
1649+ 
1650+                 //  Check whether the local escapes higher up
1651+                 ++parentIndex;
1652+                 keepChecking = true ;
1653+                 break ;
1654+ 
16361655            case  GT_BOX:
16371656                isCopy = wasCopy;
16381657                ++parentIndex;
@@ -1787,7 +1806,6 @@ void ObjectAllocator::UpdateAncestorTypes(GenTree* tree, ArrayStack<GenTree*>* p
17871806                FALLTHROUGH;
17881807            case  GT_QMARK:
17891808            case  GT_ADD:
1790-             case  GT_SUB:
17911809            case  GT_FIELD_ADDR:
17921810            case  GT_INDEX_ADDR:
17931811            case  GT_BOX:
@@ -1799,6 +1817,33 @@ void ObjectAllocator::UpdateAncestorTypes(GenTree* tree, ArrayStack<GenTree*>* p
17991817                keepChecking = true ;
18001818                break ;
18011819
1820+             case  GT_SUB:
1821+             {
1822+                 //  Parent type can be TYP_I_IMPL, TYP_BYREF.
1823+                 //  But not TYP_REF.
1824+                 // 
1825+                 var_types parentType = parent->TypeGet ();
1826+                 assert (parentType != TYP_REF);
1827+ 
1828+                 //  New type can be TYP_I_IMPL, TYP_BYREF.
1829+                 //  But TYP_BYREF only if parent is also
1830+                 // 
1831+                 if  (parentType != newType)
1832+                 {
1833+                     //  We must be retyping TYP_BYREF to TYP_I_IMPL.
1834+                     // 
1835+                     assert (newType == TYP_I_IMPL);
1836+                     assert (parentType == TYP_BYREF);
1837+                     parent->ChangeType (newType);
1838+ 
1839+                     //  Propgate that upwards.
1840+                     // 
1841+                     ++parentIndex;
1842+                     keepChecking = true ;
1843+                 }
1844+                 break ;
1845+             }
1846+ 
18021847            case  GT_COLON:
18031848            {
18041849                GenTree* const  lhs = parent->AsOp ()->gtGetOp1 ();
0 commit comments