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

Reply via email to