https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121992
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- let me explain a little bit more: v w = {0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}; unsigned short *p = (unsigned short *)&w; int main() { w.h = 1; // write to w via the struct return (short)(e(*p, 3) + *p - 4661) + *p == 4661 ? 0 : 1; // reads via unsigned short since bitfields and underlying types are not alias "compatible" the read of a pointer and the write to w are infered not to the same variable so the read can be moved before the write. as seen by the assembly: ``` mov rax, QWORD PTR "p"[rip] ... movzx ecx, WORD PTR [rax] or BYTE PTR "w"[rip], 1 ``` Either use an union for the w to get the unsigned short value, memcpy or -fno-strict-aliasing and you will get the correct result.