diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 7d836353baea18..30a66726279ca2 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2610,6 +2610,37 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) { *resultVN = VNForIntCon(knownSize); } + + // Case 4: ARR_LENGTH(new T[(long)size]) -> size + VNFuncApp newArrFuncApp; + if (GetVNFunc(arg0VN, &newArrFuncApp) && (newArrFuncApp.m_func == VNF_JitNewArr)) + { + ValueNum actualSizeVN = newArrFuncApp.m_args[1]; + var_types actualSizeVNType = TypeOfVN(actualSizeVN); + + // JitNewArr's size argument (args[1]) is typically upcasted to TYP_LONG via VNF_Cast. + if (actualSizeVNType == TYP_LONG) + { + VNFuncApp castFuncApp; + if (GetVNFunc(actualSizeVN, &castFuncApp) && (castFuncApp.m_func == VNF_Cast)) + { + var_types castToType; + bool srcIsUnsigned; + GetCastOperFromVN(castFuncApp.m_args[1], &castToType, &srcIsUnsigned); + + // Make sure we have exactly (TYP_LONG)myInt32 cast: + if (!srcIsUnsigned && (castToType == TYP_LONG) && TypeOfVN(castFuncApp.m_args[0]) == TYP_INT) + { + // If that is the case, return the original size argument + *resultVN = castFuncApp.m_args[0]; + } + } + } + else if (actualSizeVNType == TYP_INT) + { + *resultVN = actualSizeVN; + } + } } // Try to perform constant-folding.