aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2024-10-24 14:22:33 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2024-10-24 14:22:33 +0100
commitd6c4badffafa295f6082b7d74de314e131f30a96 (patch)
tree0fd7eb32174e5c36bc140b60b04b9fc3d46e26cc
parentec8e8d359690e7347e6e718cc9254d59f694e138 (diff)
downloadgcc-d6c4badffafa295f6082b7d74de314e131f30a96.zip
gcc-d6c4badffafa295f6082b7d74de314e131f30a96.tar.gz
gcc-d6c4badffafa295f6082b7d74de314e131f30a96.tar.bz2
Handle POLY_INT_CSTs in get_nonzero_bits
This patch extends get_nonzero_bits to handle POLY_INT_CSTs, The easiest (but also most useful) case is that the number of trailing zeros in the runtime value is at least the number of trailing zeros in each individual component. In principle, we could do this for coeffs 1 and above only, and then OR in ceoff 0. This would give ~0x11 for [14, 32], say. But that's future work. gcc/ * tree-ssanames.cc (get_nonzero_bits): Handle POLY_INT_CSTs. * match.pd (with_possible_nonzero_bits): Likewise. gcc/testsuite/ * gcc.target/aarch64/sve/cnt_fold_4.c: New test.
-rw-r--r--gcc/match.pd2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_4.c61
-rw-r--r--gcc/tree-ssanames.cc3
3 files changed, 66 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 17613ec..391c60b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2873,6 +2873,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(match with_possible_nonzero_bits
INTEGER_CST@0)
(match with_possible_nonzero_bits
+ POLY_INT_CST@0)
+(match with_possible_nonzero_bits
SSA_NAME@0
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0)))))
/* Slightly extended version, do not make it recursive to keep it cheap. */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_4.c
new file mode 100644
index 0000000..b7a5370
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_4.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+/*
+** f1:
+** cnth x0
+** ret
+*/
+uint64_t
+f1 ()
+{
+ uint64_t x = svcntw ();
+ x >>= 2;
+ return x << 3;
+}
+
+/*
+** f2:
+** [^\n]+
+** [^\n]+
+** ...
+** ret
+*/
+uint64_t
+f2 ()
+{
+ uint64_t x = svcntd ();
+ x >>= 2;
+ return x << 3;
+}
+
+/*
+** f3:
+** cntb x0, all, mul #4
+** ret
+*/
+uint64_t
+f3 ()
+{
+ uint64_t x = svcntd ();
+ x >>= 1;
+ return x << 6;
+}
+
+/*
+** f4:
+** [^\n]+
+** [^\n]+
+** ...
+** ret
+*/
+uint64_t
+f4 ()
+{
+ uint64_t x = svcntd ();
+ x >>= 2;
+ return x << 2;
+}
diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc
index 4f83fcb..ae6a0cd 100644
--- a/gcc/tree-ssanames.cc
+++ b/gcc/tree-ssanames.cc
@@ -502,6 +502,9 @@ get_nonzero_bits (const_tree name)
if (TREE_CODE (name) == INTEGER_CST)
return wi::to_wide (name);
+ if (POLY_INT_CST_P (name))
+ return -known_alignment (wi::to_poly_wide (name));
+
/* Use element_precision instead of TYPE_PRECISION so complex and
vector types get a non-zero precision. */
unsigned int precision = element_precision (TREE_TYPE (name));