diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2cefdf1c92bcc..933f4d6078da1 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -8166,6 +8166,7 @@ class Compiler // Get the flags bool eeIsValueClass(CORINFO_CLASS_HANDLE clsHnd); + bool eeIsByrefLike(CORINFO_CLASS_HANDLE clsHnd); bool eeIsIntrinsic(CORINFO_METHOD_HANDLE ftn); bool eeIsFieldStatic(CORINFO_FIELD_HANDLE fldHnd); diff --git a/src/coreclr/jit/ee_il_dll.hpp b/src/coreclr/jit/ee_il_dll.hpp index d676ba8caa479..237d43ef762e5 100644 --- a/src/coreclr/jit/ee_il_dll.hpp +++ b/src/coreclr/jit/ee_il_dll.hpp @@ -53,6 +53,12 @@ bool Compiler::eeIsValueClass(CORINFO_CLASS_HANDLE clsHnd) return info.compCompHnd->isValueClass(clsHnd); } +FORCEINLINE +bool Compiler::eeIsByrefLike(CORINFO_CLASS_HANDLE clsHnd) +{ + return (info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_BYREF_LIKE) != 0; +} + FORCEINLINE bool Compiler::eeIsIntrinsic(CORINFO_METHOD_HANDLE ftn) { diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index be74838c190f2..448ee995579af 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -2672,8 +2672,7 @@ bool Compiler::verCheckTailCallConstraint(OPCODE opcode, } // Check that the argument is not a byref-like for tailcalls. - if ((ciType == CORINFO_TYPE_VALUECLASS) && - ((info.compCompHnd->getClassAttribs(classHandle) & CORINFO_FLG_BYREF_LIKE) != 0)) + if ((ciType == CORINFO_TYPE_VALUECLASS) && eeIsByrefLike(classHandle)) { return false; } @@ -10121,8 +10120,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) break; } - bool isByRefLike = - (info.compCompHnd->getClassAttribs(resolvedToken.hClass) & CORINFO_FLG_BYREF_LIKE) != 0; + bool isByRefLike = eeIsByrefLike(resolvedToken.hClass); if (isByRefLike) { // For ByRefLike types we are required to either fold the diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index ae003b934cc8b..e7889ed79fccd 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3885,8 +3885,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, retNode = gtNewIconNode(eeIsValueClass(hClass) ? 1 : 0); break; case NI_System_Type_get_IsByRefLike: - retNode = gtNewIconNode( - (info.compCompHnd->getClassAttribs(hClass) & CORINFO_FLG_BYREF_LIKE) ? 1 : 0); + retNode = gtNewIconNode(eeIsByrefLike(hClass) ? 1 : 0); break; case NI_System_Type_get_IsPrimitive: // getTypeForPrimitiveValueClass returns underlying type for enums, so we check it first diff --git a/src/coreclr/jit/layout.cpp b/src/coreclr/jit/layout.cpp index 8de93f838971f..655750718bc73 100644 --- a/src/coreclr/jit/layout.cpp +++ b/src/coreclr/jit/layout.cpp @@ -432,8 +432,7 @@ void ClassLayout::InitializeGCPtrs(Compiler* compiler) bool ClassLayout::IsStackOnly(Compiler* comp) const { // Byref-like structs are stack only - if ((m_classHandle != NO_CLASS_HANDLE) && - (((comp->info.compCompHnd->getClassAttribs(m_classHandle)) & CORINFO_FLG_BYREF_LIKE) != 0)) + if ((m_classHandle != NO_CLASS_HANDLE) && comp->eeIsByrefLike(m_classHandle)) { return true; } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 4c841f8c7f1f8..e5ac22723ab9d 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7735,6 +7735,19 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA } break; + case GT_STOREIND: + if (op1->OperIs(GT_FIELD_ADDR) && varTypeIsGC(tree)) + { + CORINFO_FIELD_HANDLE fieldHandle = op1->AsFieldAddr()->gtFldHnd; + if (eeIsByrefLike(info.compCompHnd->getFieldClass(fieldHandle))) + { + JITDUMP("Marking [%06u] STOREIND as GTF_IND_TGT_NOT_HEAP: field's owner is a byref-like struct\n", + dspTreeID(tree)); + tree->gtFlags |= GTF_IND_TGT_NOT_HEAP; + } + } + break; + case GT_DIV: // Replace "val / dcon" with "val * (1.0 / dcon)" if dcon is a power of two. // Powers of two within range are always exactly represented,