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.
--- /dev/null
+/* { 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;
+}
}
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))