https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79619
Bug ID: 79619 Summary: store via pointer obtained from alternate address space offset 0 dropped Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: roland at gnu dot org CC: rth at gcc dot gnu.org Target Milestone: --- Target: x86_64-elf Given this test code: void bug(void) { *(*(char*__seg_fs*)0) = 1; } void nobug(void) { *(*(char*__seg_fs*)0) = 1; *(*(char*__seg_fs*)8) = 1; } I get this: .text .globl bug .type bug, @function bug: .LFB0: .cfi_startproc rep ret .cfi_endproc .LFE0: .size bug, .-bug .globl nobug .type nobug, @function nobug: .LFB1: .cfi_startproc movq %fs:0, %rax movb $1, (%rax) movq %fs:8, %rax movb $1, (%rax) ret .cfi_endproc .LFE1: .size nobug, .-nobug .ident "GCC: (GNU) 6.2.0" x86_64 GCC at -O1 or better silently elides the store in bug. My guess is that it's deciding *(TYPE __seg_fs*)0 constitutes a null pointer dereference and is therefore UB so screw everybody. But alternate-address-space 0 is not a null pointer, it's just like any other alternate-address-space pointer value and should not be treated specially. (Except that if you wanted to "know" that the target ABI is that %fs:0 == %fs.base, then you can optimize (*(char*__seg_fs*)0)[n] accesses to direct "%fs:n"; LLVM does this for x86-64 glibc-based targets. But that's a missed optimization opportunity unrelated to this bug.) But note how the mere presence of a different alternate-address-space reference not at zero in the same function (nobug) makes it emit both stores! Definitely fishy. Maybe related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66768 but that's beyond my ken.