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

            Bug ID: 128651
           Summary: [14/15/16/17 Regression] wrong code at -O2: FRE
                    replaces stored (unsigned)x with (unsigned)(x ^ k)
                    inside a loop
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: needs-bisection, wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---

int printf(const char *, ...);
void *malloc(unsigned long);
void *memcpy(void *, const void *, unsigned long);
int x = 8;
unsigned long long acc;
int main(void) {
  char *b = malloc(64);
  char *b2 = b + 8;
  for (int i = 0; i < 8; i++) ((long long *)b)[i] = 0;
  for (int k = 0; k < 4; k++)
    *(int *)(b + 8) = (int)((unsigned)k * 3u + (unsigned)x);
  for (int k = 0; k < 4; k++) {
    *(long *)(b2 + 8) = (unsigned)(k ^ x);
    unsigned long long t;
    memcpy(&t, b + 16 + k * 8, 8);
    acc += t;
    *(long *)(b2 + 8) = 0;
    *(long *)(b2 + 8) = (long)((unsigned long)*(long *)(b2 + 8) * 3u +
(unsigned)x);
  }
  unsigned long long h;
  memcpy(&h, b + 16, 8);
  printf("%llu\n", h);
}

$ gcc -O0 t.c && ./a.out
8
$ gcc -O2 t.c && ./a.out
11

Expected: 8. The last store in each iteration is 0 * 3 + x = 8, so h = 8. -O2
gives 11 = 3 ^ 8 (value of the last k).

Suspected cause: FRE (RPO VN) keeps a stale optimistic value: (unsigned)x and
(unsigned)(x ^ k) are equal only for k = 0.

Avoided by: -fno-tree-fre.

Known to fail: 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0, 17.0.

Known to work: 7.5.0, 8.5.0, 10.5.0, 11.4.0.

-O0 -fsanitize=undefined,address is clean.

gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release
  • [Bug tree-optimization/128651] N... jeffchen006 at gmail dot com via Gcc-bugs

Reply via email to