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]
Other format: [Raw text]

[patch] for PR29921


Hello,

when HONOR_SIGNED_ZEROS is false, we fold 0.0 * x to 0.0, however we
still consider 0 and -0 different in operand_equal_p.  This causes
problems in constant propagation: given statement

y = 0.0 * x

if we first consider the possibility x = -1.0, we set y to constant -0.
When we later find out that x is varying, we fold the expression to 0,
which causes ice in set_lattice_value (since we are changing the value
of y to different constant).

There are basically two ways how to fix the problem: In case
HONOR_SIGNED_ZEROS = false, we can either

1) consider 0 and -0 equal in operand_equal_p, or
2) canonicalize -0 to 0 in constant propagation

I do not have a strong preference here, the patch below implements the
first choice since it seems more consistent with the rest of fold-const
regarding HONOR_SIGNED_ZEROS, but if there is any problem with this
solution, the second possibility is not difficult to implement, either.

Bootstrapped & regtested on i686.

Zdenek

	PR tree-optimization/29921
	* fold-const.c (operand_equal_p): Without HONOR_SIGNED_ZEROS, consider
	signed and unsigned zero equal.

	* gcc.dg/pr29921.c: New test.

Index: fold-const.c
===================================================================
*** fold-const.c	(revision 119043)
--- fold-const.c	(working copy)
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2584,2591 ****
  	return tree_int_cst_equal (arg0, arg1);
  
        case REAL_CST:
! 	return REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
! 				      TREE_REAL_CST (arg1));
  
        case VECTOR_CST:
  	{
--- 2584,2602 ----
  	return tree_int_cst_equal (arg0, arg1);
  
        case REAL_CST:
! 	if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
! 				   TREE_REAL_CST (arg1)))
! 	  return 1;
! 
! 	
! 	if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0))))
! 	  {
! 	    /* If we do not distinguish between signed and unsigned zero,
! 	       consider them equal.  */
! 	    if (real_zerop (arg0) && real_zerop (arg1))
! 	      return 1;
! 	  }
! 	return 0;
  
        case VECTOR_CST:
  	{
Index: testsuite/gcc.dg/pr29921.c
===================================================================
*** testsuite/gcc.dg/pr29921.c	(revision 0)
--- testsuite/gcc.dg/pr29921.c	(revision 0)
***************
*** 0 ****
--- 1,20 ----
+ /* With -ffast-math, the latice value for t changes from -0.0 to 0.0 in this
+    testcase.  */
+ 
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -ffast-math" } */
+ 
+ double test (int param)
+ {
+   double a = 0.0, b = -1.0, t;
+   int i;
+ 
+   for (i = 0; i < 100; i++)
+     {
+       t = a * b;
+       if (param)
+ 	b = 2.0;
+     }
+ 
+   return t;
+ }


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