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} } } */