aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-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));