From 2e82d6174f236816312b82985fab6b0dea5e844c Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 27 Sep 2026 16:15:49 +0200 Subject: [PATCH 1/2] JIT: Extend non-null assertion propagation to pointer-sized comparisons Use existing non-null assertions, including offset and PHI reasoning, when folding equality comparisons against zero. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e05d15f9-4ceb-4f50-9f11-1926af5515df --- src/coreclr/jit/assertionprop.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index d51d8d852e2241..348f26e188d976 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -4691,19 +4691,12 @@ GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, return nullptr; } - // See if we have "PHI ==/!= null" tree. If so, we iterate over all PHI's arguments, - // and if all of them are known to be non-null, we can bash the comparison to true/false. - if (op2->IsIntegralConst(0) && op1->TypeIs(TYP_REF)) + // Use non-null assertions for the address or its base, including across PHIs. + if (op2->IsIntegralConst(0) && varTypeIsI(op1)) { - JITDUMP("Checking PHI [%06u] arguments for non-nullness\n", dspTreeID(op1)) - auto visitor = [this](ValueNum reachingVN, ASSERT_TP reachingAssertions) { - return optAssertionVNIsNonNull(reachingVN, reachingAssertions) ? AssertVisit::Continue : AssertVisit::Abort; - }; - - ValueNum op1vn = vnStore->VNConservativeNormalValue(op1->gtVNPair); - if (optVisitReachingAssertions(op1vn, visitor) == AssertVisit::Continue) + if (optAssertionVNIsNonNull(op1VN, assertions)) { - JITDUMP("... all of PHI's arguments are never null!\n"); + JITDUMP("Proved [%06u] non-null\n", dspTreeID(op1)); assert(newTree->OperIs(GT_EQ, GT_NE)); newTree = tree->OperIs(GT_EQ) ? gtNewIconNode(0) : gtNewIconNode(1); return optAssertionProp_Update(newTree, tree, stmt); From 4a062ab28d28423f69cc0bb8e8078a295217ebe0 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 27 Sep 2026 17:12:13 +0200 Subject: [PATCH 2/2] JIT: Guard non-null assertion propagation by VN type Reject non-pointer-sized VNs before peeling offsets, including small-type PHIs referenced by int nodes on 32-bit targets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e05d15f9-4ceb-4f50-9f11-1926af5515df --- src/coreclr/jit/assertionprop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 348f26e188d976..359a8c69cc526b 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -5270,7 +5270,7 @@ bool Compiler::optAssertionIsNonNull(GenTree* op, ASSERT_VALARG_TP assertions) // bool Compiler::optAssertionVNIsNonNull(ValueNum vn, ASSERT_VALARG_TP assertions, int budget) { - if (vn == ValueNumStore::NoVN) + if ((vn == ValueNumStore::NoVN) || !varTypeIsI(vnStore->TypeOfVN(vn))) { return false; }