From dda7edd25f45fc6c3e6fa581aea725a8115886a8 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 16 Jun 2026 01:44:06 +0200 Subject: [PATCH 1/3] Improve nullability analysis in ValueNumStore::IsKnownNonNull --- src/coreclr/jit/valuenum.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 78029405054ccf..4afcf17e388e6d 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -1614,6 +1614,20 @@ ValueNumPair ValueNumStore::VNPWithExc(ValueNumPair vnp, ValueNumPair excSetVNP) bool ValueNumStore::IsKnownNonNull(ValueNum vn) { + if (vn == NoVN) + { + return false; + } + + assert(varTypeIsIntegralOrI(TypeOfVN(vn))); + + target_ssize_t offset; + PeelOffsets(&vn, &offset); + if (m_compiler->fgIsBigOffset(offset)) + { + return false; + } + auto vnVisitor = [this](ValueNum vn) -> VNVisit { if (vn != NoVN) { @@ -1623,10 +1637,20 @@ bool ValueNumStore::IsKnownNonNull(ValueNum vn) return VNVisit::Continue; } - VNFuncApp funcAttr; - if (GetVNFunc(vn, &funcAttr) && ((s_vnfOpAttribs[funcAttr.GetFunc()] & VNFOA_KnownNonNull) != 0)) + VNFuncApp funcApp; + if (GetVNFunc(vn, &funcApp)) { - return VNVisit::Continue; + // The address of an array element is non-null: on the non-exceptional path + // the array itself is non-null, so &array[index] cannot be null. + if (funcApp.FuncIs(VNF_PtrToArrElem)) + { + return VNVisit::Continue; + } + + if ((s_vnfOpAttribs[funcApp.GetFunc()] & VNFOA_KnownNonNull) != 0) + { + return VNVisit::Continue; + } } } return VNVisit::Abort; From d68854121bcd9f5c2d290bcbc689ef20702172e5 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 16 Jun 2026 01:55:50 +0200 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/jit/valuenum.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 4afcf17e388e6d..6b4bb20f584b70 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -1619,11 +1619,11 @@ bool ValueNumStore::IsKnownNonNull(ValueNum vn) return false; } - assert(varTypeIsIntegralOrI(TypeOfVN(vn))); + assert((TypeOfVN(vn) == TYP_I_IMPL) || (TypeOfVN(vn) == TYP_REF) || (TypeOfVN(vn) == TYP_BYREF)); target_ssize_t offset; PeelOffsets(&vn, &offset); - if (m_compiler->fgIsBigOffset(offset)) + if ((offset < 0) || m_compiler->fgIsBigOffset(static_cast(offset))) { return false; } From 92f1641135df63ade8396c36acf5397e4dcb7584 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 16 Jun 2026 02:00:18 +0200 Subject: [PATCH 3/3] fb --- src/coreclr/jit/valuenum.cpp | 14 ++------------ src/coreclr/jit/valuenumfuncs.h | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 6b4bb20f584b70..02416987bec776 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -1638,19 +1638,9 @@ bool ValueNumStore::IsKnownNonNull(ValueNum vn) } VNFuncApp funcApp; - if (GetVNFunc(vn, &funcApp)) + if (GetVNFunc(vn, &funcApp) && ((s_vnfOpAttribs[funcApp.GetFunc()] & VNFOA_KnownNonNull) != 0)) { - // The address of an array element is non-null: on the non-exceptional path - // the array itself is non-null, so &array[index] cannot be null. - if (funcApp.FuncIs(VNF_PtrToArrElem)) - { - return VNVisit::Continue; - } - - if ((s_vnfOpAttribs[funcApp.GetFunc()] & VNFOA_KnownNonNull) != 0) - { - return VNVisit::Continue; - } + return VNVisit::Continue; } } return VNVisit::Abort; diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index 461f2d2ddd18ab..14e233b206f982 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -14,7 +14,7 @@ ValueNumFuncDef(BitCast, 2, false, false) // Args: 0: VN of the arg, ValueNumFuncDef(ZeroObj, 1, false, false) // Args: 0: VN of the class handle. ValueNumFuncDef(PtrToLoc, 2, false, true) // Pointer (byref) to a local variable. Args: VN's of: 0: local's number, 1: offset. -ValueNumFuncDef(PtrToArrElem, 4, false, false) // Pointer (byref) to an array element. Args: 0: array elem type eq class var_types value, VN's of: 1: array, 2: index, 3: offset. +ValueNumFuncDef(PtrToArrElem, 4, false, true) // Pointer (byref) to an array element. Args: 0: array elem type eq class var_types value, VN's of: 1: array, 2: index, 3: offset. ValueNumFuncDef(PtrToStatic, 3, false, true) // Pointer (byref) to a static variable (or possibly a field thereof, if the static variable is a struct). // Args: 0: (VN of) the box's address if the static is "boxed", // 1: (VN of) the field sequence,