https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121992
--- Comment #4 from Anonymous <iamanonymous.cs at gmail dot com> ---
(In reply to Andrew Pinski from comment #2)
> 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.
got it, thank you andrew!