Skip to content

Commit 6d38a7f

Browse files
authored
remove bounds checks for some more unsigned comparisons (#43568)
* Remove bound checks for unsigned <= with constant integers * formatting * update comment and add next edge tests
1 parent a632a53 commit 6d38a7f

File tree

3 files changed

+385
-4
lines changed

3 files changed

+385
-4
lines changed

src/coreclr/jit/valuenum.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4285,19 +4285,34 @@ void ValueNumStore::GetConstantBoundInfo(ValueNum vn, ConstantBoundInfo* info)
42854285
}
42864286
}
42874287

4288+
//------------------------------------------------------------------------
4289+
// IsVNPositiveInt32Constant: returns true iff vn is a known Int32 constant that is greater then 0
4290+
//
4291+
// Arguments:
4292+
// vn - Value number to query
4293+
bool ValueNumStore::IsVNPositiveInt32Constant(ValueNum vn)
4294+
{
4295+
return IsVNInt32Constant(vn) && (ConstantValue<INT32>(vn) > 0);
4296+
}
4297+
42884298
//------------------------------------------------------------------------
42894299
// IsVNArrLenUnsignedBound: Checks if the specified vn represents an expression
4290-
// such as "(uint)i < (uint)len" that implies that the index is valid
4291-
// (0 <= i && i < a.len).
4300+
// of one of the following forms:
4301+
// - "(uint)i < (uint)len" that implies (0 <= i < len)
4302+
// - "const < (uint)len" that implies "len > const"
4303+
// - "const <= (uint)len" that implies "len > const - 1"
42924304
//
42934305
// Arguments:
42944306
// vn - Value number to query
42954307
// info - Pointer to an UnsignedCompareCheckedBoundInfo object to return information about
42964308
// the expression. Not populated if the vn expression isn't suitable (e.g. i <= len).
4297-
// This enables optCreateJTrueBoundAssertion to immediatly create an OAK_NO_THROW
4309+
// This enables optCreateJTrueBoundAssertion to immediately create an OAK_NO_THROW
42984310
// assertion instead of the OAK_EQUAL/NOT_EQUAL assertions created by signed compares
42994311
// (IsVNCompareCheckedBound, IsVNCompareCheckedBoundArith) that require further processing.
4300-
4312+
//
4313+
// Note:
4314+
// For comparisons of the form constant <= length, this returns them as (constant - 1) < length
4315+
//
43014316
bool ValueNumStore::IsVNUnsignedCompareCheckedBound(ValueNum vn, UnsignedCompareCheckedBoundInfo* info)
43024317
{
43034318
VNFuncApp funcApp;
@@ -4314,6 +4329,19 @@ bool ValueNumStore::IsVNUnsignedCompareCheckedBound(ValueNum vn, UnsignedCompare
43144329
info->vnBound = funcApp.m_args[1];
43154330
return true;
43164331
}
4332+
// We care about (uint)len < constant and its negation "(uint)len >= constant"
4333+
else if (IsVNPositiveInt32Constant(funcApp.m_args[1]) && IsVNCheckedBound(funcApp.m_args[0]))
4334+
{
4335+
// Change constant < len into (uint)len >= (constant - 1)
4336+
// to make consuming this simpler (and likewise for it's negation).
4337+
INT32 validIndex = ConstantValue<INT32>(funcApp.m_args[1]) - 1;
4338+
assert(validIndex >= 0);
4339+
4340+
info->vnIdx = VNForIntCon(validIndex);
4341+
info->cmpOper = (funcApp.m_func == VNF_GE_UN) ? VNF_LT_UN : VNF_GE_UN;
4342+
info->vnBound = funcApp.m_args[0];
4343+
return true;
4344+
}
43174345
}
43184346
else if ((funcApp.m_func == VNF_GT_UN) || (funcApp.m_func == VNF_LE_UN))
43194347
{
@@ -4326,6 +4354,19 @@ bool ValueNumStore::IsVNUnsignedCompareCheckedBound(ValueNum vn, UnsignedCompare
43264354
info->vnBound = funcApp.m_args[0];
43274355
return true;
43284356
}
4357+
// Look for constant > (uint)len and its negation "constant <= (uint)len"
4358+
else if (IsVNPositiveInt32Constant(funcApp.m_args[0]) && IsVNCheckedBound(funcApp.m_args[1]))
4359+
{
4360+
// Change constant <= (uint)len to (constant - 1) < (uint)len
4361+
// to make consuming this simpler (and likewise for it's negation).
4362+
INT32 validIndex = ConstantValue<INT32>(funcApp.m_args[0]) - 1;
4363+
assert(validIndex >= 0);
4364+
4365+
info->vnIdx = VNForIntCon(validIndex);
4366+
info->cmpOper = (funcApp.m_func == VNF_LE_UN) ? VNF_LT_UN : VNF_GE_UN;
4367+
info->vnBound = funcApp.m_args[1];
4368+
return true;
4369+
}
43294370
}
43304371
}
43314372

src/coreclr/jit/valuenum.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ class ValueNumStore
228228
template <typename T, typename NumMap>
229229
inline ValueNum VnForConst(T cnsVal, NumMap* numMap, var_types varType);
230230

231+
// returns true iff vn is known to be a constant int32 that is > 0
232+
bool IsVNPositiveInt32Constant(ValueNum vn);
233+
231234
public:
232235
// Initializes any static variables of ValueNumStore.
233236
static void InitValueNumStoreStatics();

0 commit comments

Comments
 (0)