Skip to content

Commit 3d40d73

Browse files
AndyAyersMSCopilot
andauthored
JIT: recognize CORINFO_HELP_BOX in impThrowIfNull (#129392)
In Tier0 struct boxes are emitted as direct CORINFO_HELP_BOX helper calls rather than GT_BOX nodes; recognize this form too so Tier0 ThrowIfNull(struct) doesn't allocate. Fixes #128574. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f003ba4 commit 3d40d73

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

src/coreclr/jit/importercalls.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,35 @@ GenTree* Compiler::impThrowIfNull(GenTreeCall* call)
16391639
return gtNewNothingNode();
16401640
}
16411641

1642+
// Case 1b: value-type (non-nullable) boxed via CORINFO_HELP_BOX helper.
1643+
// In Tier0 (and other size-constrained modes) struct boxes are emitted as a
1644+
// direct helper call rather than GT_BOX. The helper always returns non-null,
1645+
// so the ThrowIfNull is a no-op aside from the side effects of computing the
1646+
// helper's address argument and the valueName.
1647+
//
1648+
// ArgumentNullException_ThrowIfNull(CORINFO_HELP_BOX(clsHnd, addr), valueName)
1649+
// ->
1650+
// NOP (with side-effects of addr and valueName preserved)
1651+
//
1652+
if (value->IsHelperCall(CORINFO_HELP_BOX))
1653+
{
1654+
GenTree* boxHelperClsArg = value->AsCall()->gtArgs.GetUserArgByIndex(0)->GetNode();
1655+
GenTree* boxHelperAddrArg = value->AsCall()->gtArgs.GetUserArgByIndex(1)->GetNode();
1656+
1657+
if ((boxHelperClsArg->gtFlags & GTF_SIDE_EFFECT) != 0)
1658+
{
1659+
// The class handle is normally a constant; bail if not.
1660+
return call;
1661+
}
1662+
1663+
// Spill addr then valueName to preserve evaluation order of any side effects.
1664+
unsigned boxedAddrTmp = lvaGrabTemp(true DEBUGARG("boxedAddr spilled"));
1665+
unsigned boxedArgNameTmp = lvaGrabTemp(true DEBUGARG("boxedArg spilled"));
1666+
impStoreToTemp(boxedAddrTmp, boxHelperAddrArg, CHECK_SPILL_ALL);
1667+
impStoreToTemp(boxedArgNameTmp, valueName, CHECK_SPILL_ALL);
1668+
return gtNewNothingNode();
1669+
}
1670+
16421671
// Case 2: nullable:
16431672
//
16441673
// ArgumentNullException.ThrowIfNull(CORINFO_HELP_BOX_NULLABLE(classHandle, addr), valueName);

0 commit comments

Comments
 (0)