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

            Bug ID: 128462
           Summary: wrong code at -O2: RTL GCSE reuses a load across the
                    receiver of a non-local goto since r10-1202
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-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 *, ...);

unsigned f(void)
{
  unsigned r, x = 0;
  {
    __label__ l1;
    unsigned d = 0;
    void g1(void) { d = 1; goto l1; }
    g1();
  l1:
    r = d;
  }
  {
    __label__ l2;
    unsigned d2 = 0;
    unsigned g2(unsigned y) { if (y == 0) goto l2; return d2; }
    x = g2(1);
  l2:;
  }
  return r + x;
}

int main(void)
{
  printf("%u\n", f());
  return 0;
}

$ gcc -O0 t.c && ./a.out
1
$ gcc -O2 t.c && ./a.out
0

-O2, -O3 fail; -O1 is correct.

Expected: 1. g1 sets the parent's d to 1 and jumps to l1, so r = 1. g2(1)
returns d2 = 0, so f returns 1.

The load of d after l1 is replaced by the earlier value 0. The ipa-cp clone of
g2 is marked pure although g2 contains a non-local goto, and RTL GCSE then
reuses the load across the receiver.

Avoided by: -fno-ipa-pure-const, -fno-ipa-cp, -fno-gcse.
Bisected to r10-1202-g25403c416e5.
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