diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 5f6352d8fc2e6..f158eb485ca60 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3169,37 +3169,35 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool assert(varDsc->lvSingleDef); // Now see if we should update. - // + // New information may not always be "better" so do some // simple analysis to decide if the update is worthwhile. const bool isNewClass = (clsHnd != varDsc->lvClassHnd); bool shouldUpdate = false; - // Are we attempting to update the class? Only check this when we have - // an new type and the existing class is inexact... we should not be - // updating exact classes. - if (!varDsc->lvClassIsExact && isNewClass) + // Are we attempting to update exactness? + if (isExact && !varDsc->lvClassIsExact) { - shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); + shouldUpdate = true; } - // Else are we attempting to update exactness? - else if (isExact && !varDsc->lvClassIsExact && !isNewClass) + // Are we attempting to update the class? + else if (isNewClass) { - shouldUpdate = true; + shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); } -#if DEBUG - if (isNewClass || (isExact != varDsc->lvClassIsExact)) + if (shouldUpdate) { +#if DEBUG JITDUMP("\nlvaUpdateClass:%s Updating class for V%02u", shouldUpdate ? "" : " NOT", varNum); JITDUMP(" from (%p) %s%s", dspPtr(varDsc->lvClassHnd), eeGetClassName(varDsc->lvClassHnd), varDsc->lvClassIsExact ? " [exact]" : ""); JITDUMP(" to (%p) %s%s\n", dspPtr(clsHnd), eeGetClassName(clsHnd), isExact ? " [exact]" : ""); - } #endif // DEBUG - if (shouldUpdate) - { + assert(!varDsc->lvClassIsExact || + ((info.compCompHnd->getClassAttribs(varDsc->lvClassHnd) & CORINFO_FLG_SHAREDINST) != 0)); + varDsc->lvClassHnd = clsHnd; varDsc->lvClassIsExact = isExact; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 453e80c381e5c..a20eb57a22507 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2860,8 +2860,9 @@ private bool isMoreSpecificType(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUC if (isType1CanonSubtype != isType2CanonSubtype) { // Only one of type1 and type2 is shared. - // type2 is more specific if type1 is the shared type. - return isType1CanonSubtype; + // type2 is more specific if type1 can't be assigned there. + return isType1CanonSubtype && !type1.CanCastTo(type2) || + isType2CanonSubtype && type2.CanCastTo(type1); } // Otherwise both types are either shared or not shared. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b7dcf9eacd88e..c1dd47a747dec 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4563,8 +4563,9 @@ static BOOL isMoreSpecificTypeHelper( if (isHnd1CanonSubtype != isHnd2CanonSubtype) { // Only one of hnd1 and hnd2 is shared. - // hdn2 is more specific if hnd1 is the shared type. - return isHnd1CanonSubtype; + // hdn2 is more specific if hnd1 can't be assigned there. + return (isHnd1CanonSubtype && !hnd1.CanCastTo(hnd2)) || + (isHnd2CanonSubtype && hnd2.CanCastTo(hnd1)); } // Otherwise both types are either shared or not shared.