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.