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.
---
 .../gcc.target/aarch64/sve/cnt_fold_6.c       | 75 +++++++++++++++++++
 gcc/value-query.cc                            |  7 ++
 2 files changed, 82 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_6.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_6.c 
b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_6.c
new file mode 100644
index 00000000000..9d9e1ca9330
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_6.c
@@ -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;
+}
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index cac2cb5b2bc..34499da1a98 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -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))
-- 
2.25.1

Reply via email to