[gcc r17-3519] AArch64: Add POLY_INT_CST bounds for SVE.

Tamar Christina via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:a3fb4bf350d6b7bea7aa04efcf9c584e6a9d93df

commit r17-3519-ga3fb4bf350d6b7bea7aa04efcf9c584e6a9d93df
Author: Tamar Christina <[email protected]>
Date:   Fri Aug 21 16:12:26 2026 +0100

    AArch64: Add POLY_INT_CST bounds for SVE.
    
    This patch implements POLY_INT indeterminate bounds for AArch64.
    
    With this patch
    
    #include <arm_sve.h>
    
    int g (void)
    {
      unsigned int vl = svcntb ();
      return vl < 257;
    }
    
    int h (void)
    {
      return svcntw () <= 64;
    }
    
    gets folded away to
    
    g():
            mov     w0, #1
            ret
    
    h():
            mov     w0, #1
            ret
    
    which is right because both are always true for any SVE vector length.
    
    Instead of the previous:
    
    g():
            cntb    x0
            cmp     w0, 257
            cset    w0, cc
            ret
    h():
            cntw    x0
            cmp     x0, 65
            cset    w0, cc
            ret
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64.cc (aarch64_poly_int_indeterminate_bound): New.
            (TARGET_POLY_INT_INDETERMINATE_BOUND): Implement hook using it.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/sve/slp_12.c: Update testcases
            * gcc.target/aarch64/sve/cnt_fold_7.c: New test.
            * gcc.target/aarch64/sve/cnt_fold_7_run.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64.cc                      |  11 ++
 gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c  | 154 +++++++++++++++++++++
 .../gcc.target/aarch64/sve/cnt_fold_7_run.c        |  47 +++++++
 gcc/testsuite/gcc.target/aarch64/sve/slp_12.c      |  14 +-
 4 files changed, 218 insertions(+), 8 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 4671a47d3950..8e62ab6a72e0 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31328,6 +31328,14 @@ aarch64_estimated_poly_value (poly_int64 val,
   return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
 }
 
+/* Implement TARGET_POLY_INT_INDETERMINATE_BOUND.  */
+
+static poly_uint64
+aarch64_poly_int_indeterminate_bound ()
+{
+  return poly_uint64 (0, 15);
+}
+
 
 /* Return true for types that could be supported as SIMD return or
    argument types.  */
@@ -34650,6 +34658,9 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ESTIMATED_POLY_VALUE
 #define TARGET_ESTIMATED_POLY_VALUE aarch64_estimated_poly_value
 
