aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-05-26 12:00:48 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-05-26 12:00:48 +0000
commit8f0c696a7b5079c5deea4b4301b16b41145e7986 (patch)
tree93308095f66ea23ff7e2686d0c3d93c9eb180d0c
parent534bd33b61d08e0bf4d58efbeb3da5a368f8a247 (diff)
downloadgcc-8f0c696a7b5079c5deea4b4301b16b41145e7986.zip
gcc-8f0c696a7b5079c5deea4b4301b16b41145e7986.tar.gz
gcc-8f0c696a7b5079c5deea4b4301b16b41145e7986.tar.bz2
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 ...
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c37
-rw-r--r--gcc/match.pd24
3 files changed, 30 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3197dfc..8fc8fbe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 5545ecf..55196b5 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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:
diff --git a/gcc/match.pd b/gcc/match.pd
index 1e46677..abd7851 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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