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