summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2004-07-03 11:57:18 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-07-03 11:57:18 -0700
commitf05ef4220a4cd6c3c8aafc41efd1f4165865825f (patch)
tree4f592787da68b05ca62b4a01784fe39a83f221f2 /gcc
parentfa9784263f4e37528e0acb57019488a735221b7f (diff)
downloadgcc-f05ef4220a4cd6c3c8aafc41efd1f4165865825f.tar.gz
tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Don't fold fp plus with minus.
* tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Don't fold fp plus with minus. From-SVN: r84061
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040703-1.c12
-rw-r--r--gcc/tree-ssa-dom.c20
2 files changed, 32 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040703-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040703-1.c
new file mode 100644
index 00000000000..8f6ae167d3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040703-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom2" } */
+
+float foo(float x)
+{
+ x += 1;
+ x -= 1;
+ return x;
+}
+
+/* We should *not* fold the arithmetic. */
+/* { dg-final { scan-tree-dump-times "0.0" 0 "dom2"} } */
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index b556b4eedf2..356daacb21c 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1945,6 +1945,25 @@ simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *walk_data,
tree type = TREE_TYPE (TREE_OPERAND (stmt, 0));
tree t;
+ /* If we care about correct floating point results, then
+ don't fold x + c1 - c2. Note that we need to take both
+ the codes and the signs to figure this out. */
+ if (FLOAT_TYPE_P (type)
+ && !flag_unsafe_math_optimizations
+ && (rhs_def_code == PLUS_EXPR
+ || rhs_def_code == MINUS_EXPR))
+ {
+ bool neg = false;
+
+ neg ^= (rhs_code == MINUS_EXPR);
+ neg ^= (rhs_def_code == MINUS_EXPR);
+ neg ^= real_isneg (TREE_REAL_CST_PTR (outer_const));
+ neg ^= real_isneg (TREE_REAL_CST_PTR (def_stmt_op1));
+
+ if (neg)
+ goto dont_fold_assoc;
+ }
+
/* Ho hum. So fold will only operate on the outermost
thingy that we give it, so we have to build the new
expression in two pieces. This requires that we handle
@@ -1979,6 +1998,7 @@ simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *walk_data,
}
}
}
+ dont_fold_assoc:;
}
/* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR