fold-const.c (fold_binary_loc): Move X % -Y -> X % Y and X % C -> X & (C - 1) for...
authorRichard Biener <rguenther@suse.de>
Tue, 26 May 2015 12:00:48 +0000 (12:00 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 26 May 2015 12:00:48 +0000 (12:00 +0000)
2015-05-26  Richard Biener  <rguenther@suse.de>

* fold-const.c (fold_binary_loc): Move X % -Y -> X % Y and
X % C -> X & (C - 1) for C being a power-of two to ...
* match.pd: ... patterns.

From-SVN: r223690

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

index 3197dfcfe47cd70d6b35c414654bc72b748bf278..8fc8fbe3ccee5eff686b7ac910f2944ec1e963f9 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-26  Richard Biener  <rguenther@suse.de>
+
+       * fold-const.c (fold_binary_loc): Move X % -Y -> X % Y and
+       X % C -> X & (C - 1) for C being a power-of two to ...
+       * match.pd: ... patterns.
+
 2015-05-26  Marc Glisse  <marc.glisse@inria.fr>
 
        * match.pd (swapped_tcc_comparison): New operator list.
index 5545ecf3b97bdb27632c1692c60a450982884c24..55196b54c6ba88d836e6e7d2f5e79d5d65ccc275 100644 (file)
@@ -11941,15 +11941,6 @@ fold_binary_loc (location_t loc,
     case FLOOR_MOD_EXPR:
     case ROUND_MOD_EXPR:
     case TRUNC_MOD_EXPR:
-      /* X % -Y is the same as X % Y.  */
-      if (code == TRUNC_MOD_EXPR
-         && !TYPE_UNSIGNED (type)
-         && TREE_CODE (arg1) == NEGATE_EXPR
-         && !TYPE_OVERFLOW_TRAPS (type))
-       return fold_build2_loc (loc, code, type, fold_convert_loc (loc, type, arg0),
-                           fold_convert_loc (loc, type,
-                                             TREE_OPERAND (arg1, 0)));
-
       strict_overflow_p = false;
       if (TREE_CODE (arg1) == INTEGER_CST
          && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
@@ -11962,34 +11953,6 @@ fold_binary_loc (location_t loc,
          return fold_convert_loc (loc, type, tem);
        }
 
-      /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
-         i.e. "X % C" into "X & (C - 1)", if X and C are positive.  */
-      if ((code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR)
-         && (TYPE_UNSIGNED (type)
-             || tree_expr_nonnegative_warnv_p (op0, &strict_overflow_p)))
-       {
-         tree c = arg1;
-         /* Also optimize A % (C << N)  where C is a power of 2,
-            to A & ((C << N) - 1).  */
-         if (TREE_CODE (arg1) == LSHIFT_EXPR)
-           c = TREE_OPERAND (arg1, 0);
-
-         if (integer_pow2p (c) && tree_int_cst_sgn (c) > 0)
-           {
-             tree mask
-               = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (arg1), arg1,
-                                  build_int_cst (TREE_TYPE (arg1), 1));
-             if (strict_overflow_p)
-               fold_overflow_warning (("assuming signed overflow does not "
-                                       "occur when simplifying "
-                                       "X % (power of two)"),
-                                      WARN_STRICT_OVERFLOW_MISC);
-             return fold_build2_loc (loc, BIT_AND_EXPR, type,
-                                     fold_convert_loc (loc, type, arg0),
-                                     fold_convert_loc (loc, type, mask));
-           }
-       }
-
       return NULL_TREE;
 
     case LROTATE_EXPR:
index 1e46677d5255371a0daee8f38c0c4c5704e61aae..abd785178fc0f7795284559e4b6a8d5f4607adc6 100644 (file)
@@ -230,6 +230,30 @@ along with GCC; see the file COPYING3.  If not see
        && !sign_bit_p (@1, @1))
    (trunc_mod @0 (negate @1))))
 
+/* X % -Y is the same as X % Y.  */
+(simplify
+ (trunc_mod @0 (convert? (negate @1)))
+ (if (!TYPE_UNSIGNED (type)
+      && !TYPE_OVERFLOW_TRAPS (type)
+      && tree_nop_conversion_p (type, TREE_TYPE (@1)))
+  (trunc_mod @0 (convert @1))))
+
+/* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
+   i.e. "X % C" into "X & (C - 1)", if X and C are positive.
+   Also optimize A % (C << N)  where C is a power of 2,
+   to A & ((C << N) - 1).  */
+(match (power_of_two_cand @1)
+ INTEGER_CST@1)
+(match (power_of_two_cand @1)
+ (lshift INTEGER_CST@1 @2))
+(for mod (trunc_mod floor_mod)
+ (simplify
+  (mod @0 (power_of_two_cand@1 @2))
+  (if ((TYPE_UNSIGNED (type)
+       || tree_expr_nonnegative_p (@0))
+       && integer_pow2p (@2) && tree_int_cst_sgn (@2) > 0)
+   (bit_and @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); })))))
+
 /* X % Y is smaller than Y.  */
 (for cmp (lt ge)
  (simplify