+#undef TARGET_POLY_INT_INDETERMINATE_BOUND
+#define TARGET_POLY_INT_INDETERMINATE_BOUND aarch64_poly_int_indeterminate_bound
+
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c
new file mode 100644
index 000000000000..d64933527da7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c
@@ -0,0 +1,154 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+/*
+** b_lt_257:
+**	mov	w0, 1
+**	ret
+*/
+int
+b_lt_257 (void)
+{
+  unsigned int vl = svcntb ();
+
+  return vl < 257;
+}
+
+/*
+** h_ge_8:
+**	mov	w0, 1
+**	ret
+*/
+int
+h_ge_8 (void)
+{
+  return svcnth () >= 8;
+}
+
+/*
+** w_le_64:
+**	mov	w0, 1
+**	ret
+*/
+int
+w_le_64 (void)
+{
+  return svcntw () <= 64;
+}
+
+/*
+** d_gt_1:
+**	mov	w0, 1
+**	ret
+*/
+int
+d_gt_1 (void)
+{
+  return svcntd () > 1;
+}
+
+/*
+** b_ne_0:
+**	mov	w0, 1
+**	ret
+*/
+int
+b_ne_0 (void)
+{
+  return svcntb () != 0;
+}
+
+/*
+** b_le_15:
+**	mov	w0, 0
+**	ret
+*/
+int
+b_le_15 (void)
+{
+  return svcntb () <= 15;
+}
+
+/*
+** h_lt_8:
+**	mov	w0, 0
+**	ret
+*/
+int
+h_lt_8 (void)
+{
+  return svcnth () < 8;
+}
+
+/*
+** w_gt_64:
+**	mov	w0, 0
+**	ret
+*/
+int
+w_gt_64 (void)
+{
+  return svcntw () > 64;
+}
+
+/*
+** d_eq_0:
+**	mov	w0, 0
+**	ret
+*/
+int
+d_eq_0 (void)
+{
+  return svcntd () == 0;
+}
+
+/*
+** b_lt_256:
+**	cntb	x0
+**	cmp	x0, 256
+**	cset	w0, cc
+**	ret
+*/
+int
+b_lt_256 (void)
+{
+  return svcntb () < 256;
+}
+
+/*
+** w_gt_4:
+**	cntw	x0
+**	cmp	x0, 4
+**	cset	w0, hi
+**	ret
+*/
+int
+w_gt_4 (void)
+{
+  return svcntw () > 4;
+}
+
+/*
+** b_pat_all_lt_257:
+**	mov	w0, 1
+**	ret
+*/
+int
+b_pat_all_lt_257 (void)
+{
+  return svcntb_pat (SV_ALL) < 257;
+}
+
+/*
+** w_pat_all_le_64:
+**	mov	w0, 1
+**	ret
+*/
+int
+w_pat_all_le_64 (void)
+{
+  return svcntw_pat (SV_ALL) <= 64;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7_run.c
new file mode 100644
index 000000000000..59217ab343ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7_run.c
@@ -0,0 +1,47 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+#define CHECK(EXPR) \
+  do \
+    { \
+      if (!(EXPR)) \
+	__builtin_abort (); \
+    } \
+  while (0)
+
+int
+main (void)
+{
+  unsigned int b = svcntb ();
+  unsigned int h = svcnth ();
+  unsigned int w = svcntw ();
+  unsigned int d = svcntd ();
+
+  CHECK (b >= 16 && b <= 256);
+  CHECK (h >= 8 && h <= 128);
+  CHECK (w >= 4 && w <= 64);
+  CHECK (d >= 2 && d <= 32);
+
+  CHECK (b < 257);
+  CHECK (h >= 8);
+  CHECK (w <= 64);
+  CHECK (d > 1);
+  CHECK (b != 0);
+
+  CHECK (!(b <= 15));
+  CHECK (!(h < 8));
+  CHECK (!(w > 64));
+  CHECK (!(d == 0));
+
+  CHECK ((svcntb () < 256) == (b < 256));
+  CHECK ((svcntw () > 4) == (w > 4));
+
+  CHECK (svcntb_pat (SV_ALL) == b);
+  CHECK (svcntw_pat (SV_ALL) == w);
+  CHECK (svcntb_pat (SV_ALL) < 257);
+  CHECK (svcntw_pat (SV_ALL) <= 64);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c
index 6ba4c9651b67..c81845f2c87f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c
@@ -47,14 +47,12 @@ TEST_ALL (VEC_PERM)
 
 /* We should use WHILEs for all accesses.  */
 /* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.b} 20 } } */
-/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.h} 18 } } */
-/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s} 27 } } */
-/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d} 24 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.h} 16 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s} 21 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d} 15 } } */
 
 /* 6 for the 8-bit types and 2 for the 16-bit types.  */
 /* { dg-final { scan-assembler-times {\tuqdecb\t} 8 } } */
-/* 4 for the 16-bit types and 3 for the 32-bit types.  */
-/* { dg-final { scan-assembler-times {\tuqdech\t} 7 } } */
-/* 6 for the 32-bit types and 3 for the 64-bit types.  */
-/* { dg-final { scan-assembler-times {\tuqdecw\t} 9 } } */
-/* { dg-final { scan-assembler-times {\tuqdecd\t} 6 } } */
+/* { dg-final { scan-assembler-times {\tuqdech\t} 2 } } */
+/* { dg-final { scan-assembler-times {\tuqdecw\t} 3 } } */
+/* { dg-final { scan-assembler-not {\tuqdecd\t} } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.