diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index c28c48e0c67b66f794b9b18e60dab7dd2a5c082b..9891317505e82cdcf5a44b42069efee668a43576 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -1633,21 +1633,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 9264e6521a139eac898141a24ebfe353a01ccfca..f5a6c2bb565597d0e17bb3e9730ceefa24ed4fc3 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -12825,6 +12825,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 @@ -12842,17 +12843,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 df7891d025a2b48a727d6f4295e9faec47b1a47d..a78f4e160771543bb14efd45266ea8d22fc84bbf 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -20256,6 +20256,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; @@ -20292,7 +20302,7 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo, } if (inlCurArgInfo->argIsInvariant) { - printf(" is a constant"); + printf(" is a constant or invariant"); } if (inlCurArgInfo->argHasGlobRef) { @@ -20560,8 +20570,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; } @@ -20573,12 +20582,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; }