This moves a few more patterns that show up during bootstrap.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2015-07-07  Richard Biener  <rguent...@suse.de>

        * fold-const.c (fold_binary_loc): Move
        (X & C2) << C1 -> (X << C1) & (C2 << C1) simplification ...
        * match.pd: ... here.
        Add (X * C1) % C2 -> 0 simplification pattern derived from
        extract_muldiv_1.

        * gcc.dg/vect/vect-over-widen-3-big-array.c: Adjust.

Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (revision 225504)
+++ gcc/match.pd        (working copy)
@@ -230,7 +230,14 @@ (define_operator_list CBRT BUILT_IN_CBRT
  /* (X % Y) % Y is just X % Y.  */
  (simplify
   (mod (mod@2 @0 @1) @1)
-  @2))
+  @2)
+ /* From extract_muldiv_1: (X * C1) % C2 is zero if C1 is a multiple of C2.  */
+ (simplify
+  (mod (mult @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (ANY_INTEGRAL_TYPE_P (type)
+       && TYPE_OVERFLOW_UNDEFINED (type)
+       && wi::multiple_of_p (@1, @2, TYPE_SIGN (type)))
+   { build_zero_cst (type); })))
 
 /* X % -C is the same as X % C.  */
 (simplify
@@ -992,6 +999,16 @@ (define_operator_list CBRT BUILT_IN_CBRT
           (if (shift_type == TREE_TYPE (@3))
            (bit_and @4 { newmaskt; }))))))))))))
 
+/* Fold (X & C2) << C1 into (X << C1) & (C2 << C1)
+   (X & C2) >> C1 into (X >> C1) & (C2 >> C1).  */
+(for shift (lshift rshift)
+ (simplify
+  (shift (convert? (bit_and @0 INTEGER_CST@2)) INTEGER_CST@1)
+  (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (with { tree mask = int_const_binop (shift, fold_convert (type, @2), @1); }
+    (bit_and (shift (convert @0) @1) { mask; })))))
+
+
 /* Simplifications of conversions.  */
 
 /* Basic strip-useless-type-conversions / strip_nops.  */
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 225504)
+++ gcc/fold-const.c    (working copy)
@@ -11194,27 +11140,6 @@ fold_binary_loc (location_t loc,
                             prec) == 0)
        return TREE_OPERAND (arg0, 0);
 
-      /* Fold (X & C2) << C1 into (X << C1) & (C2 << C1)
-             (X & C2) >> C1 into (X >> C1) & (C2 >> C1)
-        if the latter can be further optimized.  */
-      if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR)
-         && TREE_CODE (arg0) == BIT_AND_EXPR
-         && TREE_CODE (arg1) == INTEGER_CST
-         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-       {
-         tree mask = fold_build2_loc (loc, code, type,
-                                  fold_convert_loc (loc, type,
-                                                    TREE_OPERAND (arg0, 1)),
-                                  arg1);
-         tree shift = fold_build2_loc (loc, code, type,
-                                   fold_convert_loc (loc, type,
-                                                     TREE_OPERAND (arg0, 0)),
-                                   arg1);
-         tem = fold_binary_loc (loc, BIT_AND_EXPR, type, shift, mask);
-         if (tem)
-           return tem;
-       }
-
       return NULL_TREE;
 
     case MIN_EXPR:
Index: gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c
===================================================================
--- gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c     (revision 
225504)
+++ gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c     (working copy)
@@ -58,6 +58,6 @@ int main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "vect_recog_over_widening_pattern: 
detected" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vect_recog_over_widening_pattern: 
detected" 2 "vect" } } */
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
 

Reply via email to