https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117149
Bug ID: 117149 Summary: GCC's optimizer intermittently generates erroneous thread-local storage code, causing segmentation fault Product: gcc Version: 14.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: devraymondsh at gmail dot com Target Milestone: --- I have encountered a critical bug in GCC's optimizer when compiling a small project using nolibc. The project doesn't utilize thread-local storage (TLS) at all, yet GCC generates instructions to load from the `%fs` register, which is used to reference thread-local variables in x86-64 architecture. This behavior is incorrect and leads to a segmentation fault when the generated program is run. Specifically, the following problematic instruction is generated: 401010: 64 48 8b 04 25 28 00 00 00 mov %fs:0x28,%rax This instruction attempts to load a value from the TLS area into `%rax`, which shouldn't happen because the project does not involve any thread-local variables. The loading from `%fs:0x28` causes a segmentation fault when executed, as this area is not valid for this simple nolibc program. Steps to Reproduce: 1. Here’s a minimal reproducible example: static void memcpy(volatile char *__restrict dest, const char *__restrict src, long n) { for (long i = 0; i < n; ++i) dest [i] = src [i]; } extern "C" void __attribute__((noinline, noreturn)) start(void *s) { const char source [] = "Hello, World!"; char dest [20] = {0}; memcpy(dest, source, sizeof(source)); __asm__ __volatile__("syscall" ::"a"(60), "D"(0) : "rcx", "r11", "memory"); __builtin_unreachable(); } __asm__(".text \n" ".global _start \n" "_start: \n" " xor %rbp,%rbp \n" " mov %rsp,%rdi \n" " andq $-16,%rsp \n" " call start \n"); 2. Compile the code with optimization flags: gcc gcc_bug.cpp -o gcc_bug -ffreestanding -nostdlib -static -O3 3. Disassemble the binary using: objdump -D --section=.text ./gcc_bug The disassembly reveals that, at address `0x401010`, GCC inserts the following invalid instruction: 401010: 64 48 8b 04 25 28 00 00 00 mov %fs:0x28,%rax This is unexpected, as there are no thread-local variables in the program. This bug appears sporadically when using different optimization flags such as `-static`, `-fstack-protector`, `-flto`, or various `-Ox` levels. Notes: - The bug does not always appear, but it is more likely to manifest with different combinations of optimization flags like `-static`, `-fstack-protector`, `-flto`, and `-Ox`.