-
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
JIT: Fold more nullchecks #111985
JIT: Fold more nullchecks #111985
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
@AndyAyersMS @jakobbotsch @dotnet/jit-contrib PTAL, diffs show no TP regression. I also tried to extend the algorithm to handle nested PHIs, but it didn't find additionally anything. Ideally, like Jakob suggested, we should use |
@@ -5810,6 +5833,35 @@ ASSERT_VALRET_TP Compiler::optGetVnMappedAssertions(ValueNum vn) | |||
return BitVecOps::UninitVal(); | |||
} | |||
|
|||
//------------------------------------------------------------------------ | |||
// optGetEdgeAssertions: Given a block and its predecessor, get the assertions |
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've extracted this function from rangecheck.cpp to re-use in my function
{ | ||
AssertionIndex assertionIndex = GetAssertionIndex(index); | ||
if (assertionIndex > optAssertionCount) |
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.
redundant condition, I guess it wasn't deleted when we moved all "walk asserts" pieces to BitVecOps::Iter
.
src/coreclr/jit/assertionprop.cpp
Outdated
return blockPred->bbAssertionOut; | ||
} | ||
|
||
if ((blockPred->KindIs(BBJ_ALWAYS) && blockPred->TargetIs(block)) || |
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 thought for BBJ_ALWAYS
the right set was bbAssertionOut
?
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 for all other BBJ_KINDs you can use bbAssertionOut
. Just BBJ_COND is special.
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.
@AndyAyersMS are you sure? e.g. what about BBJ_SWITCH or some EH related blocks? I copied this function from rangecheck
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've partially addressed your feedback as I was not confident I can just unconditionally return bbAssertionOut
for something other than BBJ_ALWAYS/BBJ_COND(false edge).
However, it looks like we don't typically work with anything but these two anyway.
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.
bbAssertionOut
should be set for all blocks -- for most block kinds it is the only thing we have. Only BBJ_COND also has bbJtrueAssertionOut
.
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.
@AndyAyersMS I see, ok changed
src/coreclr/jit/assertionprop.cpp
Outdated
return bbJtrueAssertionOut[blockPred->bbNum]; | ||
} | ||
} | ||
return BitVecOps::UninitVal(); |
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.
Seems like this should return an empty BV on failure, though I also think (once the above is restructured to handle all pred block kinds) you should never get here.
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.
returned empty BV
Co-authored-by: Jakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
@AndyAyersMS @jakobbotsch anything else? I've addressed your feedback. Diffs slightly improved (due to better way to look for PhiDefs via VN). I plan to use |
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, just one thing I'm puzzled about.
{ | ||
if ((blockPred->KindIs(BBJ_COND) && blockPred->TrueTargetIs(block))) | ||
{ | ||
if (bbJtrueAssertionOut != nullptr) |
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.
Curious if you ever see this being null.
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 assumed it could in rangecheck if assertprop didn't run, but not sure such combination is possible. From a quick SPMI run it's not null. I'll convert it into an assert in my next PR to avoid spinning CI for it
/ba-g "Linux-arm64 is blocked by dotnet/dnceng#4892, Build-analysis didn't recognize some failures as known build issue " |
* main: JIT: fix case where implied subrange assertions can get lost in morph (dotnet#112020) Propose new async API (dotnet#110420) Move the diagnostic print for stack overflow test failure (dotnet#112001) JIT: Fold more nullchecks (dotnet#111985) Baseline more pri1 tests (dotnet#111068)
Handles redundant checks in Example 1 in #111980
Some nice diffs