From dfb36f9be274a9968048ab7137eb52a258aa7106 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sat, 7 Feb 2004 15:35:40 +0000 Subject: [PATCH] fold-const.c (negate_expr_p, [...]): Optimize -(A+B) into either (-A)-B or (-B)-A... * fold-const.c (negate_expr_p, negate_expr): Optimize -(A+B) into either (-A)-B or (-B)-A, if A or B is easily negated respectively. (fold) : Optimize (A*C) - (B*C) -> (A-B)*C for both integer types and floating point with unsafe_math_optimizations. Add similar optimization for (A*C1) - (A*C2) -> A*(C1-C2). Optimize A - B as A + (-B), if B is easily negated. From-SVN: r77453 --- gcc/ChangeLog | 9 ++++++ gcc/fold-const.c | 72 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b08da77bef..ef66edd96af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-02-07 Roger Sayle + + * fold-const.c (negate_expr_p, negate_expr): Optimize -(A+B) into + either (-A)-B or (-B)-A, if A or B is easily negated respectively. + (fold) : Optimize (A*C) - (B*C) -> (A-B)*C for both + integer types and floating point with unsafe_math_optimizations. + Add similar optimization for (A*C1) - (A*C2) -> A*(C1-C2). + Optimize A - B as A + (-B), if B is easily negated. + 2004-02-07 Kazu Hirata * c-ppoutput.c, cfganal.c, diagnostic.h, print-rtl.c, diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 264e5f01f28..b93665c94d0 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -878,6 +878,17 @@ negate_expr_p (tree t) return negate_expr_p (TREE_REALPART (t)) && negate_expr_p (TREE_IMAGPART (t)); + case PLUS_EXPR: + if (FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) + return false; + /* -(A + B) -> (-B) - A. */ + if (negate_expr_p (TREE_OPERAND (t, 1)) + && reorder_operands_p (TREE_OPERAND (t, 0), + TREE_OPERAND (t, 1))) + return true; + /* -(A + B) -> (-A) - B. */ + return negate_expr_p (TREE_OPERAND (t, 0)); + case MINUS_EXPR: /* We can't turn -(A-B) into B-A when we honor signed zeros. */ return (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations) @@ -979,6 +990,26 @@ negate_expr (tree t) case NEGATE_EXPR: return convert (type, TREE_OPERAND (t, 0)); + case PLUS_EXPR: + if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations) + { + /* -(A + B) -> (-B) - A. */ + if (negate_expr_p (TREE_OPERAND (t, 1)) + && reorder_operands_p (TREE_OPERAND (t, 0), + TREE_OPERAND (t, 1))) + return convert (type, + fold (build (MINUS_EXPR, TREE_TYPE (t), + negate_expr (TREE_OPERAND (t, 1)), + TREE_OPERAND (t, 0)))); + /* -(A + B) -> (-A) - B. */ + if (negate_expr_p (TREE_OPERAND (t, 0))) + return convert (type, + fold (build (MINUS_EXPR, TREE_TYPE (t), + negate_expr (TREE_OPERAND (t, 0)), + TREE_OPERAND (t, 1)))); + } + break; + case MINUS_EXPR: /* - (A - B) -> B - A */ if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations) @@ -6089,19 +6120,6 @@ fold (tree expr) if (integer_zerop (arg1)) return non_lvalue (convert (type, arg0)); - /* (A * C) - (B * C) -> (A-B) * C. Since we are most concerned - about the case where C is a constant, just try one of the - four possibilities. */ - - if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 1), - TREE_OPERAND (arg1, 1), 0)) - return fold (build (MULT_EXPR, type, - fold (build (MINUS_EXPR, type, - TREE_OPERAND (arg0, 0), - TREE_OPERAND (arg1, 0))), - TREE_OPERAND (arg0, 1))); - /* Fold A - (A & B) into ~B & A. */ if (!TREE_SIDE_EFFECTS (arg0) && TREE_CODE (arg1) == BIT_AND_EXPR) @@ -6158,6 +6176,34 @@ fold (tree expr) && operand_equal_p (arg0, arg1, 0)) return convert (type, integer_zero_node); + /* A - B -> A + (-B) if B is easily negatable. */ + if (!wins && negate_expr_p (arg1) + && (FLOAT_TYPE_P (type) + || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))) + return fold (build (PLUS_EXPR, type, arg0, negate_expr (arg1))); + + if (TREE_CODE (arg0) == MULT_EXPR + && TREE_CODE (arg1) == MULT_EXPR + && (INTEGRAL_TYPE_P (type) || flag_unsafe_math_optimizations)) + { + /* (A * C) - (B * C) -> (A-B) * C. */ + if (operand_equal_p (TREE_OPERAND (arg0, 1), + TREE_OPERAND (arg1, 1), 0)) + return fold (build (MULT_EXPR, type, + fold (build (MINUS_EXPR, type, + TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg1, 0))), + TREE_OPERAND (arg0, 1))); + /* (A * C1) - (A * C2) -> A * (C1-C2). */ + if (operand_equal_p (TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg1, 0), 0)) + return fold (build (MULT_EXPR, type, + TREE_OPERAND (arg0, 0), + fold (build (MINUS_EXPR, type, + TREE_OPERAND (arg0, 1), + TREE_OPERAND (arg1, 1))))); + } + goto associate; case MULT_EXPR: -- 2.30.2