[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2023-03-16 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

Martin Liška  changed:

   What|Removed |Added

   Assignee|marxin at gcc dot gnu.org  |unassigned at gcc dot 
gnu.org
 Status|ASSIGNED|NEW

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2023-01-11 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

--- Comment #8 from Martin Liška  ---
Thinking about it, we would likely need a "data flow" algorithm, where we want
to transitively propagate equal predicates that occur in both successors of a
basic block. Once we "merge" such a predictor, a new merging opportunity can
happen.

Honza, do you know about a feasible framework I should use? Or should I create
an ad-hoc work queue approach in this situation?

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-17 Thread hubicka at kam dot mff.cuni.cz via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

--- Comment #7 from hubicka at kam dot mff.cuni.cz ---
> I can try implementing that.
That would be nice.  I think if path predictor logic hits the same
predictor both ways, it can simply predict that basic block with the
same predictor (i.e. recurse on that block).   It will need to keep
track what basic blocks were already predicted to handle cycles.

Honza

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-16 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

Martin Liška  changed:

   What|Removed |Added

 CC||marxin at gcc dot gnu.org
 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2022-06-16
   Assignee|unassigned at gcc dot gnu.org  |marxin at gcc dot 
gnu.org
 Ever confirmed|0   |1

--- Comment #6 from Martin Liška  ---
I can try implementing that.

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-15 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

--- Comment #5 from Jonathan Wakely  ---
If the two noreturn functions are replaced with throwing exceptions, I get the
behaviour I expect:

  if (n > (__PTRDIFF_MAX__ / sizeof(T)))
  {
if (n > (__SIZE_MAX__ / sizeof(T)))
  throw 1;
throw 2L;
  }

This is correctly treated as unlikely. So the problem only seems to happen
because of libstdc++'s convention of using named noreturn functions to throw
exceptions (which is done to simplify -fno-exceptions cases). This probably
doesn't affect much user code.

It also seem that if I explicitly add the 'cold' attribute to those noreturn
functions, I get the behaviour I expect.

So maybe it's not worth spending any effort on this, and I should just change
__attribute__((__noreturn__)) to __attribute__((__noreturn__,__cold)) for every
function in libstdc++-v3/include/bits/functexcept.h

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-15 Thread hubicka at kam dot mff.cuni.cz via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

--- Comment #4 from hubicka at kam dot mff.cuni.cz ---
> possibly the noreturn predictor doesn't trigger here
The problem here is that we handle throw1 and throw2 as two independent
reason for code path to be unlikely.  This makes us to look for
conditional controling the code path and we predict the inner if both
ways as unlikely so they cancel out.

I suppose we could be smarter here and teach path predictor to check for
this situation and if both directions of a branch are considered bad for
same reason continue propagating up.  This shoudl not be hard to
implement.

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-15 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

Richard Biener  changed:

   What|Removed |Added

 CC||hubicka at gcc dot gnu.org

--- Comment #3 from Richard Biener  ---
possibly the noreturn predictor doesn't trigger here

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-14 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

--- Comment #2 from Jonathan Wakely  ---
https://godbolt.org/z/asecWe6KK

[Bug tree-optimization/105973] Wrong branch prediction for if (COND) { if(x) noreturn1(); else noreturn2(); }

2022-06-14 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973

--- Comment #1 from Jonathan Wakely  ---
In fact we get it wrong even if both branches call the same noreturn function:

  if (PREDICT(n > (__PTRDIFF_MAX__ / sizeof(T
  {
if (n > (__SIZE_MAX__ / sizeof(T)))
  throw1();
throw1();
  }


This is not compiled to the same code as:

  if (PREDICT(n > (__PTRDIFF_MAX__ / sizeof(T
  {
throw1();
  }

even though it has identical effects.