https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120596
Bug ID: 120596 Summary: Wrong code on -O2 and above (possibly affecting many versions) Product: gcc Version: 16.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: haoxintu at gmail dot com Target Milestone: --- Hi, We found a possible wrong-code issue with our new testing tool. Please look at the details below. $cat small.c #include <stdio.h> #include <stdint.h> static inline int8_t safe_mod_func_int8_t_s_s(int8_t si1, int8_t si2) { if (si2 == 0 || (si1 == INT8_MIN && si2 == -1)) return si1; else return si1 % si2; } int idx = 0; void __attribute__((noinline)) marker_1(void) { idx++; printf("%d\n", idx); } int32_t f = 0; union { int64_t d; int32_t e; } aa = {6}; struct { int32_t g; } m[1][2] = {{{0}, {0}}}; int32_t k, l, j, i; static int32_t *o = &aa.e; int8_t n; int64_t q[10][3] = {{0}}; int8_t r(int8_t *, int8_t *, int8_t *, uint32_t, uint32_t); int8_t *ac(int8_t); uint32_t ae(int8_t, int32_t *, int32_t *, int64_t); static uint8_t af(void) { int8_t *ag = 0; int32_t ah = f; r(ag, ac(7), ag, ah, 0); return l; } int8_t r(int8_t *ai, int8_t *aj, int8_t *ak, uint32_t a, uint32_t am) { an : { uint64_t ao = 3; int64_t *ap = &aa.d; *ap = 0; if (*o) { int32_t aq = 2; if (safe_mod_func_int8_t_s_s(m[0][1].g == (*aj = aq) == 0, ao)) marker_1(); else goto an; } } return (int8_t) q[6][2]; } int8_t *ac(int8_t as) { int32_t *at[10][10] = {&f}; int8_t *au = &n; ae(0, at[5][6], &k, 3); return au; } uint32_t ae(int8_t c, int32_t *d, int32_t *e, int64_t bg) { for (; k >= 0;) return j; for (;; n--) o = &i; } int main(void) { f = 100; af(); } $gcc-trunk -w -std=c99 -O0 small.c -o t0 ; ./t0 $gcc-trunk -w -std=c99 -O1 small.c -o t1 ; ./t1 $gcc-trunk -w -std=c99 -O2 small.c -o t2 ; ./t2 1 $gcc-trunk -w -std=c99 -O3 small.c -o t3 ; ./t3 1 The behavior in the Compcert compiler. $ccomp -w -std=c99 -O0 small.c -o t-c0 ; ./t-c0 $ccomp -w -std=c99 -O small.c -o t-c1 ; ./t-c1 The version I used: $gcc-trunk -v Using built-in specs. COLLECT_GCC=gcc-trunk COLLECT_LTO_WRAPPER=/home/haoxin/research/gcc/build/libexec/gcc/x86_64-pc-linux-gnu/16.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../configure --prefix=/home/haoxin/research/gcc/build --enable-bootstrap --enable-checking=release --enable-languages=c,c++ --enable-multilib --program-suffix=-trunk : (reconfigured) ../configure --prefix=/home/haoxin/research/gcc/build --enable-bootstrap --enable-checking=release --enable-languages=c,c++ --enable-multilib --program-suffix=-trunk : (reconfigured) ../configure --prefix=/home/haoxin/research/gcc/build --enable-bootstrap --enable-checking=release --enable-multilib --program-suffix=-trunk --enable-languages=c,c++,lto --no-create --no-recursion Thread model: posix Supported LTO compression algorithms: zlib gcc version 16.0.0 20250607 (experimental) (GCC) $ccomp --version The CompCert C verified compiler, version 3.15 Reproduced in Godblot: https://godbolt.org/z/KEo5nah7f. Many old versions of GCC behave the same. Interestingly, the LLVM compiler also behaves the same as GCC, so I am unsure if this code contains any UB (I checked the code carefully and am not aware of any). Since CompCert (a formally verified C compiler) behaves consistently with different optimization levels, I doubt there is something wrong with GCC (and LLVM). Could you please have a look and let me know if I've missed anything? Thanks! Best regards, Haoxin