-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Use rangecheck in assertprop #112766
Use rangecheck in assertprop #112766
Conversation
PTAL @jakobbotsch @AndyAyersMS @dotnet/jit-contrib Diffs Had to fix a bug inside |
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.
Changes LGTM.
Up at the top of the method seems like we could hoist the // First, check simple properties without assertions
code up above the initial set of bail-out checks?
src/coreclr/jit/assertionprop.cpp
Outdated
rng.LowerLimit().AddConstant(cns); | ||
rng.UpperLimit().AddConstant(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.
Return value needs to be checked?
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.
Ah, didn't realize AddConstant doesn't do anything if cns limit overflows. Added!
if ((rng.LowerLimit().GetConstant() == 0)) | ||
{ | ||
*isKnownNonNegative = true; | ||
} |
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.
Does this check not need to account for overflow?
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.
but how can X - CNS + CNS
overflow?
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.
(AddConstant
checks for overflow before it)
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.
I was worried that for a range like "[8..unknown]", that "unknown" could mean "some computation that overflowed" and hence that the lower limit was actually smaller than 8. But it's probably ok since the range here comes from assertions only.
else | ||
{ | ||
Range rng = Range(Limit(Limit::keDependent)); | ||
RangeCheck::MergeEdgeAssertions(this, treeVN, ValueNumStore::NoVN, assertions, &rng, false); | ||
Limit lowerBound = rng.LowerLimit(); | ||
if (lowerBound.IsConstant()) | ||
{ | ||
if (lowerBound.GetConstant() >= 0) | ||
{ | ||
*isKnownNonNegative = true; | ||
} | ||
if (lowerBound.GetConstant() > 0) | ||
{ | ||
*isKnownNonZero = true; | ||
} | ||
} | ||
} |
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.
Does this part catch cases? Naively I would expect assertion prop to know to check for the "straightforward" assertions that range check is checking here already.
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.
Yep, good chunk of diffs are caught by this
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.
I wonder if we could get rid of some of the checks above then, I would expect there to be a good amount of duplication between range check's assertion handling and that assertion handling above.
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.
I agree, I'll check what is missing in the above
*isKnownNonZero = true; | ||
} | ||
} | ||
} |
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.
IIRC, you had a version where you tried to use range check directly on the IR node. It seems like it would catch more cases, because the logic here for additions should already be conceptually the same logic that range check has to handle additions.
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.
That version had terrible TP impact and needed more touches (perhaps, its cache can be shared with rangecheck?), I might investigate it again in the future
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.
Actually, I'll do it after this PR - diffs look nice (if TP regressions are mitigated)
if ((rng.LowerLimit().IsConstant() && !rng.LowerLimit().AddConstant(cns)) || | ||
(rng.UpperLimit().IsConstant() && !rng.UpperLimit().AddConstant(cns))) | ||
{ | ||
// Add cns to both bounds if they are constants. Make sure the addition doesn't overflow. | ||
return; |
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.
if ((rng.LowerLimit().IsConstant() && !rng.LowerLimit().AddConstant(cns)) || | |
(rng.UpperLimit().IsConstant() && !rng.UpperLimit().AddConstant(cns))) | |
{ | |
// Add cns to both bounds if they are constants. Make sure the addition doesn't overflow. | |
return; | |
if (!rng.LowerLimit().AddConstant(cns) || !rng.UpperLimit().AddConstant(cns)) | |
{ | |
// Add cns to both bounds. Make sure the addition doesn't overflow. | |
return; |
Should be ok since there's the check for IsConstant
below already?
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.
Nope. This is too conservative - we're fine with some bounds to be Dependent (non-constant) when we e.g. only check Lower one. AddConstant returns false for them making the improvement super conservative
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.
LGTM. Would be nice to find some way to unify what assertion prop and range check are trying to do since they are starting to converge to trying to do the same thing it seems.
This reverts commit 6022adf.
Contributes to #112765 (the sign-extension cast).
The PR borrows @jakobbotsch's idea to re-use rangecheck outside of its phase (#110352)