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

            Bug ID: 128470
           Summary: wrong code at -O2: store to a global before a
                    non-local goto is lost with mutually tail-calling
                    nested functions since r12-2721
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: ipa
          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 g;

unsigned f(unsigned x)
{
  unsigned r;
  {
    __label__ out;
    void j(void) { g = x; goto out; }
    j();
  out:
    r = g;
  }
  auto unsigned t1(unsigned y, unsigned a);
  unsigned t2(unsigned y, unsigned a) { return y ? t1(y - 1, a) : a; }
  unsigned t1(unsigned y, unsigned a) { return y ? t2(y - 1, a) : a; }
  return t1(x, r);
}

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

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

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

Expected: 1. j sets g = 1 and jumps to out, so r = 1. t1(1, 1) calls t2(0, 1),
which returns 1.

-fno-ipa-modref and -fno-ipa-cp do not avoid it.

Avoided by: -fno-ipa-pure-const, -fno-gcse, -fno-optimize-sibling-calls.
Bisected to r12-2721-g4d562591018.
Correct on 8.5.0, 10.5.0.
Wrong on 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