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

            Bug ID: 128637
           Summary: [14/15/16/17 Regression] wrong code at -O2: FRE gives
                    a memcpy read a TBAA-based value of a typed load that
                    does not execute since r10-1692
           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 *memset(void *, int, unsigned long);
void *memcpy(void *, const void *, unsigned long);
int x;
long r;
int main(void) {
  unsigned char *b = malloc(8);
  memset(b, 0, 8);
  *(long long *)b = 1;
  b[4] = 1;
  if (x)
    r = *(long *)b;
  long long t;
  memcpy(&t, b, 8);
  printf("%llx\n", t);
}

$ gcc -O0 t.c && ./a.out
100000001
$ gcc -O2 t.c && ./a.out
100000000

Expected: 100000001. b holds long long 1 and then b[4] = 1, so the 8 bytes are
0x100000001. The long load under if (x) does not run (x = 0). -O2 gives the
memcpy read the memset value for the low word.

Suspected cause: SCCVN: the value of a typed load (found with TBAA) is reused
for a ref-all (memcpy) read at the same VUSE (first bad 38988cbf9eb, 2019,
PR83518). Related: PR101641.

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

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

Known to work: 8.5.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

Related: PR101641, PR83518.

Reply via email to