diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-04 23:42:48 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-04 23:42:48 +0000 |
commit | cf58ef1d6fbe1a6314a68061ffb09439410751b3 (patch) | |
tree | 9617a20782252283684d9c8639c9ad8e7fbf7873 /gcc/fold-const.c | |
parent | b518d98cdf1091c3dd4cefa5d959b69677197394 (diff) | |
download | gcc-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.c | 79 |
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); |