Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5513,16 +5513,34 @@ GenTree* Compiler::impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_T
}
else if (castResult == TypeCompareState::MustNot)
{
// See if we can sharpen exactness by looking for final classes
if (!isExact)
// See if we can prove that no subtype of fromClass can be cast to toClass.
bool castMustFail = isExact || info.compCompHnd->isExactType(fromClass);

if (!castMustFail && !isCastClass)
Comment thread
EgorBo marked this conversation as resolved.
{
isExact = info.compCompHnd->isExactType(fromClass);
constexpr unsigned nonClassTypeAttribs = CORINFO_FLG_ARRAY | CORINFO_FLG_DELEGATE |
CORINFO_FLG_GENERIC_TYPE_VARIABLE | CORINFO_FLG_INTERFACE |
CORINFO_FLG_VALUECLASS;

// If both types are ordinary classes and neither derives from the other,
// then their class hierarchies cannot overlap.
const unsigned toClassAttribs = info.compCompHnd->getClassAttribs(toClass);
if ((toClassAttribs & nonClassTypeAttribs) == 0)
{
const unsigned fromClassAttribs = info.compCompHnd->getClassAttribs(fromClass);
if ((fromClassAttribs & nonClassTypeAttribs) == 0)
{
const TypeCompareState reverseCastResult =
info.compCompHnd->compareTypesForCast(toClass, fromClass);
if (reverseCastResult == TypeCompareState::MustNot)
{
castMustFail = true;
}
}
}
}

// Cast to exact type will fail. Handle case where we have
// an exact type (that is, fromClass is not a subtype)
// and we're not going to throw on failure.
if (isExact && !isCastClass)
if (castMustFail && !isCastClass)
{
JITDUMP("Cast will fail, optimizing to return null\n");

Expand All @@ -5539,7 +5557,7 @@ GenTree* Compiler::impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_T
}
return gtNewNull();
}
else if (isExact)
else if (castMustFail)
{
JITDUMP("Not optimizing failing castclass (yet)\n");
}
Expand Down
Loading