Skip to content

Commit c9d3d3e

Browse files
authored
RyuJIT: Don't emit null checks for constant strings (#37245)
* Fold "ldstr ==/!== null" (mikedn's PR) * Formatting * check IsUnsigned for GT_GT * Address feedback
1 parent 7eba836 commit c9d3d3e

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

src/coreclr/src/jit/flowgraph.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7321,6 +7321,10 @@ bool Compiler::fgAddrCouldBeNull(GenTree* addr)
73217321
{
73227322
return false;
73237323
}
7324+
else if (addr->OperIs(GT_CNS_STR))
7325+
{
7326+
return false;
7327+
}
73247328
else if (addr->gtOper == GT_LCL_VAR)
73257329
{
73267330
unsigned varNum = addr->AsLclVarCommon()->GetLclNum();
@@ -23763,10 +23767,13 @@ Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
2376323767
if (call->gtFlags & GTF_CALL_NULLCHECK && !inlineInfo->thisDereferencedFirst)
2376423768
{
2376523769
// Call impInlineFetchArg to "reserve" a temp for the "this" pointer.
23766-
nullcheck = gtNewNullCheck(impInlineFetchArg(0, inlArgInfo, lclVarInfo), block);
23767-
23768-
// The NULL-check statement will be inserted to the statement list after those statements
23769-
// that assign arguments to temps and before the actual body of the inlinee method.
23770+
GenTree* thisOp = impInlineFetchArg(0, inlArgInfo, lclVarInfo);
23771+
if (fgAddrCouldBeNull(thisOp))
23772+
{
23773+
nullcheck = gtNewNullCheck(impInlineFetchArg(0, inlArgInfo, lclVarInfo), block);
23774+
// The NULL-check statement will be inserted to the statement list after those statements
23775+
// that assign arguments to temps and before the actual body of the inlinee method.
23776+
}
2377023777
}
2377123778

2377223779
/* Treat arguments that had to be assigned to temps */

src/coreclr/src/jit/gentree.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14531,8 +14531,22 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree)
1453114531

1453214532
/* String nodes are an RVA at this point */
1453314533

14534-
if (op1->gtOper == GT_CNS_STR || op2->gtOper == GT_CNS_STR)
14534+
if (op1->OperIs(GT_CNS_STR) || op2->OperIs(GT_CNS_STR))
1453514535
{
14536+
// Fold "ldstr" ==/!= null
14537+
if (op2->IsIntegralConst(0))
14538+
{
14539+
if (tree->OperIs(GT_EQ))
14540+
{
14541+
i1 = 0;
14542+
goto FOLD_COND;
14543+
}
14544+
if (tree->OperIs(GT_NE) || (tree->OperIs(GT_GT) && tree->IsUnsigned()))
14545+
{
14546+
i1 = 1;
14547+
goto FOLD_COND;
14548+
}
14549+
}
1453614550
return tree;
1453714551
}
1453814552

src/coreclr/src/jit/morph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6110,8 +6110,8 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac)
61106110

61116111
bool addExplicitNullCheck = false;
61126112

6113-
// Implicit byref locals are never null.
6114-
if (!((objRef->gtOper == GT_LCL_VAR) && lvaIsImplicitByRefLocal(objRef->AsLclVarCommon()->GetLclNum())))
6113+
// Implicit byref locals and string literals are never null.
6114+
if (fgAddrCouldBeNull(objRef))
61156115
{
61166116
// If the objRef is a GT_ADDR node, it, itself, never requires null checking. The expression
61176117
// whose address is being taken is either a local or static variable, whose address is necessarily

0 commit comments

Comments
 (0)