This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] for PR29921
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: roger at eyesopen dot com
- Date: Tue, 21 Nov 2006 23:46:00 +0100
- Subject: [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;
+ }