diff options
author | Richard Guenther <rguenther@suse.de> | 2008-02-20 14:13:47 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-02-20 14:13:47 +0000 |
commit | 2dc0f63301e9bddc5520f2a283d7a8bfdac21fb6 (patch) | |
tree | c5e05848bec7920261ee516331b46b45437148c4 | |
parent | 1c8bd6a397365e8cc69507f8c311f1fda3d6ebec (diff) | |
download | gcc-2dc0f63301e9bddc5520f2a283d7a8bfdac21fb6.tar.gz |
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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c | 15 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 22 | ||||
-rw-r--r-- | gcc/tree.h | 2 |
6 files changed, 47 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50456696bcb..18dd9dc4a31 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 a33b2b07a46..aba71b6bf41 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 4037344d742..7e947ec4b27 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 00000000000..4d4dfeb446b --- /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 a4118c92339..6e6f5f7f442 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 99c4aeadab1..f98afe9be80 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); |