https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109210
Bug ID: 109210 Summary: Bogus use of __builtin_expect defined by PHI arguments Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: gcov-profile Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org CC: marxin at gcc dot gnu.org Target Milestone: --- gcc.dg/predict-20.c shows how we bogously apply a __builtin_expect value from a PHI def without considering the guarding condition. We have from the loop exit block _2 = b.0_1 < 0; _3 = (long int) _2; _4 = __builtin_expect (_3, 0); if (_4 != 0) goto <bb 5>; [10.00%] and the __builtin_expect guarding the asm() is CSEd to the above and the block looks like <bb 5> [local count: 977105059]: # _9 = PHI <_4(3), 0(4)> if (_9 != 0) goto <bb 6>; [10.00%] else goto <bb 7>; [90.00%] we are blindly handling _4 as having a value zero with probability 90% for the first PHI argument, then merging with zero on the other edge and using that as predictor for _9. But we fail to account for the __builtin_expect inversion implied by the condition on the 3->5 edge. We're somehow lucky in the end and the profile looks good. With a proposed patch that propagates the equivalence using value-range info we'd get <bb 5> [local count: 977105059]: # _9 = PHI <1(3), 0(4)> (also showing the prediction is bad) and we no longer predict anything. If we'd simply resort to look for recorded predictions on the edges we'd discover a __builtin_expect unlikely on 3->5 and likely on the other. If we then just take the likely constant (zero) as prediction the testcase would work again (but probability of the incoming edge is not a good measure for the count we'd end up here?)