diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index bd455e19f3d57..cc6ff733f4bba 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -2354,12 +2354,12 @@ bool Compiler::fgOptimizeEmptyBlock(BasicBlock* block) { case BBJ_COND: case BBJ_SWITCH: - case BBJ_THROW: /* can never happen */ - noway_assert(!"Conditional, switch, or throw block with empty body!"); + noway_assert(!"Conditional or switch block with empty body!"); break; + case BBJ_THROW: case BBJ_CALLFINALLY: case BBJ_RETURN: case BBJ_EHCATCHRET: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 4100eb7e29f94..0b083746808c4 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -11075,9 +11075,6 @@ GenTree* Compiler::impCastClassOrIsInstToTree(GenTree* op1, condTrue = gtNewIconNode(0, TYP_REF); } -#define USE_QMARK_TREES - -#ifdef USE_QMARK_TREES GenTree* qmarkMT; // // Generate first QMARK - COLON tree @@ -11091,6 +11088,12 @@ GenTree* Compiler::impCastClassOrIsInstToTree(GenTree* op1, temp = new (this, GT_COLON) GenTreeColon(TYP_REF, condTrue, condFalse); qmarkMT = gtNewQmarkNode(TYP_REF, condMT, temp); + if (isCastClass && impIsClassExact(pResolvedToken->hClass) && condTrue->OperIs(GT_CALL)) + { + // condTrue is used only for throwing InvalidCastException in case of casting to an exact class. + condTrue->AsCall()->gtCallMoreFlags |= GTF_CALL_M_DOES_NOT_RETURN; + } + GenTree* qmarkNull; // // Generate second QMARK - COLON tree @@ -11119,7 +11122,6 @@ GenTree* Compiler::impCastClassOrIsInstToTree(GenTree* op1, JITDUMP("Marked V%02u as a single def temp\n", tmp); lvaSetClass(tmp, pResolvedToken->hClass); return gtNewLclvNode(tmp, TYP_REF); -#endif } #ifndef DEBUG diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 6b31152a9978a..9122dbf0756d8 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -17689,6 +17689,11 @@ void Compiler::fgExpandQmarkForCastInstOf(BasicBlock* block, Statement* stmt) // Finally remove the nested qmark stmt. fgRemoveStmt(block, stmt); + if (true2Expr->OperIs(GT_CALL) && (true2Expr->AsCall()->gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN)) + { + fgConvertBBToThrowBB(helperBlock); + } + #ifdef DEBUG if (verbose) {