aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-02-20 14:13:47 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-02-20 14:13:47 +0000
commit2dc0f63301e9bddc5520f2a283d7a8bfdac21fb6 (patch)
treec5e05848bec7920261ee516331b46b45437148c4
parent1c8bd6a397365e8cc69507f8c311f1fda3d6ebec (diff)
downloadgcc-2dc0f63301e9bddc5520f2a283d7a8bfdac21fb6.zip
gcc-2dc0f63301e9bddc5520f2a283d7a8bfdac21fb6.tar.gz
gcc-2dc0f63301e9bddc5520f2a283d7a8bfdac21fb6.tar.bz2
tree.h (fold_real_zero_addition_p): Declare.
2008-02-20 Richard Guenther <rguenther@suse.de> * tree.h (fold_real_zero_addition_p): Declare. * fold-const.c (fold_real_zero_addition_p): Export. * tree-ssa-reassoc.c (eliminate_using_constants): Also handle floating-point operations with zero and one. * gcc.dg/tree-ssa/reassoc-13.c: New testcase. From-SVN: r132480
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c15
-rw-r--r--gcc/tree-ssa-reassoc.c22
-rw-r--r--gcc/tree.h2
6 files changed, 47 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5045669..18dd9dc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-20 Richard Guenther <rguenther@suse.de>
+
+ * tree.h (fold_real_zero_addition_p): Declare.
+ * fold-const.c (fold_real_zero_addition_p): Export.
+ * tree-ssa-reassoc.c (eliminate_using_constants): Also handle
+ floating-point operations with zero and one.
+
2008-02-20 Paolo Bonzini <bonzini@gnu.org>
* doc/install.texi: Correct references to CFLAGS, replacing them
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index a33b2b0..aba71b6 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -134,7 +134,6 @@ static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *);
static tree fold_binary_op_with_conditional_arg (enum tree_code, tree,
tree, tree,
tree, tree, int);
-static bool fold_real_zero_addition_p (const_tree, const_tree, int);
static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
tree, tree, tree);
static tree fold_inf_compare (enum tree_code, tree, tree, tree);
@@ -6426,7 +6425,7 @@ fold_binary_op_with_conditional_arg (enum tree_code code,
X - 0 is not the same as X because 0 - 0 is -0. In other rounding
modes, X + 0 is not the same as X because -0 + 0 is 0. */
-static bool
+bool
fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
{
if (!real_zerop (addend))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4037344..7e947ec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-02-20 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/reassoc-13.c: New testcase.
+
2008-02-20 Ira Rosen <irar@il.ibm.com>
* lib/target-supports.exp (check_effective_target_vect_unpack):
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c
new file mode 100644
index 0000000..4d4dfeb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ffast-math -fdump-tree-reassoc1 -fdump-tree-optimized" } */
+
+double foo(double a)
+{
+ double tmp = 5.0;
+ double tmp2 = a + tmp;
+ tmp2 = tmp2 - a;
+ return a + tmp2 - 5.0;
+}
+
+/* { dg-final { scan-tree-dump-not "\\\+ 0.0" "reassoc1" } } */
+/* { dg-final { scan-tree-dump "return a;" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "reassoc1" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index a4118c9..6e6f5f7 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "pointer-set.h"
#include "cfgloop.h"
+#include "flags.h"
/* This is a simple global reassociation pass. It is, in part, based
on the LLVM pass of the same name (They do some things more/less
@@ -598,8 +599,10 @@ eliminate_using_constants (enum tree_code opcode,
VEC(operand_entry_t, heap) **ops)
{
operand_entry_t oelast = VEC_last (operand_entry_t, *ops);
+ tree type = TREE_TYPE (oelast->op);
- if (oelast->rank == 0 && INTEGRAL_TYPE_P (TREE_TYPE (oelast->op)))
+ if (oelast->rank == 0
+ && (INTEGRAL_TYPE_P (type) || FLOAT_TYPE_P (type)))
{
switch (opcode)
{
@@ -660,7 +663,11 @@ eliminate_using_constants (enum tree_code opcode,
}
break;
case MULT_EXPR:
- if (integer_zerop (oelast->op))
+ if (integer_zerop (oelast->op)
+ || (FLOAT_TYPE_P (type)
+ && !HONOR_NANS (TYPE_MODE (type))
+ && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
+ && real_zerop (oelast->op)))
{
if (VEC_length (operand_entry_t, *ops) != 1)
{
@@ -675,7 +682,10 @@ eliminate_using_constants (enum tree_code opcode,
return;
}
}
- else if (integer_onep (oelast->op))
+ else if (integer_onep (oelast->op)
+ || (FLOAT_TYPE_P (type)
+ && !HONOR_SNANS (TYPE_MODE (type))
+ && real_onep (oelast->op)))
{
if (VEC_length (operand_entry_t, *ops) != 1)
{
@@ -690,7 +700,11 @@ eliminate_using_constants (enum tree_code opcode,
case BIT_XOR_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
- if (integer_zerop (oelast->op))
+ if (integer_zerop (oelast->op)
+ || (FLOAT_TYPE_P (type)
+ && (opcode == PLUS_EXPR || opcode == MINUS_EXPR)
+ && fold_real_zero_addition_p (type, oelast->op,
+ opcode == MINUS_EXPR)))
{
if (VEC_length (operand_entry_t, *ops) != 1)
{
diff --git a/gcc/tree.h b/gcc/tree.h
index 99c4aea..f98afe9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4851,6 +4851,8 @@ extern enum tree_code invert_tree_comparison (enum tree_code, bool);
extern bool tree_expr_nonzero_p (tree);
extern bool tree_expr_nonzero_warnv_p (tree, bool *);
+extern bool fold_real_zero_addition_p (const_tree, const_tree, int);
+
/* In builtins.c */
extern tree fold_call_expr (tree, bool);
extern tree fold_builtin_fputs (tree, tree, bool, bool, tree);