* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132480
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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);
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))
+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):
--- /dev/null
+/* { 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" } } */
#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
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)
{
}
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)
{
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)
{
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)
{
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);