re PR tree-optimization/79408 (Missed VRP optimization of integer modulo)
PR tree-optimization/79408 * tree-vrp.c (simplify_div_or_mod_using_ranges): If op1 is not constant, but SSA_NAME with a known integer range, use the minimum of that range instead of op1 to determine if modulo can be replaced with its first operand. * gcc.dg/tree-ssa/pr79408.c: New test. From-SVN: r245273
This commit is contained in:
parent
01726bc977
commit
74a15d1424
|
@ -1,3 +1,11 @@
|
|||
2017-02-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/79408
|
||||
* tree-vrp.c (simplify_div_or_mod_using_ranges): If op1 is not
|
||||
constant, but SSA_NAME with a known integer range, use the minimum
|
||||
of that range instead of op1 to determine if modulo can be replaced
|
||||
with its first operand.
|
||||
|
||||
2016-02-08 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
* config/riscv/riscv.c (riscv_build_integer_1): Avoid use of INT16_MAX.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-02-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/79408
|
||||
* gcc.dg/tree-ssa/pr79408.c: New test.
|
||||
|
||||
2017-02-08 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/71824
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* PR tree-optimization/79408 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
|
||||
void link_error (void);
|
||||
|
||||
void
|
||||
foo (unsigned int x, unsigned int y)
|
||||
{
|
||||
if (x > 7312)
|
||||
return;
|
||||
if (y <= 7312)
|
||||
return;
|
||||
if (x % y != x)
|
||||
link_error ();
|
||||
}
|
||||
|
||||
void
|
||||
bar (int x, int y)
|
||||
{
|
||||
if (x > 7312 || x < 0)
|
||||
return;
|
||||
if (y <= 7312)
|
||||
return;
|
||||
if (x % y != x)
|
||||
link_error ();
|
||||
}
|
||||
|
||||
void
|
||||
baz (int x, int y)
|
||||
{
|
||||
if (x > 7312 || x < -7312)
|
||||
return;
|
||||
if (y <= 7312)
|
||||
return;
|
||||
if (x % y != x)
|
||||
link_error ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
|
|
@ -9226,12 +9226,12 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
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
|
||||
/* 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. For TRUNC_MOD_EXPR op0 % op1 with
|
||||
constant op1 (op1min = op1) or with op1 in [op1min, op1max] range,
|
||||
optimize it into just op0 if op0's range is known to be a subset of
|
||||
[-op1min + 1, op1min - 1] for signed and [0, op1min - 1] for unsigned
|
||||
modulo. */
|
||||
|
||||
static bool
|
||||
|
@ -9241,17 +9241,25 @@ simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
|
|||
tree val = NULL;
|
||||
tree op0 = gimple_assign_rhs1 (stmt);
|
||||
tree op1 = gimple_assign_rhs2 (stmt);
|
||||
tree op1min = op1;
|
||||
value_range *vr = get_value_range (op0);
|
||||
|
||||
if (rhs_code == TRUNC_MOD_EXPR
|
||||
&& TREE_CODE (op1) == INTEGER_CST
|
||||
&& tree_int_cst_sgn (op1) == 1
|
||||
&& TREE_CODE (op1) == SSA_NAME)
|
||||
{
|
||||
value_range *vr1 = get_value_range (op1);
|
||||
if (range_int_cst_p (vr1))
|
||||
op1min = vr1->min;
|
||||
}
|
||||
if (rhs_code == TRUNC_MOD_EXPR
|
||||
&& TREE_CODE (op1min) == INTEGER_CST
|
||||
&& tree_int_cst_sgn (op1min) == 1
|
||||
&& range_int_cst_p (vr)
|
||||
&& tree_int_cst_lt (vr->max, op1))
|
||||
&& tree_int_cst_lt (vr->max, op1min))
|
||||
{
|
||||
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),
|
||||
|| tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), op1min),
|
||||
vr->min))
|
||||
{
|
||||
/* If op0 already has the range op0 % op1 has,
|
||||
|
|
Loading…
Reference in New Issue