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

            Bug ID: 128638
           Summary: [16/17 Regression] wrong code at -O3: PRE moves a load
                    past a long long store by TBAA; the executed read is a
                    memcpy since r12-3918
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: alias, 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 = 1;
unsigned h(char *p, char *q) {
  if (x)
    *(float *)p = 2;
  else
    *(int *)p = 5;
  *(long long *)q = 1;
  unsigned t;
  if (x)
    memcpy(&t, p, 4);
  else
    t = *(int *)p;
  return t;
}
unsigned (*fp)(char *, char *) = h;
int main(void) {
  char *b = malloc(8);
  printf("%x\n", fp(b, b));
}

$ gcc -O0 t.c && ./a.out
1
$ gcc -O3 t.c && ./a.out
40000000

Expected: 1. p == q. The long long 1 store at q overwrites the float 2.0f at p,
and the memcpy (alias set 0) must see it: t = 1. -O3 (and -O2
-ftree-partial-pre) gives 0x40000000, the bits of 2.0f. 13.4-15.2 do not show
it (hidden).

Suspected cause: PRE ANTIC: the load expression is hoisted past the store by
the TBAA of an int representative, but the read that runs is the memcpy (first
bad 5b8b1522e04, 2021, PR100112).

Avoided by: -fno-tree-pre, -fno-strict-aliasing.

Known to fail: 12.5.0, 16.2.0, 17.0.

Known to work: 8.5.0, 10.5.0, 11.4.0, 13.4.0, 14.3.0, 15.2.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

Reply via email to