mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-15 22:51:38 +08:00
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
This commit is contained in:
parent
534bd33b61
commit
8f0c696a7b
@ -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.
|
||||
|
@ -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:
|
||||
|
24
gcc/match.pd
24
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user