re PR tree-optimization/64454 (optimize (x%5)%5)
PR tree-optimization/64454 * tree-vrp.c (simplify_div_or_mod_using_ranges): Optimize op0 % op1 into op0 if op0 is in range [-op1 + 1, op1 - 1] for signed or [0, op1 - 1] for unsigned modulo. (simplify_stmt_using_ranges): Call simplify_div_or_mod_using_ranges even if op1 does not satisfy integer_pow2p. * gcc.dg/pr64454.c: New test. From-SVN: r219491
This commit is contained in:
parent
0199195344
commit
f51286f21f
|
@ -1,5 +1,12 @@
|
|||
2015-01-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/64454
|
||||
* tree-vrp.c (simplify_div_or_mod_using_ranges): Optimize
|
||||
op0 % op1 into op0 if op0 is in range [-op1 + 1, op1 - 1]
|
||||
for signed or [0, op1 - 1] for unsigned modulo.
|
||||
(simplify_stmt_using_ranges): Call simplify_div_or_mod_using_ranges
|
||||
even if op1 does not satisfy integer_pow2p.
|
||||
|
||||
PR other/64370
|
||||
* sreal.c (sreal::to_double): Use ldexp instead of scalbnl.
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
2015-01-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/64454
|
||||
* gcc.dg/pr64454.c: New test.
|
||||
|
||||
PR testsuite/64028
|
||||
* gcc.dg/vect/no-section-anchors-vect-31.c: Add dg-add-options
|
||||
bind_pic_locally.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* PR tree-optimization/64454 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-vrp1" } */
|
||||
|
||||
unsigned
|
||||
f1 (unsigned x)
|
||||
{
|
||||
return (x % 5) % 5;
|
||||
}
|
||||
|
||||
int
|
||||
f2 (int x)
|
||||
{
|
||||
return (x % 5) % 5;
|
||||
}
|
||||
|
||||
int
|
||||
f3 (int x)
|
||||
{
|
||||
return (x % -5) % -5;
|
||||
}
|
||||
|
||||
unsigned
|
||||
f4 (unsigned x)
|
||||
{
|
||||
return (x % 5) % 6;
|
||||
}
|
||||
|
||||
int
|
||||
f5 (int x)
|
||||
{
|
||||
return (x % 5) % 6;
|
||||
}
|
||||
|
||||
int
|
||||
f6 (int x)
|
||||
{
|
||||
return (x % -5) % -6;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "% 5" 6 "vrp1" } } */
|
||||
/* { dg-final { scan-tree-dump-times "% 6" 0 "vrp1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vrp1" } } */
|
|
@ -8998,7 +8998,11 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
|
|||
|
||||
/* Simplify a division or modulo operator to a right shift or
|
||||
bitwise and if the first operand is unsigned or is greater
|
||||
than zero and the second operand is an exact power of two. */
|
||||
than zero and the second operand is an exact power of two.
|
||||
For TRUNC_MOD_EXPR op0 % op1 with constant op1, optimize it
|
||||
into just op0 if op0's range is known to be a subset of
|
||||
[-op1 + 1, op1 - 1] for signed and [0, op1 - 1] for unsigned
|
||||
modulo. */
|
||||
|
||||
static bool
|
||||
simplify_div_or_mod_using_ranges (gimple stmt)
|
||||
|
@ -9007,7 +9011,30 @@ simplify_div_or_mod_using_ranges (gimple stmt)
|
|||
tree val = NULL;
|
||||
tree op0 = gimple_assign_rhs1 (stmt);
|
||||
tree op1 = gimple_assign_rhs2 (stmt);
|
||||
value_range_t *vr = get_value_range (gimple_assign_rhs1 (stmt));
|
||||
value_range_t *vr = get_value_range (op0);
|
||||
|
||||
if (rhs_code == TRUNC_MOD_EXPR
|
||||
&& TREE_CODE (op1) == INTEGER_CST
|
||||
&& tree_int_cst_sgn (op1) == 1
|
||||
&& range_int_cst_p (vr)
|
||||
&& tree_int_cst_lt (vr->max, op1))
|
||||
{
|
||||
if (TYPE_UNSIGNED (TREE_TYPE (op0))
|
||||
|| tree_int_cst_sgn (vr->min) >= 0
|
||||
|| tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1), op1),
|
||||
vr->min))
|
||||
{
|
||||
/* If op0 already has the range op0 % op1 has,
|
||||
then TRUNC_MOD_EXPR won't change anything. */
|
||||
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
|
||||
gimple_assign_set_rhs_from_tree (&gsi, op0);
|
||||
update_stmt (stmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!integer_pow2p (op1))
|
||||
return false;
|
||||
|
||||
if (TYPE_UNSIGNED (TREE_TYPE (op0)))
|
||||
{
|
||||
|
@ -9880,11 +9907,14 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
|
|||
|
||||
/* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
|
||||
and BIT_AND_EXPR respectively if the first operand is greater
|
||||
than zero and the second operand is an exact power of two. */
|
||||
than zero and the second operand is an exact power of two.
|
||||
Also optimize TRUNC_MOD_EXPR away if the second operand is
|
||||
constant and the first operand already has the right value
|
||||
range. */
|
||||
case TRUNC_DIV_EXPR:
|
||||
case TRUNC_MOD_EXPR:
|
||||
if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
|
||||
&& integer_pow2p (gimple_assign_rhs2 (stmt)))
|
||||
if (TREE_CODE (rhs1) == SSA_NAME
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
|
||||
return simplify_div_or_mod_using_ranges (stmt);
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue