-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Remove bounds checks for Log2 function in FormattingHelpers.CountDigits #113790
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR removes bounds checks and unsafe array access in the Log2-based digit lookup in FormattingHelpers.CountDigits, improving both performance and clarity.
- Replaces Unsafe.Add pointer arithmetic with direct array indexing for the ulong-based digit lookup.
- Applies the same change for the uint-based computation using a lookup table.
Files not reviewed (3)
- src/coreclr/jit/rangecheck.cpp: Language not supported
- src/coreclr/jit/valuenum.cpp: Language not supported
- src/coreclr/jit/valuenum.h: Language not supported
@jakobbotsch @dotnet/jit-contrib PTAL - removes unsafe array access from two places. Just a couple of diffs, but, hopefully, this introduces more convenient helpers to do pattern matching on top of VNs. the GetVNFunc patter is quite verbose |
Range RangeCheck::ComputeRangeForBinOp(BasicBlock* block, GenTreeOp* binop, bool monIncreasing DEBUGARG(int indent)) | ||
{ | ||
assert(binop->OperIs(GT_ADD, GT_AND, GT_RSH, GT_RSZ, GT_LSH, GT_UMOD, GT_MUL)); | ||
assert(binop->OperIs(GT_ADD, GT_XOR, GT_AND, GT_RSH, GT_RSZ, GT_LSH, GT_UMOD, GT_MUL)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: ideally, we should have handled XOR/OR/HWINTRINSIC all separately for GetRange, but it seems that it has no diffs outside of Log2 pattern, so I decided to just do an ad-hoc Log2 matching.
int xorBy; | ||
ValueNum op; | ||
// First, see if it's "X ^ 31" or "X ^ 63". | ||
if (IsVNBinFuncWithConst(vn, VNF_XOR, &op, &xorBy) && ((xorBy == 31) || (xorBy == 63))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This is missing handling for X86Base_BitScanReverse
which is used for R2R and NAOT, since LZCNT isn't baseline.
#endif | ||
// Next, see if it's "LZCNT32(X | 1)" or "LZCNT64(X | 1)". | ||
int orBy; | ||
if (IsVNBinFunc(op, lzcntFunc, &op) && IsVNBinFuncWithConst(op, VNF_OR, &op, &orBy) && (orBy == 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noting, that X | 1
isn't required if we know that X != 0
, but its probably not necessary to handle.
bool IsVNBinFunc(ValueNum vn, VNFunc func, ValueNum* op1 = nullptr, ValueNum* op2 = nullptr); | ||
|
||
// Returns "true" iff "vn" is a function application of the form "func(op, cns)" | ||
// the cns can be on the left side if the function is commutative. | ||
template <typename T> | ||
bool IsVNBinFuncWithConst(ValueNum vn, VNFunc func, ValueNum* op, T* cns) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Other functions in this class seem to write out Binary
in full (e.g. EvalMathFuncBinary
above).
Feel free to ignore or address as part of a separate PR.
@EgorBo, can this be merged? |
Yeah, I wanted to generalize the jit part a bit, but I think I'll merge as is, let me check again |
/ba-g same issue as #116041 |
Closes #79257
And replaces unsafe array access in FormattingHelpers.CountDigits.cs
Example:
Was:
Now: