summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-04 23:42:48 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-04 23:42:48 +0000
commitcf58ef1d6fbe1a6314a68061ffb09439410751b3 (patch)
tree9617a20782252283684d9c8639c9ad8e7fbf7873 /gcc/fold-const.c
parentb518d98cdf1091c3dd4cefa5d959b69677197394 (diff)
downloadgcc-cf58ef1d6fbe1a6314a68061ffb09439410751b3.tar.gz
* fold-const.c (fold <PLUS_EXPR>): Transform x+x into x*2.0.
Optimize x*c+x and x+x*c into x*(c+1) and x*c1+x*c2 into x*(c1+c2) for floating point expressions with -ffast-math. (fold <MULT_EXPR>): Don't transform x*2.0 into x+x. * expmed.c (expand_mult): Wrap long line. Expand x*2.0 as x+x. * gcc.dg/20030804-1.c: New test case. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70158 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index c4faf075d0d..4dd606f68bf 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5659,14 +5659,72 @@ fold (tree expr)
same));
}
}
+ else
+ {
+ /* See if ARG1 is zero and X + ARG1 reduces to X. */
+ if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
+ return non_lvalue (convert (type, arg0));
- /* See if ARG1 is zero and X + ARG1 reduces to X. */
- else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
- return non_lvalue (convert (type, arg0));
+ /* Likewise if the operands are reversed. */
+ if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
+ return non_lvalue (convert (type, arg1));
- /* Likewise if the operands are reversed. */
- else if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
- return non_lvalue (convert (type, arg1));
+ /* Convert x+x into x*2.0. */
+ if (operand_equal_p (arg0, arg1, 0))
+ return fold (build (MULT_EXPR, type, arg0,
+ build_real (type, dconst2)));
+
+ /* Convert x*c+x into x*(c+1). */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg0) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
+ && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
+ {
+ REAL_VALUE_TYPE c;
+
+ c = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
+ real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
+ return fold (build (MULT_EXPR, type, arg1,
+ build_real (type, c)));
+ }
+
+ /* Convert x+x*c into x*(c+1). */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
+ && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
+ {
+ REAL_VALUE_TYPE c;
+
+ c = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
+ real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
+ return fold (build (MULT_EXPR, type, arg0,
+ build_real (type, c)));
+ }
+
+ /* Convert x*c1+x*c2 into x*(c1+c2). */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg0) == MULT_EXPR
+ && TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
+ && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
+ && operand_equal_p (TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg1, 0), 0))
+ {
+ REAL_VALUE_TYPE c1, c2;
+
+ c1 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
+ c2 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
+ real_arithmetic (&c1, PLUS_EXPR, &c1, &c2);
+ return fold (build (MULT_EXPR, type,
+ TREE_OPERAND (arg0, 0),
+ build_real (type, c1)));
+ }
+ }
bit_rotate:
/* (A << C1) + (A >> C2) if A is unsigned and C1+C2 is the size of A
@@ -5954,15 +6012,6 @@ fold (tree expr)
&& real_minus_onep (arg1))
return fold (build1 (NEGATE_EXPR, type, arg0));
- /* x*2 is x+x */
- if (! wins && real_twop (arg1)
- && (*lang_hooks.decls.global_bindings_p) () == 0
- && ! CONTAINS_PLACEHOLDER_P (arg0))
- {
- tree arg = save_expr (arg0);
- return fold (build (PLUS_EXPR, type, arg, arg));
- }
-
if (flag_unsafe_math_optimizations)
{
enum built_in_function fcode0 = builtin_mathfn_code (arg0);