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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed also on x86-64 with -O2 [-fwrapv].  But I'll note that

      for (unsigned char u = 2; u < (unsigned char)m[r] - 196; u += -254)

with m[0] == -12326 should never be entered?  (unsigned char)-12326 - 196
is -158, and the comparison should be carried out in integer type(?)

Reduced testcase which behaves differently for -O[01] vs. -O2, no
vectorization happening.

unsigned short a;
char b;
short m[24];
unsigned char p[24][24][24];
unsigned q[4][24];
static void __attribute__((noipa)) c()
{
  for (long r = 0; r < 3; r = 7)
    for (unsigned s = 0; s < 4; s = ~02)
      for (unsigned char u = 2; u < (unsigned char)m[r] - 196; u += -254)
        for (int w = 0; w < 24; w += 2) {
          a += p[1][u][1] ?: m[s];
          b = q[u + 1][s];
        }
}
int main()
{
  for (int r = 0; r < 24; ++r)
    m[r] = -12326;
  for (int r = 0; r < 4; ++r)
    for (int s = 0; s < 4; ++s)
      for (int t = 0; t < 4; ++t)
        p[r][s][t] = 1;
  c();
  if (a != 45060 || b != 0)
    __builtin_abort ();
}


Interestingly the C frontend emits

        if ((int) u < (int) (unsigned char) *(m + (sizetype) ((long unsigned
int) r * 2)) + -196) goto <D.2978>; else goto <D.2972>;

which looks OK (and expected).

We do

t.c:10:35: optimized: loop turned into non-loop; it never loops

to the 'u' loop.  That said, I did confirm that at -O0 we do enter
the u and w loop bodies - which is unexpected to me.  I'm confused.
2 is not less than -158!?

Reply via email to