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?)

Reply via email to