This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
emit-rtl.c NaN bug
- To: egcs-patches at cygnus dot com
- Subject: emit-rtl.c NaN bug
- From: Stephen L Moshier <moshier at mediaone dot net>
- Date: Wed, 25 Nov 1998 21:29:14 -0500 (EST)
- Reply-To: moshier at mediaone dot net
> This program prints the bit pattern of the NaN (Not-a-Number)
> which is 0x7fc00000. Compiled without optimizations it indeed
> does so, but even -O1 causes it to print 0xffc00000 instead.
The immediate cause of this problem is that make_nan did not always
output the desired sign bit, while enan does input the sign correctly.
The previous fix applied to emit-rtl.c should be removed, since it
causes a reload abort in egcs.
Original test case below.
* emit-rtl.c (gen_lowpart_common): Remove earlier change.
real.c (make_nan): Make SIGN arg actually specify the sign bit.
*** /tmp/T0a004AE Wed Nov 25 17:23:50 1998
--- emit-rtl.c Wed Nov 25 17:21:45 1998
***************
*** 783,791 ****
i = INTVAL (x);
r = REAL_VALUE_FROM_TARGET_SINGLE (i);
- /* Avoid changing the bit pattern of a NaN. */
- if (REAL_VALUE_ISNAN (r))
- return 0;
return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
}
#else
--- 783,788 ----
***************
*** 824,831 ****
i[0] = low, i[1] = high;
r = REAL_VALUE_FROM_TARGET_DOUBLE (i);
- if (REAL_VALUE_ISNAN (r))
- return 0;
return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
}
#else
--- 821,826 ----
*** /tmp/T0a004AH Wed Nov 25 17:24:04 1998
--- real.c Wed Nov 25 16:56:51 1998
***************
*** 6260,6270 ****
abort ();
}
if (REAL_WORDS_BIG_ENDIAN)
! *nan++ = (sign << 15) | *p++;
while (--n != 0)
*nan++ = *p++;
if (! REAL_WORDS_BIG_ENDIAN)
! *nan = (sign << 15) | *p;
}
/* This is the inverse of the function `etarsingle' invoked by
--- 6260,6270 ----
abort ();
}
if (REAL_WORDS_BIG_ENDIAN)
! *nan++ = (sign << 15) | (*p++ & 0x7fff);
while (--n != 0)
*nan++ = *p++;
if (! REAL_WORDS_BIG_ENDIAN)
! *nan = (sign << 15) | (*p & 0x7fff);
}
/* This is the inverse of the function `etarsingle' invoked by
-------------
/* This program prints the bit pattern of the NaN (Not-a-Number)
which is 0x7fc00000. Compiled without optimizations it indeed
does so, but even -O1 causes it to print 0xffc00000 instead. */
#include <stdio.h>
#include <math.h>
#include <float.h>
typedef union
{
float value;
unsigned word;
} float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
do { \
float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
do { \
float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
} while (0)
int main (void)
{
unsigned iv;
float fv;
/* _control87(0x033f, 0xffff);*/ /* mask all numeric exceptions */
SET_FLOAT_WORD(fv, 0x7fc00000U);
GET_FLOAT_WORD(iv, fv);
printf ("SET_FLOAT_WORD: %f, GET_FLOAT_WORD: %x\n", fv, iv);
return 0;
}