This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

emit-rtl.c NaN bug



>  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;
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]