diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index d59301991aaa61..9232c9a0ee5dd5 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -1604,21 +1604,12 @@ Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo) } else { - /* The argument is either not used or a const or lcl var */ - + // The argument is either not used or a const or lcl var noway_assert(!argInfo.argIsUsed || argInfo.argIsInvariant || argInfo.argIsLclVar); - - /* Make sure we didnt change argNode's along the way, or else - subsequent uses of the arg would have worked with the bashed value */ - if (argInfo.argIsInvariant) - { - assert(argNode->OperIsConst() || argNode->gtOper == GT_ADDR); - } noway_assert((argInfo.argIsLclVar == 0) == (argNode->gtOper != GT_LCL_VAR || (argNode->gtFlags & GTF_GLOB_REF))); - /* If the argument has side effects, append it */ - + // If the argument has side effects, append it if (argInfo.argHasSideEff) { noway_assert(argInfo.argIsUsed == false); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index ae7583871a2bc7..065d122b82fac6 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -12896,6 +12896,7 @@ GenTree* Compiler::gtCreateHandleCompare(genTreeOps oper, // Checks for // typeof(...) == obj.GetType() // typeof(...) == typeof(...) +// typeof(...) == null // obj1.GetType() == obj2.GetType() // // And potentially optimizes away the need to obtain actual @@ -12913,17 +12914,19 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) // Screen for the right kinds of operands GenTree* const op1 = tree->AsOp()->gtOp1; - const TypeProducerKind op1Kind = gtGetTypeProducerKind(op1); - if (op1Kind == TPK_Unknown) - { - return tree; - } - GenTree* const op2 = tree->AsOp()->gtOp2; + const TypeProducerKind op1Kind = gtGetTypeProducerKind(op1); const TypeProducerKind op2Kind = gtGetTypeProducerKind(op2); - if (op2Kind == TPK_Unknown) + + // Fold "typeof(handle) cmp null" + if (((op2Kind == TPK_Null) && (op1Kind == TPK_Handle)) || ((op1Kind == TPK_Null) && (op2Kind == TPK_Handle))) { - return tree; + GenTree* call = op1Kind == TPK_Handle ? op1 : op2; + GenTree* handle = call->AsCall()->gtArgs.GetArgByIndex(0)->GetNode(); + if (gtGetHelperArgClassHandle(handle) != NO_CLASS_HANDLE) + { + return oper == GT_EQ ? gtNewFalse() : gtNewTrue(); + } } // If both types are created via handles, we can simply compare diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 8cff503d5eabeb..e9b647b9114b52 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -20206,6 +20206,16 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo, return; } } + else + { + if (curArgVal->IsHelperCall() && gtIsTypeHandleToRuntimeTypeHelper(curArgVal->AsCall()) && + (gtGetHelperArgClassHandle(curArgVal->AsCall()->gtArgs.GetArgByIndex(0)->GetEarlyNode()) != + NO_CLASS_HANDLE)) + { + inlCurArgInfo->argIsInvariant = true; + inlCurArgInfo->argHasSideEff = false; + } + } bool isExact = false; bool isNonNull = false; @@ -20242,7 +20252,7 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo, } if (inlCurArgInfo->argIsInvariant) { - printf(" is a constant"); + printf(" is a constant or invariant"); } if (inlCurArgInfo->argHasGlobRef) { @@ -20510,8 +20520,7 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) // Try to fold the node in case we have constant arguments. if (inlArgInfo[i].argIsInvariant) { - inlArgNode = gtFoldExprConst(inlArgNode); - assert(inlArgNode->OperIsConst()); + inlArgNode = gtFoldExpr(inlArgNode); } *pInlArgNode = inlArgNode; } @@ -20523,12 +20532,10 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) inlArgInfo[i].argIsLclVar = false; - /* Try to fold the node in case we have constant arguments */ - + // Try to fold the node in case we have constant arguments. if (inlArgInfo[i].argIsInvariant) { - inlArgNode = gtFoldExprConst(inlArgNode); - assert(inlArgNode->OperIsConst()); + inlArgNode = gtFoldExpr(inlArgNode); } *pInlArgNode = inlArgNode; }