From: Marc Glisse Date: Thu, 25 May 2017 08:39:37 +0000 (+0200) Subject: Move "(A & C) == D is false when D & ~C != 0" to match.pd X-Git-Tag: upstream/12.2.0~39262 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=10bc8017a3028c291e7b85486bc66bfc12b5f377;p=platform%2Fupstream%2Fgcc.git Move "(A & C) == D is false when D & ~C != 0" to match.pd 2017-05-25 Marc Glisse * fold-const.c (fold_binary_loc) [(A & C) == D]: Remove transformation. * match.pd (X == C): Rewrite it here. (with_possible_nonzero_bits, with_possible_nonzero_bits2, with_certain_nonzero_bits2): New predicates. * tree-ssanames.c (get_nonzero_bits): Handle INTEGER_CST. From-SVN: r248447 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 014b136..5445bd5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-05-25 Marc Glisse + + * fold-const.c (fold_binary_loc) [(A & C) == D]: Remove transformation. + * match.pd (X == C): Rewrite it here. + (with_possible_nonzero_bits, with_possible_nonzero_bits2, + with_certain_nonzero_bits2): New predicates. + * tree-ssanames.c (get_nonzero_bits): Handle INTEGER_CST. + 2017-05-24 Nathan Sidwell * lto-streamer-in.c (lto_input_data_block): Adjust T const cast to diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 736552c..efc0b10 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10636,24 +10636,6 @@ fold_binary_loc (location_t loc, } } - /* If we have (A & C) == D where D & ~C != 0, convert this into 0. - Similarly for NE_EXPR. */ - if (TREE_CODE (arg0) == BIT_AND_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - { - tree notc = fold_build1_loc (loc, BIT_NOT_EXPR, - TREE_TYPE (TREE_OPERAND (arg0, 1)), - TREE_OPERAND (arg0, 1)); - tree dandnotc - = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), - fold_convert_loc (loc, TREE_TYPE (arg0), arg1), - notc); - tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; - if (integer_nonzerop (dandnotc)) - 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) diff --git a/gcc/match.pd b/gcc/match.pd index ba50149..618b2ec 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1097,6 +1097,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (TREE_INT_CST_LOW (@1) & 1) { constant_boolean_node (cmp == NE_EXPR, type); }))) +/* Arguments on which one can call get_nonzero_bits to get the bits + possibly set. */ +(match with_possible_nonzero_bits + INTEGER_CST@0) +(match with_possible_nonzero_bits + SSA_NAME@0 + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))))) +/* Slightly extended version, do not make it recursive to keep it cheap. */ +(match (with_possible_nonzero_bits2 @0) + with_possible_nonzero_bits@0) +(match (with_possible_nonzero_bits2 @0) + (bit_and:c with_possible_nonzero_bits@0 @2)) + +/* Same for bits that are known to be set, but we do not have + an equivalent to get_nonzero_bits yet. */ +(match (with_certain_nonzero_bits2 @0) + INTEGER_CST@0) +(match (with_certain_nonzero_bits2 @0) + (bit_ior @1 INTEGER_CST@0)) + +/* X == C (or X & Z == Y | C) is impossible if ~nonzero(X) & C != 0. */ +(for cmp (eq ne) + (simplify + (cmp:c (with_possible_nonzero_bits2 @0) (with_certain_nonzero_bits2 @1)) + (if ((~get_nonzero_bits (@0) & @1) != 0) + { constant_boolean_node (cmp == NE_EXPR, type); }))) + /* ((X inner_op C0) outer_op C1) With X being a tree where value_range has reasoned certain bits to always be zero throughout its computed value range, diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 353c7b1..e83dd46 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -427,11 +427,14 @@ set_nonzero_bits (tree name, const wide_int_ref &mask) } /* Return a widest_int with potentially non-zero bits in SSA_NAME - NAME, or -1 if unknown. */ + NAME, the constant for INTEGER_CST, or -1 if unknown. */ wide_int get_nonzero_bits (const_tree name) { + if (TREE_CODE (name) == INTEGER_CST) + return name; + unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); if (POINTER_TYPE_P (TREE_TYPE (name))) {