diff options
author | Richard Biener <rguenther@suse.de> | 2015-05-26 12:00:48 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-05-26 12:00:48 +0000 |
commit | 8f0c696a7b5079c5deea4b4301b16b41145e7986 (patch) | |
tree | 93308095f66ea23ff7e2686d0c3d93c9eb180d0c | |
parent | 534bd33b61d08e0bf4d58efbeb3da5a368f8a247 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 37 | ||||
-rw-r--r-- | gcc/match.pd | 24 |
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 |