From 66e1cacf608045c09f7c1e4be9940caefeccd473 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 26 Jun 2015 10:59:27 +0000 Subject: [PATCH] fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B and -A CMP CST -> A CMP -CST which is redundant... 2015-06-26 Richard Biener * fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B and -A CMP CST -> A CMP -CST which is redundant with a pattern in match.pd. Move (A | C) == D where C & ~D != 0 -> 0, (X ^ Y) ==/!= 0 -> X ==/!= Y, (X ^ Y) ==/!= {Y,X} -> {X,Y} ==/!= 0 and (X ^ C1) op C2 -> X op (C1 ^ C2) to ... * match.pd: ... patterns here. * gcc.dg/tree-ssa/forwprop-25.c: Adjust. From-SVN: r225007 --- gcc/ChangeLog | 10 ++++ gcc/fold-const.c | 59 --------------------- gcc/match.pd | 29 ++++++++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c | 7 +-- 5 files changed, 45 insertions(+), 64 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f47ea92978f..4398ee744f5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-06-26 Richard Biener + + * fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B + and -A CMP CST -> A CMP -CST which is redundant with a pattern + in match.pd. + Move (A | C) == D where C & ~D != 0 -> 0, (X ^ Y) ==/!= 0 -> X ==/!= Y, + (X ^ Y) ==/!= {Y,X} -> {X,Y} ==/!= 0 and + (X ^ C1) op C2 -> X op (C1 ^ C2) to ... + * match.pd: ... patterns here. + 2015-06-26 Marek Polacek * match.pd ((x | y) & ~(x & y) -> x ^ y, diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8fa32c62f65..6f12dd04c6e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -12163,15 +12163,6 @@ fold_binary_loc (location_t loc, type); } - /* Similarly for a NEGATE_EXPR. */ - if (TREE_CODE (arg0) == NEGATE_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && 0 != (tem = negate_expr (fold_convert_loc (loc, TREE_TYPE (arg0), - arg1))) - && TREE_CODE (tem) == INTEGER_CST - && !TREE_OVERFLOW (tem)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem); - /* Similarly for a BIT_XOR_EXPR; X ^ C1 == C2 is X == (C1 ^ C2). */ if (TREE_CODE (arg0) == BIT_XOR_EXPR && TREE_CODE (arg1) == INTEGER_CST @@ -12356,22 +12347,6 @@ fold_binary_loc (location_t loc, return omit_one_operand_loc (loc, type, rslt, arg0); } - /* If we have (A | C) == D where C & ~D != 0, convert this into 0. - Similarly for NE_EXPR. */ - if (TREE_CODE (arg0) == BIT_IOR_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - { - tree notd = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1), arg1); - tree candnotd - = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), - TREE_OPERAND (arg0, 1), - fold_convert_loc (loc, TREE_TYPE (arg0), notd)); - tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; - if (integer_nonzerop (candnotd)) - return omit_one_operand_loc (loc, type, rslt, arg0); - } - /* If this is a comparison of a field, we may be able to simplify it. */ if ((TREE_CODE (arg0) == COMPONENT_REF || TREE_CODE (arg0) == BIT_FIELD_REF) @@ -12429,32 +12404,6 @@ fold_binary_loc (location_t loc, } } - /* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y. */ - if (integer_zerop (arg1) - && TREE_CODE (arg0) == BIT_XOR_EXPR) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - TREE_OPERAND (arg0, 1)); - - /* (X ^ Y) == Y becomes X == 0. We know that Y has no side-effects. */ - if (TREE_CODE (arg0) == BIT_XOR_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - build_zero_cst (TREE_TYPE (arg0))); - /* Likewise (X ^ Y) == X becomes Y == 0. X has no side-effects. */ - if (TREE_CODE (arg0) == BIT_XOR_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) - && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 1), - build_zero_cst (TREE_TYPE (arg0))); - - /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ - if (TREE_CODE (arg0) == BIT_XOR_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - fold_build2_loc (loc, BIT_XOR_EXPR, TREE_TYPE (arg1), - TREE_OPERAND (arg0, 1), arg1)); - /* Fold (~X & C) == 0 into (X & C) != 0 and (~X & C) != 0 into (X & C) == 0 when C is a single bit. */ if (TREE_CODE (arg0) == BIT_AND_EXPR @@ -12508,14 +12457,6 @@ fold_binary_loc (location_t loc, return omit_one_operand_loc (loc, type, res, arg0); } - /* Fold -X op -Y as X op Y, where op is eq/ne. */ - if (TREE_CODE (arg0) == NEGATE_EXPR - && TREE_CODE (arg1) == NEGATE_EXPR) - return fold_build2_loc (loc, code, type, - TREE_OPERAND (arg0, 0), - fold_convert_loc (loc, TREE_TYPE (arg0), - TREE_OPERAND (arg1, 0))); - /* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries. */ if (TREE_CODE (arg0) == BIT_AND_EXPR && TREE_CODE (arg1) == BIT_AND_EXPR) diff --git a/gcc/match.pd b/gcc/match.pd index 91dfddb9645..b2f8429c120 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1209,6 +1209,35 @@ along with GCC; see the file COPYING3. If not see (if (tem && !TREE_OVERFLOW (tem)) (scmp @0 { tem; })))))) + +/* Equality compare simplifications from fold_binary */ +(for cmp (eq ne) + + /* If we have (A | C) == D where C & ~D != 0, convert this into 0. + Similarly for NE_EXPR. */ + (simplify + (cmp (convert?@3 (bit_ior @0 INTEGER_CST@1)) INTEGER_CST@2) + (if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0)) + && wi::bit_and_not (@1, @2) != 0) + { constant_boolean_node (cmp == NE_EXPR, type); })) + + /* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y. */ + (simplify + (cmp (bit_xor @0 @1) integer_zerop) + (cmp @0 @1)) + + /* (X ^ Y) == Y becomes X == 0. + Likewise (X ^ Y) == X becomes Y == 0. */ + (simplify + (cmp (bit_xor:c @0 @1) @0) + (cmp @1 { build_zero_cst (TREE_TYPE (@1)); })) + + /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ + (simplify + (cmp (convert?@3 (bit_xor @0 INTEGER_CST@1)) INTEGER_CST@2) + (if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0))) + (cmp @0 (bit_xor @1 (convert @2)))))) + /* Simplification of math builtins. */ (define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ddf2a9fa8e6..55fa18f1dc4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-06-26 Richard Biener + + * gcc.dg/tree-ssa/forwprop-25.c: Adjust. + 2015-06-26 Marek Polacek * gcc.dg/fold-and-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c index 888a7ed09d2..2670a50b6a5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-forwprop1" } */ +/* { dg-options "-O1 -fdump-tree-cddce1" } */ struct rtx_def; typedef struct rtx_def *rtx; @@ -37,7 +37,4 @@ convert_move (rtx to, rtx from, int unsignedp) 0 : 0)); } -/* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} } */ - - - +/* { dg-final { scan-tree-dump-not " ^ " "cddce1"} } */