recognize implied ranges for modulo.
implement op1_range for modulo with implied positive and negative ranges. gcc/ PR tree-optimization/91029 * range-op.cc (operator_trunc_mod::op1_range): New. gcc/testsuite/ * gcc.dg/pr91029.c: New.
This commit is contained in:
parent
0c1db9fa47
commit
1e27e7a582
2 changed files with 75 additions and 0 deletions
|
@ -2634,6 +2634,9 @@ public:
|
|||
const wide_int &lh_ub,
|
||||
const wide_int &rh_lb,
|
||||
const wide_int &rh_ub) const;
|
||||
virtual bool op1_range (irange &r, tree type,
|
||||
const irange &lhs,
|
||||
const irange &op2) const;
|
||||
} op_trunc_mod;
|
||||
|
||||
void
|
||||
|
@ -2680,6 +2683,31 @@ operator_trunc_mod::wi_fold (irange &r, tree type,
|
|||
value_range_with_overflow (r, type, new_lb, new_ub);
|
||||
}
|
||||
|
||||
bool
|
||||
operator_trunc_mod::op1_range (irange &r, tree type,
|
||||
const irange &lhs,
|
||||
const irange &op2) const
|
||||
{
|
||||
// PR 91029. Check for signed truncation with op2 >= 0.
|
||||
if (TYPE_SIGN (type) == SIGNED && wi::ge_p (op2.lower_bound (), 0, SIGNED))
|
||||
{
|
||||
unsigned prec = TYPE_PRECISION (type);
|
||||
// if a & b >=0 , then a >= 0.
|
||||
if (wi::ge_p (lhs.lower_bound (), 0, SIGNED))
|
||||
{
|
||||
r = value_range (type, wi::zero (prec), wi::max_value (prec, SIGNED));
|
||||
return true;
|
||||
}
|
||||
// if a & b < 0 , then a <= 0.
|
||||
if (wi::lt_p (lhs.upper_bound (), 0, SIGNED))
|
||||
{
|
||||
r = value_range (type, wi::min_value (prec, SIGNED), wi::zero (prec));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
class operator_logical_not : public range_operator
|
||||
{
|
||||
|
|
47
gcc/testsuite/gcc.dg/pr91029.c
Normal file
47
gcc/testsuite/gcc.dg/pr91029.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-evrp" } */
|
||||
|
||||
void kill (void);
|
||||
int xx;
|
||||
|
||||
void f1 (int i)
|
||||
{
|
||||
if ((i % 7) == 3)
|
||||
{
|
||||
xx = (i < 0);
|
||||
if (xx)
|
||||
kill ();
|
||||
}
|
||||
}
|
||||
|
||||
void f2 (int i)
|
||||
{
|
||||
if ((i % 7) >= 0)
|
||||
{
|
||||
xx = (i < 0);
|
||||
if (xx)
|
||||
kill ();
|
||||
}
|
||||
}
|
||||
|
||||
void f3 (int i)
|
||||
{
|
||||
if ((i % 7) == -3)
|
||||
{
|
||||
xx = (i > 0);
|
||||
if (xx)
|
||||
kill ();
|
||||
}
|
||||
}
|
||||
|
||||
void f4 (int i)
|
||||
{
|
||||
if ((i % 7) < 0)
|
||||
{
|
||||
xx = (i > 0);
|
||||
if (xx)
|
||||
kill ();
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
|
Loading…
Add table
Reference in a new issue