From 9be73dcc9b0063510222b7153dcff2ac52030db1 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 15 Jul 2026 19:56:14 +0200 Subject: [PATCH 1/2] Fold impossible type tests between unrelated classes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bfa09cf3-e00d-4d69-98d1-a03f33c6283e --- src/coreclr/jit/importer.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index f15a3409cbd529..84aa2d79cf9150 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5513,16 +5513,30 @@ 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) { - 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) + { + castMustFail = + info.compCompHnd->compareTypesForCast(toClass, fromClass) == TypeCompareState::MustNot; + } + } } - // 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"); @@ -5539,7 +5553,7 @@ GenTree* Compiler::impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_T } return gtNewNull(); } - else if (isExact) + else if (castMustFail) { JITDUMP("Not optimizing failing castclass (yet)\n"); } From 5c893bee89e2c10e52bb5d995ba963f77bf6d96d Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 15 Jul 2026 20:34:23 +0200 Subject: [PATCH 2/2] Clarify reverse cast check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bfa09cf3-e00d-4d69-98d1-a03f33c6283e --- src/coreclr/jit/importer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 84aa2d79cf9150..62897c3c65207b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5530,8 +5530,12 @@ GenTree* Compiler::impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_T const unsigned fromClassAttribs = info.compCompHnd->getClassAttribs(fromClass); if ((fromClassAttribs & nonClassTypeAttribs) == 0) { - castMustFail = - info.compCompHnd->compareTypesForCast(toClass, fromClass) == TypeCompareState::MustNot; + const TypeCompareState reverseCastResult = + info.compCompHnd->compareTypesForCast(toClass, fromClass); + if (reverseCastResult == TypeCompareState::MustNot) + { + castMustFail = true; + } } } }