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

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Patch was previously approved by split from the series, so Pushed.

Thanks,
Tamar

gcc/ChangeLog:

        * config/aarch64/aarch64.cc (aarch64_poly_int_indeterminate_bound): New.
        (TARGET_POLY_INT_INDETERMINATE_BOUND ): Implement hook using it.
        * target.def (poly_int_indeterminate_bound): New.
        * doc/tm.texi.in: Document it.
        * doc/tm.texi: Regenerate.
        * value-query.cc (range_query::get_tree_range): Use 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 --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 
fdffb13ad222b7e86709a2e7caef520dbb77d050..da1e9eb7bc858de8563b2ab4f9e42d67aaf625aa
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31283,6 +31283,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.  */
@@ -34605,6 +34613,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 
0000000000000000000000000000000000000000..d64933527da7e3e85f37dc231355eb4cd30a1422
--- /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 
0000000000000000000000000000000000000000..59217ab343ec03509bccc6d12098e6264adaa8b1
--- /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 
6ba4c9651b67d7e2495b58ffc0ed01f563c428b6..c81845f2c87f9e68e7933cded9868d1a732a8854
 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} } } */


-- 
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index fdffb13ad222b7e86709a2e7caef520dbb77d050..da1e9eb7bc858de8563b2ab4f9e42d67aaf625aa 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31283,6 +31283,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.  */
@@ -34605,6 +34613,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 0000000000000000000000000000000000000000..d64933527da7e3e85f37dc231355eb4cd30a1422
--- /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 0000000000000000000000000000000000000000..59217ab343ec03509bccc6d12098e6264adaa8b1
--- /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 6ba4c9651b67d7e2495b58ffc0ed01f563c428b6..c81845f2c87f9e68e7933cded9868d1a732a8854 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} } } */

Reply via email to