On Thu, Dec 10, 2020 at 12:14:22PM +0100, Eric Botcazou wrote: > > 2020-12-10 Jakub Jelinek <ja...@redhat.com> > > > > PR rtl-optimization/98212 > > * dojump.c (do_compare_rtx_and_jump): Change computation of > > first_prob for and_them and don't invert prob around it. > > > > * gcc.dg/predict-8.c: Adjust expected probability. > > > > --- gcc/dojump.c.jj 2020-12-09 15:11:17.042888002 +0100 > > +++ gcc/dojump.c 2020-12-09 20:05:59.535234206 +0100 > > @@ -1148,9 +1148,8 @@ do_compare_rtx_and_jump (rtx op0, rtx op > > if (and_them) > > { > > rtx_code_label *dest_label; > > - prob = prob.invert (); > > - profile_probability first_prob = prob.split > (cprob).invert (); > > - prob = prob.invert (); > > + profile_probability first_prob > > + = prob.split (cprob.invert ()).invert (); > > /* If we only jump if true, just bypass the second > jump. */ > > if (! if_false_label) > > { > > The computation looks plausible, but you need to fix the comment too, it is > rather confusing as it seems to depict an OR-ELSE rather than an AND-THEN.
So like: 2020-12-10 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/98212 * dojump.c (do_compare_rtx_and_jump): Change computation of first_prob for and_them and don't invert prob around it. * gcc.dg/predict-8.c: Adjust expected probability. --- gcc/dojump.c.jj 2020-12-09 15:11:17.042888002 +0100 +++ gcc/dojump.c 2020-12-10 12:24:56.991844956 +0100 @@ -1138,19 +1138,21 @@ do_compare_rtx_and_jump (rtx op0, rtx op cprob = cprob.apply_scale (99, 100); else cprob = profile_probability::even (); - /* We want to split: + /* For and_them we want to split: if (x) goto t; // prob; + goto f; into - if (a) goto t; // first_prob; + if (a) ; else goto f; // first_prob for ; + // 1 - first_prob for goto f; if (b) goto t; // prob; + goto f; such that the overall probability of jumping to t - remains the same and first_prob is prob * cprob. */ + remains the same and first_prob is 1 - prob * (1 - cprob). */ if (and_them) { rtx_code_label *dest_label; - prob = prob.invert (); - profile_probability first_prob = prob.split (cprob).invert (); - prob = prob.invert (); + profile_probability first_prob + = prob.split (cprob.invert ()).invert (); /* If we only jump if true, just bypass the second jump. */ if (! if_false_label) { @@ -1163,6 +1170,15 @@ do_compare_rtx_and_jump (rtx op0, rtx op do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, size, dest_label, NULL, first_prob); } + /* For !and_them we want to split: + if (x) goto t; // prob; + goto f; + into + if (a) goto t; // first_prob; + if (b) goto t; // prob; + goto f; + such that the overall probability of jumping to t + remains the same and first_prob is prob * cprob. */ else { profile_probability first_prob = prob.split (cprob); --- gcc/testsuite/gcc.dg/predict-8.c.jj 2020-01-12 11:54:37.506396918 +0100 +++ gcc/testsuite/gcc.dg/predict-8.c 2020-12-10 10:34:00.632123682 +0100 @@ -8,4 +8,4 @@ int foo(float a, float b) { return 2; } -/* { dg-final { scan-rtl-dump-times "65.\[34]. .guessed" 2 "expand"} } */ +/* { dg-final { scan-rtl-dump-times "99.\[345]. .guessed" 2 "expand"} } */ Jakub