From a555502ad3e1a4b4a549d0c51aeb03790f15f383 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 20 Mar 2023 13:10:57 -0700 Subject: [PATCH 1/8] Initial work --- src/coreclr/jit/valuenum.cpp | 58 ++++++++++++++++++++++++++++++++++++ src/coreclr/jit/valuenum.h | 3 ++ 2 files changed, 61 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 326dccb18f188..d8cde8bf8b637 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -4714,6 +4714,14 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN { resultVN = VNOneForType(typ); } + else if ((genTreeOps(func) == GT_GE) && varTypeIsIntegralOrI(TypeOfVN(arg0VN))) + { + ZeroVN = VNZeroForType(typ); + if ((arg1VN == ZeroVN) && IsVNNeverNegative(arg0VN)) + { + resultVN = VNOneForType(typ); + } + } break; case GT_NE: @@ -4773,6 +4781,14 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN { resultVN = VNZeroForType(typ); } + else if ((genTreeOps(func) == GT_LT) && varTypeIsIntegralOrI(TypeOfVN(arg0VN))) + { + ZeroVN = VNZeroForType(typ); + if ((arg1VN == ZeroVN) && IsVNNeverNegative(arg0VN)) + { + resultVN = ZeroVN; + } + } break; default: @@ -5618,6 +5634,48 @@ bool ValueNumStore::IsVNInt32Constant(ValueNum vn) return TypeOfVN(vn) == TYP_INT; } +bool ValueNumStore::IsVNNeverNegative(ValueNum vn) +{ + if (IsVNConstant(vn)) + { + var_types vnTy = TypeOfVN(vn); + if (varTypeIsIntegral(vnTy)) + { + if (vnTy == TYP_INT) + { + return GetConstantInt32(vn) >= 0; + } + else if (vnTy == TYP_LONG) + { + return GetConstantInt64(vn) >= 0; + } + } + + return false; + } + + VNFuncApp funcApp; + if (GetVNFunc(vn, &funcApp)) + { + switch (funcApp.m_func) + { +#ifdef TARGET_XARCH + case VNF_HWI_POPCNT_PopCount: + case VNF_HWI_POPCNT_X64_PopCount: + return true; +#elif TARGET_ARM64 + case VNF_HWI_AdvSimd_PopCount: + return true; +#endif + + default: + break; + } + } + + return false; +} + GenTreeFlags ValueNumStore::GetHandleFlags(ValueNum vn) { assert(IsVNHandle(vn)); diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 50f780c1be96e..31ebe77ed9a18 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -863,6 +863,9 @@ class ValueNumStore // Returns true iff the VN represents an integer constant. bool IsVNInt32Constant(ValueNum vn); + // Returns true if the VN represents a node that is never negative. + bool IsVNNeverNegative(ValueNum vn); + typedef SmallHashTable CheckedBoundVNSet; // Returns true if the VN is known or likely to appear as the conservative value number From 74ff417a38c9394e88b848c048b19f87cb7e7309 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 20 Mar 2023 13:25:35 -0700 Subject: [PATCH 2/8] Handle arrlen case --- src/coreclr/jit/valuenum.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index d8cde8bf8b637..43f2fc1ab7ba5 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5654,6 +5654,12 @@ bool ValueNumStore::IsVNNeverNegative(ValueNum vn) return false; } + // Array length can never be negative. + if (IsVNArrLen(vn)) + { + return true; + } + VNFuncApp funcApp; if (GetVNFunc(vn, &funcApp)) { From 5a9bfab8e26e732756bdf71be5fce443a2be5ed5 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 20 Mar 2023 13:53:22 -0700 Subject: [PATCH 3/8] Added ifdef --- src/coreclr/jit/valuenum.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 43f2fc1ab7ba5..3a0beb472b9cd 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5665,6 +5665,7 @@ bool ValueNumStore::IsVNNeverNegative(ValueNum vn) { switch (funcApp.m_func) { +#ifdef FEATURE_HW_INTRINSICS #ifdef TARGET_XARCH case VNF_HWI_POPCNT_PopCount: case VNF_HWI_POPCNT_X64_PopCount: @@ -5673,6 +5674,7 @@ bool ValueNumStore::IsVNNeverNegative(ValueNum vn) case VNF_HWI_AdvSimd_PopCount: return true; #endif +#endif // FEATURE_HW_INTRINSICS default: break; From 4ca7ec1ac5c991ccc2beb35687cc109581e2fd9d Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 30 Mar 2023 14:28:41 -0700 Subject: [PATCH 4/8] Additional cases --- src/coreclr/jit/valuenum.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 1ac33dd27e840..1e48640127636 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5669,9 +5669,18 @@ bool ValueNumStore::IsVNNeverNegative(ValueNum vn) #ifdef TARGET_XARCH case VNF_HWI_POPCNT_PopCount: case VNF_HWI_POPCNT_X64_PopCount: + case VNF_HWI_LZCNT_LeadingZeroCount: + case VNF_HWI_LZCNT_X64_LeadingZeroCount: + case VNF_HWI_BMI1_TrailingZeroCount: + case VNF_HWI_BMI1_X64_TrailingZeroCount: return true; #elif TARGET_ARM64 case VNF_HWI_AdvSimd_PopCount: + case VNF_HWI_AdvSimd_LeadingZeroCount: + case VNF_HWI_AdvSimd_LeadingSignCount: + case VNF_HWI_ArmBase_LeadingZeroCount: + case VNF_HWI_ArmBase_Arm64_LeadingZeroCount: + case VNF_HWI_ArmBase_Arm64_LeadingSignCount: return true; #endif #endif // FEATURE_HW_INTRINSICS From 1c10a211412ad7cdcb8bc18f61a8591f04da91e7 Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 30 Mar 2023 14:43:39 -0700 Subject: [PATCH 5/8] Additional cases --- src/coreclr/jit/valuenum.cpp | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 1e48640127636..2f4cd0d4aea25 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -4714,12 +4714,24 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN { resultVN = VNOneForType(typ); } - else if ((genTreeOps(func) == GT_GE) && varTypeIsIntegralOrI(TypeOfVN(arg0VN))) + else if (varTypeIsIntegralOrI(TypeOfVN(arg0VN))) { ZeroVN = VNZeroForType(typ); - if ((arg1VN == ZeroVN) && IsVNNeverNegative(arg0VN)) + if (genTreeOps(func) == GT_GE) { - resultVN = VNOneForType(typ); + // (never negative) >= 0 == true + if ((arg1VN == ZeroVN) && IsVNNeverNegative(arg0VN)) + { + resultVN = VNOneForType(typ); + } + } + else if (genTreeOps(func) == GT_LE) + { + // 0 <= (never negative) == true + if ((arg0VN == ZeroVN) && IsVNNeverNegative(arg1VN)) + { + resultVN = VNOneForType(typ); + } } } break; @@ -4781,12 +4793,24 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN { resultVN = VNZeroForType(typ); } - else if ((genTreeOps(func) == GT_LT) && varTypeIsIntegralOrI(TypeOfVN(arg0VN))) + else if (varTypeIsIntegralOrI(TypeOfVN(arg0VN))) { ZeroVN = VNZeroForType(typ); - if ((arg1VN == ZeroVN) && IsVNNeverNegative(arg0VN)) + if (genTreeOps(func) == GT_LT) { - resultVN = ZeroVN; + // (never negative) < 0 == false + if ((arg1VN == ZeroVN) && IsVNNeverNegative(arg0VN)) + { + resultVN = ZeroVN; + } + } + else if (genTreeOps(func) == GT_GT) + { + // 0 > (never negative) == false + if ((arg0VN == ZeroVN) && IsVNNeverNegative(arg1VN)) + { + resultVN = ZeroVN; + } } } break; From 9f096f0a89b3413da71406163e85352b1c835c39 Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 31 Mar 2023 15:12:46 -0700 Subject: [PATCH 6/8] Add assert to IsVNNeverNegative --- src/coreclr/jit/valuenum.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 2f4cd0d4aea25..5bf1db8a97cf8 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5660,19 +5660,18 @@ bool ValueNumStore::IsVNInt32Constant(ValueNum vn) bool ValueNumStore::IsVNNeverNegative(ValueNum vn) { + assert(varTypeIsIntegral(TypeOfVN(vn))); + if (IsVNConstant(vn)) { var_types vnTy = TypeOfVN(vn); - if (varTypeIsIntegral(vnTy)) + if (vnTy == TYP_INT) { - if (vnTy == TYP_INT) - { - return GetConstantInt32(vn) >= 0; - } - else if (vnTy == TYP_LONG) - { - return GetConstantInt64(vn) >= 0; - } + return GetConstantInt32(vn) >= 0; + } + else if (vnTy == TYP_LONG) + { + return GetConstantInt64(vn) >= 0; } return false; From 69c79bdd11467ab448942fa04d45fa5a45c72184 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Mon, 3 Apr 2023 12:32:35 -0700 Subject: [PATCH 7/8] Update src/coreclr/jit/valuenum.cpp Co-authored-by: Bruce Forstall --- src/coreclr/jit/valuenum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 5bf1db8a97cf8..cd369d8d70a9e 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5697,7 +5697,7 @@ bool ValueNumStore::IsVNNeverNegative(ValueNum vn) case VNF_HWI_BMI1_TrailingZeroCount: case VNF_HWI_BMI1_X64_TrailingZeroCount: return true; -#elif TARGET_ARM64 +#elif defined(TARGET_ARM64) case VNF_HWI_AdvSimd_PopCount: case VNF_HWI_AdvSimd_LeadingZeroCount: case VNF_HWI_AdvSimd_LeadingSignCount: From d6665c28dcbf7c71ec28969eb6382a8c6ade8f39 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 3 Apr 2023 12:52:03 -0700 Subject: [PATCH 8/8] Additional cases --- src/coreclr/jit/valuenum.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index cd369d8d70a9e..d047cf5108a70 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5688,6 +5688,14 @@ bool ValueNumStore::IsVNNeverNegative(ValueNum vn) { switch (funcApp.m_func) { + case VNF_GE_UN: + case VNF_GT_UN: + case VNF_LE_UN: + case VNF_LT_UN: + case VNF_COUNT: + case VNF_ADD_UN_OVF: + case VNF_SUB_UN_OVF: + case VNF_MUL_UN_OVF: #ifdef FEATURE_HW_INTRINSICS #ifdef TARGET_XARCH case VNF_HWI_POPCNT_PopCount: