https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128266
Bug ID: 128266
Summary: wrong code at -O1 and above: an unused
atomic_load_explicit from a volatile _Atomic object is
removed
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: kyuwoncho18 at gmail dot com
Target Milestone: ---
Target: x86_64-pc-linux-gnu
#include <signal.h>
#include <stdatomic.h>
#include <sys/mman.h>
#include <unistd.h>
static void handler(int sig) { (void)sig; _exit(42); }
int main(void) {
signal(SIGSEGV, handler);
void *p = mmap(0, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED)
return 3;
atomic_load_explicit((volatile _Atomic unsigned *)p, memory_order_relaxed);
return 0;
}
godbolt: https://godbolt.org/z/vW45P96sj
A load from a volatile object is an observable access even when its value is
unused (C17 5.1.2.3; the 7.17.1 note says the atomic generic functions preserve
volatility). At -O0 and with -O2 -fno-tree-dce the load faults on the PROT_NONE
page and the SIGSEGV handler exits with 42; at -O1, -O2, -O3 and -Os the load
is removed and the program exits with 0.