https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125444
Bug ID: 125444
Summary: Wrong code issue at -O1 and above from GCC-15.1 to
17.0 (trunk) versions
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: haoxintu at gmail dot com
Target Milestone: ---
Hi,
We found an interesting wrong-code issue with our new testing tool, where
gcc-trunk with -O1 and above eliminates a live code block (if-then-branch) for
some reasons. Please look at the details below.
$cat small.c
#include <stdlib.h>
#include <stdint.h>
# define CHAR_BIT 8
#define safe_unary_minus_func_int16_t_s(_si) \
({ int16_t si = (_si) ; \
(((int16_t)(si))==(INT16_MIN))? \
((int16_t)(si)): \
(-((int16_t)(si))) \
;})
#define safe_lshift_func_uint16_t_u_u(_left,_right) \
({ uint16_t left = (_left); unsigned int right = (_right) ; \
((((unsigned int)(right)) >= sizeof(uint16_t)*CHAR_BIT) \
|| (((uint16_t)(left)) > ((UINT16_MAX) >> ((unsigned
int)(right))))) \
? ((uint16_t)(left)) \
: (((uint16_t)(left)) << ((unsigned int)(right)));})
int idx=0;
void __attribute__((noinline)) marker_171() { idx++; }
int8_t *a;
uint16_t b;
int8_t **c(int8_t **f);
static uint8_t d(int8_t *const *, int8_t **, uint8_t);
uint8_t e() {
c(NULL);
return 0;
}
int8_t **c(int8_t **f) {
uint8_t aa = 3;
int8_t **g = &a;
int i;
for (i = 0; i < 10; i++)
d(f, g, b ^= safe_unary_minus_func_int16_t_s(aa));
return g;
}
uint8_t d(int8_t *const *l, int8_t **j, uint8_t k) {
if (safe_lshift_func_uint16_t_u_u(0, k), k)
;
else
marker_171();
return k;
}
int main() { e(); __builtin_printf("%d\n", idx);};
$gcc-trunk -w -std=c99 -O0 small.c -o t0 ; ./t0
5
$gcc-trunk -w -std=c99 -O1 small.c -o t1 ; ./t1
0
$gcc-trunk -w -std=c99 -O2 small.c -o t2 ; ./t2
0
$gcc-trunk -w -std=c99 -O3 small.c -o t3 ; ./t3
0
Interestingly, the function call `marker_171` is eliminated in the binary
t1/t2/t3.
$objdump -d t0 | grep marker_171
0000000000401126 <marker_171>:
401212: e8 0f ff ff ff call 401126 <marker_171>
$objdump -d t1 | grep marker_171
0000000000401128 <marker_171>:
$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/17.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 17.0.0 20260501 (experimental) (GCC)
Reproduced in Godblot: https://godbolt.org/z/b6Gc7zGYz. From there, it seems
there is something broken after GCC-15.1.
Could you please help check it?
Thanks,
Haoxin