[PR102546] X << Y being non-zero implies X is also non-zero.
This patch teaches this to range-ops. Tested on x86-64 Linux. gcc/ChangeLog: PR tree-optimization/102546 * range-op.cc (operator_lshift::op1_range): Teach range-ops that X << Y is non-zero implies X is also non-zero.
This commit is contained in:
parent
257d2890a7
commit
5f9ccf17de
2 changed files with 37 additions and 4 deletions
|
@ -2078,6 +2078,12 @@ operator_lshift::op1_range (irange &r,
|
|||
relation_kind rel ATTRIBUTE_UNUSED) const
|
||||
{
|
||||
tree shift_amount;
|
||||
|
||||
if (!lhs.contains_p (build_zero_cst (type)))
|
||||
r.set_nonzero (type);
|
||||
else
|
||||
r.set_varying (type);
|
||||
|
||||
if (op2.singleton_p (&shift_amount))
|
||||
{
|
||||
wide_int shift = wi::to_wide (shift_amount);
|
||||
|
@ -2089,21 +2095,24 @@ operator_lshift::op1_range (irange &r,
|
|||
return false;
|
||||
if (shift == 0)
|
||||
{
|
||||
r = lhs;
|
||||
r.intersect (lhs);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Work completely in unsigned mode to start.
|
||||
tree utype = type;
|
||||
int_range_max tmp_range;
|
||||
if (TYPE_SIGN (type) == SIGNED)
|
||||
{
|
||||
int_range_max tmp = lhs;
|
||||
utype = unsigned_type_for (type);
|
||||
range_cast (tmp, utype);
|
||||
op_rshift.fold_range (r, utype, tmp, op2);
|
||||
op_rshift.fold_range (tmp_range, utype, tmp, op2);
|
||||
}
|
||||
else
|
||||
op_rshift.fold_range (r, utype, lhs, op2);
|
||||
op_rshift.fold_range (tmp_range, utype, lhs, op2);
|
||||
|
||||
r.intersect (tmp_range);
|
||||
|
||||
// Start with ranges which can produce the LHS by right shifting the
|
||||
// result by the shift amount.
|
||||
|
@ -2128,7 +2137,8 @@ operator_lshift::op1_range (irange &r,
|
|||
range_cast (r, type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return !r.varying_p ();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
23
gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
Normal file
23
gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options "-O3 -fdump-tree-optimized" }
|
||||
|
||||
static int a;
|
||||
static char b, c, d;
|
||||
void bar(void);
|
||||
void foo(void);
|
||||
|
||||
int main() {
|
||||
int f = 0;
|
||||
for (; f <= 5; f++) {
|
||||
bar();
|
||||
b = b && f;
|
||||
d = f << f;
|
||||
if (!(a >= d || f))
|
||||
foo();
|
||||
c = 1;
|
||||
for (; c; c = 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// { dg-final { scan-tree-dump-not "foo" "optimized" } }
|
Loading…
Add table
Reference in a new issue