match.pd has a rule to simplify an extension, operation and truncation
back to the original type:

 (simplify
   (convert (op:s@0 (convert1?@3 @1) (convert2?@4 @2)))

Currently it handles cases in which @2 is an INTEGER_CST, but it
also works for POLY_INT_CSTs.[*]

For INTEGER_CST it doesn't matter whether we test @2 or @4,
but for POLY_INT_CST it is possible to have unfolded (convert …)s.

Originally I saw this leading to some bad ivopts decisions, because
we weren't folding away redundancies from candidate iv expressions.
It's also possible to test the fold directly using the SVE ACLE.

Tested on aarch64-linux-gnu and x86_64-linux-gnu, pushed as obvious.

Richard

[*] Not all INTEGER_CST rules work for POLY_INT_CSTs, since extensions
    don't necessarily distribute over the internals of the POLY_INT_CST.
    But in this case that isn't an issue.


gcc/
        * match.pd: Simplify an extend-operate-truncate sequence involving
        a POLY_INT_CST.

gcc/testsuite/
        * gcc.target/aarch64/sve/acle/general/cntb_1.c: New test.
---
 gcc/match.pd                                       |  2 +-
 .../gcc.target/aarch64/sve/acle/general/cntb_1.c   | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 334e8cc0496..30680d488ab 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6175,7 +6175,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && (types_match (@1, @2)
            /* Or the second operand is const integer or converted const
               integer from valueize.  */
-           || TREE_CODE (@2) == INTEGER_CST))
+           || poly_int_tree_p (@4)))
      (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
        (op @1 (convert @2))
        (with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
new file mode 100644
index 00000000000..b43fcf0ed6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
@@ -0,0 +1,14 @@
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <arm_sve.h>
+
+unsigned int
+foo (unsigned int x)
+{
+  unsigned long tmp = x;
+  tmp += svcntb ();
+  x = tmp;
+  return x - svcntb ();
+}
+
+/* { dg-final { scan-tree-dump-not { POLY_INT_CST } optimized } } */
-- 
2.17.1

Reply via email to