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

            Bug ID: 128461
           Summary: wrong code at -O1: LIM store motion loses reverse
                    storage order since r9-4993
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---
            Target: x86_64-pc-linux-gnu

int printf(const char *, ...);

#pragma scalar_storage_order big-endian
struct S {
  short a;
};
#pragma scalar_storage_order default

struct S g[2];
int n = 1;

int main(void)
{
  int x = 0;
  g[1].a = 2;
  for (int i = 0; i < n; i++) {
    x = g[1].a;
    (&g[0])[1].a = 0;
  }
  printf("%d\n", x);
  return 0;
}

$ gcc -O0 t.c && ./a.out
2
$ gcc -O1 t.c && ./a.out
512

-O1, -O2, -O3 all fail.

Expected: 2. g[1].a holds 2, and with big-endian storage order it must read
back as 2. At -O1 it reads as 512 (0x0200), so the bytes are read in native
order.

-fno-tree-loop-im avoids it. LIM moves the load and the store out of the loop
and does not preserve REF_REVERSE_STORAGE_ORDER. The program takes the address
of the struct, not of the reversed scalar.

Avoided by: -fno-tree-loop-im.
Bisected to r9-4993-g1c852d1d709.
Correct on 8.5.0.
Wrong on 10.5.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0, trunk.
-O0 -fsanitize=undefined,address is clean.

gcc version 17.0.0 20261029 (experimental), r17-5747-g85867b0c935,
x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release

Reply via email to