Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JIT] ARM64/X64 - Add IsVNNeverNegative #83694

Merged
merged 9 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions src/coreclr/jit/valuenum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4714,6 +4714,26 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN
{
resultVN = VNOneForType(typ);
}
else if (varTypeIsIntegralOrI(TypeOfVN(arg0VN)))
{
ZeroVN = VNZeroForType(typ);
if (genTreeOps(func) == GT_GE)
TIHan marked this conversation as resolved.
Show resolved Hide resolved
{
// (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;

case GT_NE:
Expand Down Expand Up @@ -4773,6 +4793,26 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN
{
resultVN = VNZeroForType(typ);
}
else if (varTypeIsIntegralOrI(TypeOfVN(arg0VN)))
{
ZeroVN = VNZeroForType(typ);
if (genTreeOps(func) == GT_LT)
{
// (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;

default:
Expand Down Expand Up @@ -5618,6 +5658,72 @@ bool ValueNumStore::IsVNInt32Constant(ValueNum vn)
return TypeOfVN(vn) == TYP_INT;
}

bool ValueNumStore::IsVNNeverNegative(ValueNum vn)
{
assert(varTypeIsIntegral(TypeOfVN(vn)));

if (IsVNConstant(vn))
{
var_types vnTy = TypeOfVN(vn);
if (vnTy == TYP_INT)
{
return GetConstantInt32(vn) >= 0;
}
else if (vnTy == TYP_LONG)
{
return GetConstantInt64(vn) >= 0;
}

return false;
}

// Array length can never be negative.
if (IsVNArrLen(vn))
{
return true;
}

VNFuncApp funcApp;
if (GetVNFunc(vn, &funcApp))
{
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:
TIHan marked this conversation as resolved.
Show resolved Hide resolved
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 defined(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

default:
break;
}
}

return false;
}

GenTreeFlags ValueNumStore::GetHandleFlags(ValueNum vn)
{
assert(IsVNHandle(vn));
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/jit/valuenum.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<ValueNum, bool, 8U> CheckedBoundVNSet;

// Returns true if the VN is known or likely to appear as the conservative value number
Expand Down