Move "(A & C) == D is false when D & ~C != 0" to match.pd
authorMarc Glisse <marc.glisse@inria.fr>
Thu, 25 May 2017 08:39:37 +0000 (10:39 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Thu, 25 May 2017 08:39:37 +0000 (08:39 +0000)
2017-05-25  Marc Glisse  <marc.glisse@inria.fr>

* 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

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd
gcc/tree-ssanames.c

index 014b136..5445bd5 100644 (file)
@@ -1,3 +1,11 @@
+2017-05-25  Marc Glisse  <marc.glisse@inria.fr>
+
+       * 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  <nathan@acm.org>
 
        * lto-streamer-in.c (lto_input_data_block): Adjust T const cast to
index 736552c..efc0b10 100644 (file)
@@ -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)
index ba50149..618b2ec 100644 (file)
@@ -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,
index 353c7b1..e83dd46 100644 (file)
@@ -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)))
     {