From b14a9c57cff644851084c4f602437c7fa353c5d0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 30 Jun 2015 11:58:48 +0000 Subject: [PATCH] fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x)... 2015-06-30 Richard Biener * fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x), ~ (-A) to A - 1, ~ (A - 1) or ~ (A + -1) to -A and some cases of ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify to ... * match.pd: ... here. Add a few cases of A - B -> A + (-B) when B "easily" negates. Move (x & y) | x -> x and friends before (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2). From-SVN: r225178 --- gcc/ChangeLog | 10 +++++++ gcc/fold-const.c | 34 ++++------------------ gcc/match.pd | 73 +++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a36140057e..6f919643f37 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-06-30 Richard Biener + + * fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x), + ~ (-A) to A - 1, ~ (A - 1) or ~ (A + -1) to -A and some cases of + ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify to ... + * match.pd: ... here. + Add a few cases of A - B -> A + (-B) when B "easily" negates. + Move (x & y) | x -> x and friends before + (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2). + 2015-06-30 Eric Botcazou * config/sparc/leon.md (leon_load): Enable for all LEON variants if diff --git a/gcc/fold-const.c b/gcc/fold-const.c index f330d78904a..67115d2377e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8125,9 +8125,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) TREE_TYPE (targ0), targ0)); } - /* ABS_EXPR> = ABS_EXPR even if flag_wrapv is on. */ - else if (TREE_CODE (arg0) == ABS_EXPR) - return arg0; /* Strip sign ops from argument. */ if (TREE_CODE (type) == REAL_TYPE) @@ -8155,33 +8152,14 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) return NULL_TREE; case BIT_NOT_EXPR: - /* Convert ~ (-A) to A - 1. */ - if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) - return fold_build2_loc (loc, MINUS_EXPR, type, - fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)), - build_int_cst (type, 1)); - /* Convert ~ (A - 1) or ~ (A + -1) to -A. */ - else if (INTEGRAL_TYPE_P (type) - && ((TREE_CODE (arg0) == MINUS_EXPR - && integer_onep (TREE_OPERAND (arg0, 1))) - || (TREE_CODE (arg0) == PLUS_EXPR - && integer_all_onesp (TREE_OPERAND (arg0, 1))))) - { - /* Perform the negation in ARG0's type and only then convert - to TYPE as to avoid introducing undefined behavior. */ - tree t = fold_build1_loc (loc, NEGATE_EXPR, - TREE_TYPE (TREE_OPERAND (arg0, 0)), - TREE_OPERAND (arg0, 0)); - return fold_convert_loc (loc, type, t); - } /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */ - else if (TREE_CODE (arg0) == BIT_XOR_EXPR - && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type, - fold_convert_loc (loc, type, - TREE_OPERAND (arg0, 0))))) + if (TREE_CODE (arg0) == BIT_XOR_EXPR + && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type, + fold_convert_loc (loc, type, + TREE_OPERAND (arg0, 0))))) return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem, - fold_convert_loc (loc, type, - TREE_OPERAND (arg0, 1))); + fold_convert_loc (loc, type, + TREE_OPERAND (arg0, 1))); else if (TREE_CODE (arg0) == BIT_XOR_EXPR && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type, fold_convert_loc (loc, type, diff --git a/gcc/match.pd b/gcc/match.pd index 5dcbc1a47e0..d81ea53dae4 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -389,6 +389,9 @@ along with GCC; see the file COPYING3. If not see (bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0))) (bit_and @0 @1)) +(simplify + (abs (abs@1 @0)) + @1) (simplify (abs (negate @0)) (abs @0)) @@ -396,6 +399,24 @@ along with GCC; see the file COPYING3. If not see (abs tree_expr_nonnegative_p@0) @0) +/* A - B -> A + (-B) if B is easily negatable. This just covers + very few cases of "easily negatable", effectively inlining negate_expr_p. */ +(simplify + (minus @0 INTEGER_CST@1) + (if ((INTEGRAL_TYPE_P (type) + && TYPE_OVERFLOW_WRAPS (type)) + || (!TYPE_OVERFLOW_SANITIZED (type) + && may_negate_without_overflow_p (@1))) + (plus @0 (negate @1)))) +(simplify + (minus @0 REAL_CST@1) + (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1))) + (plus @0 (negate @1)))) +(simplify + (minus @0 VECTOR_CST@1) + (if (FLOAT_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type)) + (plus @0 (negate @1)))) + /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST)) when profitable. @@ -427,6 +448,19 @@ along with GCC; see the file COPYING3. If not see || TYPE_PRECISION (type) != GET_MODE_PRECISION (TYPE_MODE (type)))) (convert (bitop @0 (convert @1)))))) +(for bitop (bit_and bit_ior) + rbitop (bit_ior bit_and) + /* (x | y) & x -> x */ + /* (x & y) | x -> x */ + (simplify + (bitop:c (rbitop:c @0 @1) @0) + @0) + /* (~x | y) & x -> x & y */ + /* (~x & y) | x -> x | y */ + (simplify + (bitop:c (rbitop:c (bit_not @0) @1) @0) + (bitop @0 @1))) + /* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */ (for bitop (bit_and bit_ior bit_xor) (simplify @@ -474,19 +508,6 @@ along with GCC; see the file COPYING3. If not see (op:c truth_valued_p@0 (logical_inverted_value @0)) { constant_boolean_node (true, type); })) -(for bitop (bit_and bit_ior) - rbitop (bit_ior bit_and) - /* (x | y) & x -> x */ - /* (x & y) | x -> x */ - (simplify - (bitop:c (rbitop:c @0 @1) @0) - @0) - /* (~x | y) & x -> x & y */ - /* (~x & y) | x -> x | y */ - (simplify - (bitop:c (rbitop:c (bit_not @0) @1) @0) - (bitop @0 @1))) - /* If arg1 and arg2 are booleans (or any single bit type) then try to simplify: @@ -515,6 +536,32 @@ along with GCC; see the file COPYING3. If not see (bit_not (bit_not @0)) @0) +/* Convert ~ (-A) to A - 1. */ +(simplify + (bit_not (convert? (negate @0))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (convert (minus @0 { build_one_cst (TREE_TYPE (@0)); })))) + +/* Convert ~ (A - 1) or ~ (A + -1) to -A. */ +(simplify + (bit_not (convert? (minus @0 integer_onep))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (convert (negate @0)))) +(simplify + (bit_not (convert? (plus @0 integer_all_onesp))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (convert (negate @0)))) + +/* Part of convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */ +(simplify + (bit_not (convert? (bit_xor @0 INTEGER_CST@1))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (convert (bit_xor @0 (bit_not @1))))) +(simplify + (bit_not (convert? (bit_xor:c (bit_not @0) @1))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (convert (bit_xor @0 @1)))) + /* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */ (simplify (bit_ior:c (bit_and:c@3 @0 (bit_not @2)) (bit_and:c@4 @1 @2)) -- 2.30.2