https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86947
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |RESOLVED Resolution|--- |INVALID --- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- Thanks. This is invalid: unsigned short *_Pmsw (double * px) { volatile _Dconst *ps = (_Dconst *)(char *)px; return (unsigned short *)&ps->_Word[3]; } if (x < 0.0) { ((*_Pmsw (&(x))) ^= ((unsigned short) 0x8000)); neg = 1; } else neg = 0; /* _Eps._Double = 1.0 */ /* aliasing issue here. Compiler uses old value of x */ if (x < _Eps._Double) { the compiler can CSE the value of x across the *_Pmsw (&x) modification because 1) the load from x via an lvalue of type unsigned short violates type based aliasing rules 2) the store to x via an lvalue of type unsigned short changes the dynamic type of x which in turn makes the later load of x violate type based aliasing rules You can use -fno-strict-aliasing to make your code work. You might think that having the _Dconst union in scope makes your program conforming but GCC does not implement this reading of the standard unless you use -fno-strict-aliasing which is not the default when optimizing with -O2 or higher.