Record nonzero bits in the irange_bitmask of POLY_INT_CSTs

At the moment, ranger punts entirely on POLY_INT_CSTs.  Numerical
ranges are a bit difficult, unless we do start modelling bounds on
the indeterminates.  But we can at least track the nonzero bits.

gcc/
	* value-query.cc (range_query::get_tree_range): Use get_nonzero_bits
	to populate the irange_bitmask of a POLY_INT_CST.

gcc/testsuite/
	* gcc.target/aarch64/sve/cnt_fold_6.c: New test.
This commit is contained in:
Richard Sandiford 2024-10-24 14:22:34 +01:00
parent af19e46c88
commit b02503d3fe
2 changed files with 82 additions and 0 deletions

View File

@ -0,0 +1,75 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { check-function-bodies "**" "" } } */
#include <arm_sve.h>
/*
** f1:
** ...
** cntb (x[0-9]+)
** ...
** add x[0-9]+, \1, #?16
** ...
** csel [^\n]+
** ret
*/
uint64_t
f1 (int x)
{
uint64_t y = x ? svcnth () : svcnth () + 8;
y >>= 3;
y <<= 4;
return y;
}
/*
** f2:
** ...
** (?:and|[al]sr) [^\n]+
** ...
** ret
*/
uint64_t
f2 (int x)
{
uint64_t y = x ? svcnth () : svcnth () + 8;
y >>= 4;
y <<= 5;
return y;
}
/*
** f3:
** ...
** cntw (x[0-9]+)
** ...
** add x[0-9]+, \1, #?16
** ...
** csel [^\n]+
** ret
*/
uint64_t
f3 (int x)
{
uint64_t y = x ? svcntd () : svcntd () + 8;
y >>= 1;
y <<= 2;
return y;
}
/*
** f4:
** ...
** (?:and|[al]sr) [^\n]+
** ...
** ret
*/
uint64_t
f4 (int x)
{
uint64_t y = x ? svcntd () : svcntd () + 8;
y >>= 2;
y <<= 3;
return y;
}

View File

@ -375,6 +375,13 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt,
}
default:
if (POLY_INT_CST_P (expr))
{
unsigned int precision = TYPE_PRECISION (type);
r.set_varying (type);
r.update_bitmask ({ wi::zero (precision), get_nonzero_bits (expr) });
return true;
}
break;
}
if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))