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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
we are computing 647 >> t even when that would invoke undefined behavior (but
LIM does this already).  Disabling either loop splitting or final value
replacement avoids the miscompile.

The only "interesting" replacement is the PHI defining the guard of the
second loop, thus 'd' after the first loop:

final value replacement:
  _54 = PHI <_4(10)>
 with expr: (d.6_22 + 1) + (d.6_22 <= _53 ? (int) ((unsigned int) _53 -
(unsigned int) d.6_22) : 0)
 final stmt:
  _54 = _67 + _73;

d.6_22 is 'd' at the start of the program, _53 is the loop split adjusted
exit test value, MIN (647 >> t, 7 - (d + 1)).

When disabling vectorization we instead get

0
Aborted (core dumped)

likewise when disabling unswitching.  When disabling early invariant motion
splitting is disabled.  Changing the test to the following, avoiding the
undefined behavior resolves the miscompile.

int printf(const char *, ...);
volatile int a = 31;
int b, d, e;
int main()
{
  int t = a;
  for (; d <= 6; d++) {
      for (b = 0; b <= 6; b++) {
          if (t >= 30)
            e = d;
          else if (d > (647 >> t))
            e = d;
          else
            e = 0;
      }
  }
  printf("%d\n", e);
  if (e != 6)
    __builtin_abort();
}

so in the end I think we see the effect of hoisting the shift and then
involving it in a complex computation + comparison, eventually enabling
folding that's "invalid" (taking advantage of the undefined behavior).

I will need to see to avoid hoisting shifts (we already rewrite undefined
signed overflow to unsigned arithmetic).  Unfortunately there's no "safe"
way to write shifts without adding computation (but maybe we should do
that, rewrite it to 647 >> min (t, 31)).

Reply via email to