https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80641

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at redhat dot com

--- Comment #5 from Jeffrey A. Law <law at redhat dot com> ---
So an interesting little bug.   Definitely similar to 79095 from last round.

So I'm going to highlight two blocks.
 <bb 6> [local count: 1073086475]:
  # c$D15286$_M_impl$_M_finish_32 = PHI <c$D15286$_M_impl$_M_finish_115(5),
_37(3)>
  _15 = c$D15286$_M_impl$_M_finish_32 - _130;
  _14 = _15 /[ex] 4;
  _11 = (long unsigned int) _14;
  if (c$D15286$_M_impl$_M_finish_32 != _130)
    goto <bb 7>; [92.50%]
  else
    goto <bb 17>; [7.50%]

Assume that bb7 is uninteresting and that it transfers control to bb8.

 <bb 8> [local count: 918159614]:
  sz_17 = _11 + 18446744073709551615;
  if (_11 < sz_17)
    goto <bb 9>; [33.00%]
  else
    goto <bb 12>; [67.00%]

If you review 79095, you'll see the similarities.  The difference is the
pointer arithmetic doesn't sink into a convenient spot (which would be bb8).  
I believe if the pointer arith sunk into bb8, then the right things would "just
happen".

bb6->bb7->bb8 implies that _32 != _130.  From that we can derive that _15, _14
and _11 are all ~[0, 0].  Which should then allow us to optimize the overflow
test in bb8 so that it always transfers control to bb12 which would in turn
avoid the warning.

So the first problem is sinking doesn't think it's profitable to sink those
statements.  If I hack around that BB8 looks like this after sinking:

 _15 = c$D15286$_M_impl$_M_finish_32 - _39;
  _14 = _15 /[ex] 4;
  _11 = (long unsigned int) _14;
  sz_17 = _11 + 18446744073709551615;
  if (_11 < sz_17)
    goto <bb 9>; [33.00%]
  else
    goto <bb 12>; [67.00%]

So.  Progress.   But not enough. ch_vect (copy headers for vectorizer?) comes
along and turns that into:

  # c$D15286$_M_impl$_M_finish_56 = PHI <_37(27),
c$D15286$_M_impl$_M_finish_115(28)>
  _15 = c$D15286$_M_impl$_M_finish_56 - _39;
  _14 = _15 /[ex] 4;
  _11 = (long unsigned int) _14;
  sz_17 = _11 + 18446744073709551615;
  if (_11 < sz_17)
    goto <bb 9>; [33.00%]
  else
    goto <bb 12>; [67.00%]


The PHI is undesirable.  If I turn off vectorization to disable vect_ct DOM (by
way of its embedded EVRP analyzer) is able to discover bb8 must transfer
control to bb12 -- which makes the problematic memset unreachable and the
warning disappear.

So two things..

1. Figure out why sinking is so pessimistic.

2. Avoid loop header copying

And this will "just work"

Reply via email to