patch for GCC floating-point nonsense bug

Paul Eggert eggert@twinsun.com
Sun Nov 9 16:38:00 GMT 1997


   Date: Sun, 9 Nov 1997 16:27:13 -0500 (EST)
   From: Stephen L Moshier <moshier@world.std.com>

   > double foo(int negative) { return negative ? -0.0 : 0.0; }

   How should it be fixed?  We might add another argument that means
   check for identical bit pattern if the args are constants.

No, operand_equal_p is supposed to return 0 when comparing -0.0 to 0.0;
see the comment at the start of operand_equal_p.

Here's a proposed patch for this GCC bug.  While I was fixing it
I found what appear to be other instances of the bug; this patch fixes
all the instances that I found.

1997-11-09  Paul Eggert  <eggert@twinsun.com>

	Fix some confusion with IEEE minus zero.

	* real.h (REAL_VALUES_IDENTICAL): New macro.

	* expr.c (is_zeros_p): Don't consider -0.0 to be all zeros.
	* fold-const.c (operand_equal_p): Don't consider -0.0 to be
	identical to 0.0.
	* tree.c (simple_cst_equal): Don't consider -0.0 to have the
	same tree structure as 0.0.

	* varasm.c (immed_real_const_1): Use new REAL_VALUES_IDENTICAL
	macro instead of doing it by hand.

===================================================================
RCS file: RCS/real.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** real.h	1997/09/19 11:26:51	1.1
--- real.h	1997/11/09 22:58:58	1.2
***************
*** 285,290 ****
--- 285,297 ----
  #define REAL_VALUE_TO_TARGET_LONG_DOUBLE(a, b) REAL_VALUE_TO_TARGET_DOUBLE (a, b)
  #endif
  
+ /* Compare two floating-point objects for bitwise identity.
+    This is not the same as comparing for equality on IEEE hosts:
+    -0.0 equals 0.0 but they are not identical, and conversely
+    two NaNs might be identical but they cannot be equal.  */
+ #define REAL_VALUES_IDENTICAL(x, y) \
+   (!bcmp ((char *) &(x), (char *) &(y), sizeof (REAL_VALUE_TYPE)))
+ 
  /* Compare two floating-point values for equality.  */
  #ifndef REAL_VALUES_EQUAL
  #define REAL_VALUES_EQUAL(x, y) ((x) == (y))
===================================================================
RCS file: RCS/expr.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** expr.c	1997/10/18 15:01:48	1.1
--- expr.c	1997/11/09 22:58:58	1.2
***************
*** 3476,3482 ****
  	is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
  
      case REAL_CST:
!       return REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconst0);
  
      case CONSTRUCTOR:
        if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
--- 3476,3482 ----
  	is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
  
      case REAL_CST:
!       return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
  
      case CONSTRUCTOR:
        if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
===================================================================
RCS file: RCS/tree.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** tree.c	1997/10/18 20:54:23	1.1
--- tree.c	1997/11/09 22:58:58	1.2
***************
*** 3832,3838 ****
  	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
  
      case REAL_CST:
!       return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
  
      case STRING_CST:
        return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
--- 3832,3838 ----
  	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
  
      case REAL_CST:
!       return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
  
      case STRING_CST:
        return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
===================================================================
RCS file: RCS/varasm.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** varasm.c	1997/10/18 15:22:16	1.1
--- varasm.c	1997/11/09 22:58:58	1.2
***************
*** 2245,2252 ****
  
    /* Detect special cases.  */
  
!   /* Avoid REAL_VALUES_EQUAL here in order to distinguish minus zero.  */
!   if (!bcmp ((char *) &dconst0, (char *) &d, sizeof d))
      return CONST0_RTX (mode);
    /* Check for NaN first, because some ports (specifically the i386) do not
       emit correct ieee-fp code by default, and thus will generate a core
--- 2245,2251 ----
  
    /* Detect special cases.  */
  
!   if (REAL_VALUES_IDENTICAL (dconst0, d))
      return CONST0_RTX (mode);
    /* Check for NaN first, because some ports (specifically the i386) do not
       emit correct ieee-fp code by default, and thus will generate a core
===================================================================
RCS file: RCS/fold-const.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** fold-const.c	1997/10/19 14:27:35	1.1
--- fold-const.c	1997/11/09 22:58:58	1.2
***************
*** 1795,1802 ****
        case REAL_CST:
  	return (! TREE_CONSTANT_OVERFLOW (arg0)
  		&& ! TREE_CONSTANT_OVERFLOW (arg1)
! 		&& REAL_VALUES_EQUAL (TREE_REAL_CST (arg0),
! 				      TREE_REAL_CST (arg1)));
  
        case COMPLEX_CST:
  	return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
--- 1795,1802 ----
        case REAL_CST:
  	return (! TREE_CONSTANT_OVERFLOW (arg0)
  		&& ! TREE_CONSTANT_OVERFLOW (arg1)
! 		&& REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
! 					  TREE_REAL_CST (arg1)));
  
        case COMPLEX_CST:
  	return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),



More information about the Gcc-bugs mailing list