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

            Bug ID: 120607
           Summary: Incorrect optimization of multiple
                    __builtin_unreachable() conditions leads to logic
                    errors in control flow
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 2023091106 at cauc dot edu.cn
  Target Milestone: ---

this problems exist in X86_64 gcc13/14/15。
GCC exhibits incorrect optimization behavior when handling multiple (>2)
__builtin_unreachable() statements.

When only a single __builtin_unreachable() is used, or when compiling with -O0,
the code executes correctly. However, when two or more __builtin_unreachable()
statements are present, the program behaves correctly under -O0, but under -O2,
GCC incorrectly folds the entire test_builtin_unreachable() function, leading
to an infinite loop at runtime.

This suggests that the optimizer does not correctly account for the
interactions of multiple unreachable paths during optimization.

========the gcc code========
#include <stdio.h>
#include <stdlib.h>

void test_output() {
    printf("the code is executing\n");
}

void test_builtin_unreachable() {
    int bb = 2;
    if ((bb & ~3) != 0)
        __builtin_unreachable();
    if ((bb & 1) == 0)
        __builtin_unreachable();
    if (bb == 2)
        printf("the value of bb is: %d\n", bb);
}

int main() {
    test_output();
    test_builtin_unreachable();
    return 0;
}

========the gcc output========
$ gcc -O0 test.c -o testclear
$ ./test
the code is executing
the value of bb is: 2

$ gcc -O2 test.c -o test
$ ./test
the code is executing
the code is executing
the code is executing
……
the code is executing
the code is executing
the code is executing
Segmentation fault (core dumped)

========the gcc versions=========
$ gcc-14 -v
Using built-in specs.
COLLECT_GCC=gcc-14
COLLECT_LTO_WRAPPER=/opt/gcc-14/libexec/gcc/x86_64-pc-linux-gnu/14.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/opt/gcc-14 --enable-languages=c,c++
--disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 14.1.0 (GCC)


========the assembly code=========
when use the -O2, we can see the function test_builtin_unreachable is none, so
the test_output always be executing:

test_output:
        lea     rdi, [rip + .Lstr]
        jmp     puts@PLT

test_builtin_unreachable:

main:
        push    rax
        lea     rdi, [rip + .Lstr]
        call    puts@PLT

.Lstr:
        .asciz  "the code is executing"

Reply via email to