Allow more obj(addr(lcl_var) foldings. (#42343)
authorSergey Andreenko <seandree@microsoft.com>
Fri, 18 Sep 2020 05:21:29 +0000 (22:21 -0700)
committerGitHub <noreply@github.com>
Fri, 18 Sep 2020 05:21:29 +0000 (22:21 -0700)
* Allow `struct<N> with no GCPointers <-> block<N>` replacements.

* Alllow local morph to fold `OBJ(ADDR(LCL_VAR))` when obj and lclVar loayouts are compatible.

src/coreclr/src/jit/layout.cpp
src/coreclr/src/jit/lclmorph.cpp

index bafe17b..87b0bef 100644 (file)
@@ -430,10 +430,8 @@ bool ClassLayout::AreCompatible(const ClassLayout* layout1, const ClassLayout* l
 {
     CORINFO_CLASS_HANDLE clsHnd1 = layout1->GetClassHandle();
     CORINFO_CLASS_HANDLE clsHnd2 = layout2->GetClassHandle();
-    assert(clsHnd1 != NO_CLASS_HANDLE);
-    assert(clsHnd2 != NO_CLASS_HANDLE);
 
-    if (clsHnd1 == clsHnd2)
+    if ((clsHnd1 != NO_CLASS_HANDLE) && (clsHnd1 == clsHnd2))
     {
         return true;
     }
@@ -453,7 +451,10 @@ bool ClassLayout::AreCompatible(const ClassLayout* layout1, const ClassLayout* l
         return true;
     }
 
+    assert(clsHnd1 != NO_CLASS_HANDLE);
+    assert(clsHnd2 != NO_CLASS_HANDLE);
     assert(layout1->HasGCPtr() && layout2->HasGCPtr());
+
     if (layout1->GetGCPtrCount() != layout2->GetGCPtrCount())
     {
         return false;
index 1df4935..811cfc0 100644 (file)
@@ -1021,7 +1021,8 @@ private:
         // otherwise the below layout equality check would be insufficient.
         assert(varDsc->GetLayout() != nullptr);
 
-        if ((val.Offset() == 0) && (structLayout == varDsc->GetLayout()))
+        if ((val.Offset() == 0) && (structLayout != nullptr) &&
+            ClassLayout::AreCompatible(structLayout, varDsc->GetLayout()))
         {
             indir->ChangeOper(GT_LCL_VAR);
             indir->AsLclVar()->SetLclNum(val.LclNum());