https://gcc.gnu.org/g:b02503d3fe79778ccc149b0abbc736f7972603da

commit r15-4607-gb02503d3fe79778ccc149b0abbc736f7972603da
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Thu Oct 24 14:22:34 2024 +0100

    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.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_6.c | 75 +++++++++++++++++++++++
 gcc/value-query.cc                                |  7 +++
 2 files changed, 82 insertions(+)

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 000000000000..9d9e1ca93303
--- /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 cac2cb5b2bc0..34499da1a987 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))

Reply via email to