Fix edge likelihoods out of optimize bools - #131356
Conversation
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
This PR fixes edge-likelihood propagation when optOptimizeCompareChainCondBlock merges two consecutive conditional blocks into a single compare-chain condition, ensuring the resulting block’s outgoing edge likelihoods preserve the original control-flow probabilities (including the “shared target” case).
Changes:
- Capture the pre-merge likelihoods for
b1’s removed and fallthrough edges and use them to recomputeb2’s outgoing edge likelihoods as unconditional probabilities after compaction. - Adjust
b2’s profile weight prior tofgCompactBlockso the merged block inherits the correct weight without incorrectly decrementing the shared-target’s weight. - Remove the prior call to
fgRepairProfileCondToUncond(which is tailored for true removal of alternate flow) in favor of this targeted repair for the compare-chain merge shape.
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
/azp list |
|
/azp run runtime-coreclr superpmi-diffs |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
src/coreclr/jit/optimizebools.cpp:1103
- The loop over
b2EdgesassumesGetTrueEdge()andGetFalseEdge()are distinct. Ifm_b2is a degenerate BBJ_COND where both edges are the same (possible elsewhere in the JIT), this code will apply the likelihood adjustment twice to the same FlowEdge, producing an incorrect final likelihood. Handle thetrueEdge == falseEdgecase explicitly and adjust each unique edge at most once.
FlowEdge* const b2Edges[] = {m_b2->GetTrueEdge(), m_b2->GetFalseEdge()};
for (FlowEdge* const b2Edge : b2Edges)
{
weight_t combined = fallthroughLikelihood * b2Edge->getLikelihood();
if (b2Edge->getDestinationBlock() == b1RemovedTarget)
src/coreclr/jit/optimizebools.cpp:1090
- Profile-weight repair is gated only on m_b2->hasProfileWeight(), but the added weight uses removedEdge->getLikelyWeight() which depends on m_b1's weight. If m_b2 has profile data but m_b1 does not, this can incorrectly treat a non-profile weight as profile and corrupt m_b2's profile weight. Gate this update on m_b1 having profile weight as well (matching fgRepairProfileCondToUncond’s precondition).
This issue also appears on line 1099 of the same file.
if (m_b2->hasProfileWeight())
{
m_b2->increaseBBProfileWeight(removedEdge->getLikelyWeight());
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/coreclr/jit/optimizebools.cpp:1090
- The profile-weight repair is currently gated on
m_b2->hasProfileWeight(), but the value you add (removedEdge->getLikelyWeight()) is derived fromm_b1->bbWeight. This diverges from the previousfgRepairProfileCondToUncondbehavior (which only adjusted weights when the source block had profile weight) and can incorrectly perturb PGO weights ifm_b2happens to have profile weight butm_b1does not. It also silently does nothing ifm_b1has profile weight butm_b2does not, leavingfgCompactBlockto inherit an underweightm_b2and potentially making PGO inconsistent.
Consider gating the adjustment on m_b1->hasProfileWeight() and explicitly marking the profile inconsistent when required profile data is missing on m_b2.
if (m_b2->hasProfileWeight())
{
m_b2->increaseBBProfileWeight(removedEdge->getLikelyWeight());
}
|
/ba-g known failing tests |
Optimize bools could produce incorrect edge likelihoods.
From the bug, we'd combine (note BB03->BB06 likelihood of 0.96):
------------ BB03 [0002] [016..022) -> BB06(0.9697322),BB04(0.03026775) (cond), preds={BB02} succs={BB04,BB06} ------------ BB04 [0003] [022..02B) -> BB06(0),BB05(1) (cond), preds={BB03} succs={BB05,BB06}into this after fusing BB003,04 (Note BB03->BB06 likelihood of 0)
------------ BB03 [0002] [016..02B) -> BB06(0),BB05(1) (cond), preds={BB02} succs={BB05,BB06}Fix
optOptimizeCompareChainCondBlockto correct this likelihood.I also replaced the call to fgRepairProfileCondToUncond which would incorrectly decrease the profile weight of BB06 in the above example.
Spent a bit looking through diffs. Regressions and improvements in perfscore are due to block weight inside loops now being calculated correctly. Some codesize changes caused by block reordering changes, as blockweight has gone 0.00->0.01 in some examples.
fixes #130150