https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124453
--- Comment #4 from LIU Hao <lh_mouse at 126 dot com> --- Also this one, not sure whether it's related: (https://gcc.godbolt.org/z/vvK9exavd) ``` typedef __UINT64_TYPE__ uint64_t; typedef struct Value Value; struct Value { uint64_t a : 1; uint64_t b : 4; uint64_t c : 4; uint64_t d : 55; }; inline void do_atomic_load_uint64_rlx(void* out, volatile const void* mem) { *(uint64_t*) out = __atomic_load_n((uint64_t*) mem, __ATOMIC_RELAXED); } void do_something(Value* p); int wants_no_b_or_d(Value* p) { Value val; do_atomic_load_uint64_rlx(&val, p); if(val.b == 0 && val.d == 0) do_something(p); return 42; } ``` GCC 16 ``` "wants_no_b_or_d": mov rax, QWORD PTR [rdi] test al, 30 jne .L10 cmp rax, 511 jbe .L14 .L10: mov eax, 42 ret .L14: sub rsp, 8 call "do_something" mov eax, 42 add rsp, 8 ret ``` Clang 22 ``` wants_no_b_or_d: mov rax, qword ptr [rdi] test rax, -482 je .LBB0_1 mov eax, 42 ret .LBB0_1: push rax call do_something@PLT add rsp, 8 mov eax, 42 ret ``` The workaround is to disable optimization on `val` after the atomic load: ``` Value val; do_atomic_load_uint64_rlx(&val, p); __asm__ ("" : "+r"(val)); ```
