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

            Bug ID: 120295
           Summary: Wrong code on -O3 for trunk version (live code is
                    wrongly eliminated)
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          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. It seems
gcc-trunk with -O3 eliminates a live code block for some reasons. Please look
at the details below.

$cat small.c
#include <stdint.h>
#include <stdio.h>
struct {
  signed a;
} b;
#define t(w, x)                                                               
\
  ({                                                                          
\
    int64_t y = w;                                                            
\
    y;                                                                        
\
  })
#define z(aa, ac)                                                             
\
  ({                                                                          
\
    int16_t ad = aa;                                                          
\
    ad<0 || ad> e;                                                            
\
  })
int a, f, j, l;
int8_t c, k, g, e;
int16_t d[2] = {0};
int32_t *i = &j;
void marker_37() {
  a++;
  printf("%d\n", a);
}
uint64_t m(uint32_t, int8_t, uint32_t, int16_t);
int32_t n(uint8_t, int64_t, int32_t);
int32_t o(uint32_t, int64_t, uint32_t);
uint16_t p(void) {
  int32_t *r = &l;
  *r |= t((m(c, c, 0, c), b.a), );
  return 0;
}
uint64_t m(uint32_t q, int8_t v, uint32_t s, int16_t u) {
  uint16_t ab = 5;
  if (n(ab, d[1], q))
    for (; g; g++)
      ;
  return c;
}
int32_t n(uint8_t e, int64_t ae, int32_t af) {
  uint32_t ag = 4;
  int32_t *ah = &f;
  *ah = z(o(f, af, ag), 4);
  return *i;
}
int32_t o(uint32_t ai, int64_t aj, uint32_t ak) {
  for (; e; e--) {
    int32_t *al = &f;
    for (; k; k++)
      *al = 0;
  }
  if (18446744073709551606UL != (uint64_t) aj)
    ;
  else
    marker_37();
  return ak;
}
int main() {
  c = 0xf6;
  p();
  return 0;
}

$gcc-trunk -w -std=c99 -O0 small.c -o t0 ; ./t0
1

$gcc-trunk -w -std=c99 -O1 small.c -o t1 ; ./t1
1

$gcc-trunk -w -std=c99 -O3 small.c -o t2 ; ./t2
Segmentation fault (core dumped)

$gcc-11.1.0 -w -std=c99 -O3 small.c -o t4 ; ./t4
1

$clang-20 -w -std=c99 -O3 small.c -o t5 ; ./t5
1

Interestingly, the function call `marker_37` is eliminated in the binary t2.

$objdump -S t2 | grep marker_37
0000000000401150 <marker_37>:

$objdump -S t1 | grep marker_37
0000000000401128 <marker_37>:
  4011c2:       e8 61 ff ff ff          callq  401128 <marker_37>

$gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/home/research/compilers/gcc/build-master/libexec/gcc/x86_64-pc-linux-gnu/16.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure
--prefix=/home/research/compilers/gcc/build-master --enable-bootstrap
--enable-checking=release --enable-languages=c,c++ --enable-multilib
--program-suffix=-trunk : (reconfigured) ../configure
--prefix=/home/research/compilers/gcc/build-master --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 20250515 (experimental) (GCC) 


Reproduced in Godblot: https://godbolt.org/z/1x1Kvb38z. From there, it seems
there is something broken after GCC-14.1.

Could you please help check it?

Thanks,
Haoxin

Reply via email to