[range-op] Take known set bits into account in popcount [PR107053]
This patch teaches popcount about known set bits which are now available in the irange. PR tree-optimization/107053 gcc/ChangeLog: * gimple-range-op.cc (cfn_popcount): Use known set bits. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107053.c: New test.
This commit is contained in:
parent
d6384ad1a9
commit
137fb7077f
2 changed files with 20 additions and 4 deletions
|
@ -880,17 +880,20 @@ public:
|
|||
if (lh.undefined_p ())
|
||||
return false;
|
||||
unsigned prec = TYPE_PRECISION (type);
|
||||
wide_int nz = lh.get_nonzero_bits ();
|
||||
wide_int pop = wi::shwi (wi::popcount (nz), prec);
|
||||
irange_bitmask bm = lh.get_bitmask ();
|
||||
wide_int nz = bm.get_nonzero_bits ();
|
||||
wide_int high = wi::shwi (wi::popcount (nz), prec);
|
||||
// Calculating the popcount of a singleton is trivial.
|
||||
if (lh.singleton_p ())
|
||||
{
|
||||
r.set (type, pop, pop);
|
||||
r.set (type, high, high);
|
||||
return true;
|
||||
}
|
||||
if (cfn_ffs::fold_range (r, type, lh, rh, rel))
|
||||
{
|
||||
int_range<2> tmp (type, wi::zero (prec), pop);
|
||||
wide_int known_ones = ~bm.mask () & bm.value ();
|
||||
wide_int low = wi::shwi (wi::popcount (known_ones), prec);
|
||||
int_range<2> tmp (type, low, high);
|
||||
r.intersect (tmp);
|
||||
return true;
|
||||
}
|
||||
|
|
13
gcc/testsuite/gcc.dg/tree-ssa/pr107053.c
Normal file
13
gcc/testsuite/gcc.dg/tree-ssa/pr107053.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options "-O2 -fdump-tree-evrp" }
|
||||
|
||||
void link_failure();
|
||||
void f(int a)
|
||||
{
|
||||
a |= 0x300;
|
||||
int b = __builtin_popcount(a);
|
||||
if (b < 2)
|
||||
link_failure();
|
||||
}
|
||||
|
||||
// { dg-final { scan-tree-dump-not "link_failure" "evrp" } }
|
Loading…
Add table
Reference in a new issue