diff --git a/gcc/match.pd b/gcc/match.pd index 17613ec8ade4f8142b36472c6ad52e430da37639..391c60bdfb32b6b75e7dd41a739f4762d69caf0c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2872,6 +2872,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) possibly set. */ (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))))) 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 0000000000000000000000000000000000000000..b7a53701993cb01266b06e1a7cca9c64efa282b1 --- /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 4f83fcbb51714d8a37102925c85179bba7fa6275..ae6a0cd48fe66d221b6fe543dc6b8caa3836568a 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));