This fixes a compiler error that occurred when trying to fold whilelt
and whilele predicate as counter builtins as if they were regular
predicated builtins.
PR target/126096
gcc/ChangeLog:
* config/aarch64/aarch64-acle-builtins.cc
(gimple_folder::fold_to_pfalse): handle svcount_t when folding
to pfalse.
* config/aarch64/aarch64-sve-builtins-base.cc: Punt in cases
where we can't fold predicate as counter builtins
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve2/acle/general/whilele_1.c: New test.
* gcc.target/aarch64/sve2/acle/general/whilelt_1.c: New test.
---
gcc/config/aarch64/aarch64-acle-builtins.cc | 11 +++-
.../aarch64/aarch64-sve-builtins-base.cc | 9 +--
.../aarch64/sve2/acle/general/whilele_1.c | 60 +++++++++++++++++++
.../aarch64/sve2/acle/general/whilelt_1.c | 60 +++++++++++++++++++
4 files changed, 135 insertions(+), 5 deletions(-)
create mode 100644
gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilele_1.c
create mode 100644
gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilelt_1.c
diff --git a/gcc/config/aarch64/aarch64-acle-builtins.cc
b/gcc/config/aarch64/aarch64-acle-builtins.cc
index 98ba6c8d347..b1a25d5cc4e 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.cc
+++ b/gcc/config/aarch64/aarch64-acle-builtins.cc
@@ -3011,7 +3011,16 @@ gimple_folder::fold_to_ptrue ()
gimple *
gimple_folder::fold_to_pfalse ()
{
- return gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
+ if (type_suffix (0).tclass == TYPE_bool)
+ return gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
+
+ if (type_suffix (0).tclass == TYPE_count)
+ {
+ tree svbool_type = abi_vector_types[VECTOR_TYPE_svbool_t];
+ return fold_call_to (build_zero_cst (svbool_type));
+ }
+
+ return NULL;
}
/* Fold an operation to a constant predicate in which the first VL
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 5d01d875a9d..df4c12916cd 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -2532,10 +2532,7 @@ public:
gimple *
fold (gimple_folder &f) const override
{
- if (f.type_suffix (0).tclass == TYPE_bool)
- return f.fold_to_pfalse ();
-
- return nullptr;
+ return f.fold_to_pfalse ();
}
rtx
@@ -3417,6 +3414,10 @@ public:
if (m_eq_p ? known_gt (arg0, arg1) : known_ge (arg0, arg1))
return f.fold_to_pfalse ();
+ /* Punt if we are trying to fold a predicate as counter builtin. */
+ if (f.type_suffix (0).tclass == TYPE_count)
+ return NULL;
+
/* Punt if we can't tell at compile time whether the result
is all-false. */
if (m_eq_p ? maybe_gt (arg0, arg1) : maybe_ge (arg0, arg1))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilele_1.c
b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilele_1.c
new file mode 100644
index 00000000000..a0b8c42244b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilele_1.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { ! aarch64_asm_sve2p1_ok } } } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+#pragma GCC target "+sve2p1"
+
+/* { dg-final { scan-assembler-not {\twhilele\t} } } */
+/* { dg-final { scan-assembler-not {\twhilelt\t} } } */
+/* { dg-final { scan-assembler-not {\tptrue\t} } } */
+
+void
+test1 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c8_s64 (0, -57, 2);
+}
+
+void
+test2 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c8_u64 (50, 0, 2);
+}
+
+void
+test3 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c16_s64 (7, 5, 2);
+}
+
+void
+test4 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c16_u64 (900, 100, 2);
+}
+
+void
+test5 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c32_s64 (-10, -50, 4);
+}
+
+void
+test6 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c32_u64 (1, 0, 4);
+}
+
+void
+test7 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c64_s64 (0, -5, 4);
+}
+
+void
+test8 (svcount_t *ptr)
+{
+ *ptr = svwhilele_c64_u64 (8, 0, 4);
+}
+
+/* { dg-final { scan-assembler-times {\tpfalse\tp[0-9]+\.b\n} 8 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilelt_1.c
b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilelt_1.c
new file mode 100644
index 00000000000..9201d216fe7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilelt_1.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { ! aarch64_asm_sve2p1_ok } } } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+#pragma GCC target "+sve2p1"
+
+/* { dg-final { scan-assembler-not {\twhilele\t} } } */
+/* { dg-final { scan-assembler-not {\twhilelt\t} } } */
+/* { dg-final { scan-assembler-not {\tptrue\t} } } */
+
+void
+test1 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c8_s64 (0, -57, 2);
+}
+
+void
+test2 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c8_u64 (50, 0, 2);
+}
+
+void
+test3 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c16_s64 (0, 0, 2);
+}
+
+void
+test4 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c16_u64 (0, 0, 2);
+}
+
+void
+test5 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c32_s64 (-10, -50, 4);
+}
+
+void
+test6 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c32_u64 (0, 0, 4);
+}
+
+void
+test7 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c64_s64 (0, 0, 4);
+}
+
+void
+test8 (svcount_t *ptr)
+{
+ *ptr = svwhilelt_c64_u64 (0, 0, 4);
+}
+
+/* { dg-final { scan-assembler-times {\tpfalse\tp[0-9]+\.b\n} 8 } } */
--
2.43.0