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 /gcc/tree-ssa-reassoc.c | |
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
Diffstat (limited to 'gcc/tree-ssa-reassoc.c')
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 22 |
1 files changed, 18 insertions, 4 deletions
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) { |