-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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: don't create degenerate flow in fgReplaceJumpTarget
#99509
Conversation
Detect if the update has created degenerate BBJ_COND flow, and simplify. Also symmetrize the true/false cases. Fixes dotnet#48609. Also fixes some issues seen in enhanced likelhood checking.
@amanasifkhalid PTAL |
src/coreclr/jit/fgbasic.cpp
Outdated
@@ -662,6 +662,8 @@ void Compiler::fgReplaceJumpTarget(BasicBlock* block, BasicBlock* oldTarget, Bas | |||
|
|||
if (block->FalseEdgeIs(oldEdge)) | |||
{ | |||
// Branch was degenerate, simplify it first | |||
// | |||
// fgRemoveRefPred returns nullptr for BBJ_COND blocks with two flow edges to target |
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.
Since you're here, could you please remove this comment about fgRemoveRefPred
returning nullptr? The new version of it that takes in a flow edge doesn't return anything. Thanks!
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.
src/coreclr/jit/fgbasic.cpp
Outdated
} | ||
} | ||
else | ||
{ | ||
assert(block->FalseTargetIs(oldTarget)); | ||
FlowEdge* const oldEdge = block->GetFalseEdge(); | ||
|
||
if (block->TrueEdgeIs(oldEdge)) |
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'm a bit confused by this check here. If a block's true and false edges are the same, then shouldn't the condition if (block->TrueTargetIs(oldTarget))
above be true, making this code unreachable?
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.
Yeah, good point.
src/coreclr/jit/fgbasic.cpp
Outdated
} | ||
|
||
if (block->GetFalseEdge() == block->GetTrueEdge()) |
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 think we need to check if block
is still a BBJ_COND
here before calling GetFalseEdge/GetTrueEdge
. If we converted it to a BBJ_ALWAYS
above, this will assert.
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.
Added the check.
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, thanks! I'm curious to see what the diffs look like from this.
} | ||
|
||
if (block->KindIs(BBJ_COND) && (block->GetFalseEdge() == block->GetTrueEdge())) |
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 noticed that we tend to compare the true/false edges with TrueEdgeIs
. I'm planning on modifying fgReplaceJumpTarget
in an upcoming PR, so I'll fix this then.
Diffs don't look too bad. Seems to be mostly layout changes (not surprising) and all that that entails. |
Detect if the update has created degenerate BBJ_COND flow, and simplify. Also symmetrize the true/false cases.
Fixes #48609.
Also fixes some issues seen in enhanced likelihood checking.
Diffs