PR121118 is about a case where we try to construct a predicate
constant using a permutation of a PFALSE and a WHILELO.  The WHILELO
is a .H operation and its result has mode VNx8BI.  However, the
permute instruction expects both inputs to be VNx16BI, leading to
an unrecognisable insn ICE.

VNx8BI is effectively a form of VNx16BI in which every odd-indexed
bit is insignificant.  In the PR's testcase that's OK, since those
bits will be dropped by the permutation.  But if the WHILELO had been a
VNx4BI, so that only every fourth bit is significant, the input to the
permutation would have had undefined bits.  The testcase in the patch
has an example of this.

This feeds into a related ACLE problem that I'd been meaning to
fix for a long time: every bit of an svbool_t result is significant,
and so every ACLE intrinsic that returns an svbool_t should return a
VNx16BI.  That doesn't currently happen for ACLE svwhile* intrinsics.

This patch fixes both issues together.

We still need to keep the current WHILE* patterns for autovectorisation,
where the result mode should match the element width.  The patch
therefore adds a new set of patterns that are defined to return
VNx16BI instead.  For want of a better scheme, it uses an "_acle"
suffix to distinguish these new patterns from the "normal" ones.

The formulation used is:

  (and:VNx16BI (subreg:VNx16BI normal-pattern 0) C)

where C has mode VNx16BI and is a canonical ptrue for normal-pattern's
element width (so that the low bit of each element is set and the upper
bits are clear).

This is a bit clunky, and leads to some repetition.  But it has two
advantages:

* With an earlier simplify-rtx patch, converting the above expression
  back to normal-pattern's mode will reduce to normal-pattern, so that
  the pattern for testing the result using a PTEST doesn't change.

* It gives RTL optimisers a bit more information, as the new tests
  demonstrate.

In the expression above, C is matched using a new "special" predicate
aarch64_ptrue_all_operand, where "special" means that the mode on the
predicate is not necessarily the mode of the expression.  In this case,
C always has mode VNx16BI, but the mode on the predicate indicates which
kind of canonical PTRUE is needed.

Tested on aarch64-linux-gnu.  OK to install?

Richard


gcc/
        PR testsuite/121118
        * config/aarch64/iterators.md (VNx16BI_ONLY): New mode iterator.
        * config/aarch64/predicates.md (aarch64_ptrue_all_operand): New
        predicate.
        * config/aarch64/aarch64-sve.md
        (@aarch64_sve_while_<while_optab_cmp><GPI:mode><VNx16BI_ONLY:mode>_acle)
        (@aarch64_sve_while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle)
        (*aarch64_sve_while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle)
        (*while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle_cc): New
        patterns.
        * config/aarch64/aarch64-sve-builtins-functions.h
        (while_comparison::expand): Use the new _acle patterns that
        always return a VNx16BI.
        * config/aarch64/aarch64-sve-builtins-sve2.cc
        (svwhilerw_svwhilewr_impl::expand): Likewise.
        * config/aarch64/aarch64.cc
        (aarch64_sve_move_pred_via_while): Likewise.

gcc/testsuite/
        PR testsuite/121118
        * gcc.target/aarch64/sve/acle/general/pr121118_1.c: New test.
        * gcc.target/aarch64/sve/acle/general/whilele_13.c: Likewise.
        * gcc.target/aarch64/sve/acle/general/whilelt_6.c: Likewise.
        * gcc.target/aarch64/sve2/acle/general/whilege_1.c: Likewise.
        * gcc.target/aarch64/sve2/acle/general/whilegt_1.c: Likewise.
        * gcc.target/aarch64/sve2/acle/general/whilerw_5.c: Likewise.
        * gcc.target/aarch64/sve2/acle/general/whilewr_5.c: Likewise.
---
 .../aarch64/aarch64-sve-builtins-functions.h  |   3 +-
 .../aarch64/aarch64-sve-builtins-sve2.cc      |   4 +-
 gcc/config/aarch64/aarch64-sve.md             |  84 +++++++++++
 gcc/config/aarch64/aarch64.cc                 |   6 +-
 gcc/config/aarch64/iterators.md               |   1 +
 gcc/config/aarch64/predicates.md              |   6 +
 .../aarch64/sve/acle/general/pr121118_1.c     |  16 +++
 .../aarch64/sve/acle/general/whilele_13.c     | 130 ++++++++++++++++++
 .../aarch64/sve/acle/general/whilelt_6.c      | 130 ++++++++++++++++++
 .../aarch64/sve2/acle/general/whilege_1.c     | 130 ++++++++++++++++++
 .../aarch64/sve2/acle/general/whilegt_1.c     | 130 ++++++++++++++++++
 .../aarch64/sve2/acle/general/whilerw_5.c     | 130 ++++++++++++++++++
 .../aarch64/sve2/acle/general/whilewr_5.c     | 130 ++++++++++++++++++
 13 files changed, 895 insertions(+), 5 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr121118_1.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_13.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_6.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilege_1.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilegt_1.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilerw_5.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilewr_5.c

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-functions.h 
b/gcc/config/aarch64/aarch64-sve-builtins-functions.h
index 6f1c6948df2..b0cfa703dc4 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-functions.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins-functions.h
@@ -838,7 +838,8 @@ public:
 
     machine_mode pred_mode = e.vector_mode (0);
     scalar_mode reg_mode = GET_MODE_INNER (e.vector_mode (1));
-    return e.use_exact_insn (code_for_while (unspec, reg_mode, pred_mode));
+    auto icode = code_for_aarch64_sve_while_acle (unspec, reg_mode, pred_mode);
+    return e.use_exact_insn (icode);
   }
 
   /* The unspec codes associated with signed and unsigned operations
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc 
b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
index 73004a8fd5c..95c5ed81d61 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
@@ -881,7 +881,9 @@ public:
   {
     for (unsigned int i = 0; i < 2; ++i)
       e.args[i] = e.convert_to_pmode (e.args[i]);
-    return e.use_exact_insn (code_for_while (m_unspec, Pmode, e.gp_mode (0)));
+    auto icode = code_for_aarch64_sve_while_acle (m_unspec, Pmode,
+                                                 e.gp_mode (0));
+    return e.use_exact_insn (icode);
   }
 
   int m_unspec;
diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index b252eef411c..6d8c5b7b00e 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -8576,6 +8576,58 @@ (define_insn 
"@while_<while_optab_cmp><GPI:mode><PRED_ALL:mode>"
   "while<cmp_op>\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
 )
 
+;; Likewise, but yield a VNx16BI result regardless of the element width.
+;; The .b case is equivalent to the above.
+(define_expand 
"@aarch64_sve_while_<while_optab_cmp><GPI:mode><VNx16BI_ONLY:mode>_acle"
+  [(parallel
+     [(set (match_operand:VNx16BI_ONLY 0 "register_operand" "=Upa")
+          (unspec:VNx16BI_ONLY
+            [(const_int SVE_WHILE_B)
+             (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+             (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
+            SVE_WHILE))
+      (clobber (reg:CC_NZC CC_REGNUM))])]
+  "TARGET_SVE"
+)
+
+;; For wider elements, bitcast the predicate result to a VNx16BI and use
+;; an (and ...) to indicate that only every second, fourth, or eighth bit
+;; is set.
+(define_expand 
"@aarch64_sve_while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle"
+  [(parallel
+     [(set (match_operand:VNx16BI 0 "register_operand")
+          (and:VNx16BI
+            (subreg:VNx16BI
+              (unspec:PRED_HSD
+                [(const_int SVE_WHILE_B)
+                 (match_operand:GPI 1 "aarch64_reg_or_zero")
+                 (match_operand:GPI 2 "aarch64_reg_or_zero")]
+                SVE_WHILE)
+              0)
+            (match_dup 3)))
+      (clobber (reg:CC_NZC CC_REGNUM))])]
+  "TARGET_SVE"
+  {
+    operands[3] = aarch64_ptrue_all (<data_bytes>);
+  }
+)
+
+(define_insn 
"*aarch64_sve_while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle"
+  [(set (match_operand:VNx16BI 0 "register_operand" "=Upa")
+       (and:VNx16BI
+         (subreg:VNx16BI
+           (unspec:PRED_HSD
+             [(const_int SVE_WHILE_B)
+              (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+              (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
+             SVE_WHILE)
+           0)
+         (match_operand:PRED_HSD 3 "aarch64_ptrue_all_operand")))
+   (clobber (reg:CC_NZC CC_REGNUM))]
+  "TARGET_SVE"
+  "while<cmp_op>\t%0.<PRED_HSD:Vetype>, %<w>1, %<w>2"
+)
+
 ;; The WHILE instructions set the flags in the same way as a PTEST with
 ;; a PTRUE GP.  Handle the case in which both results are useful.  The GP
 ;; operands to the PTEST aren't needed, so we allow them to be anything.
@@ -8607,6 +8659,38 @@ (define_insn_and_rewrite 
"*while_<while_optab_cmp><GPI:mode><PRED_ALL:mode>_cc"
   }
 )
 
+(define_insn_and_rewrite 
"*while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle_cc"
+  [(set (reg:CC_NZC CC_REGNUM)
+       (unspec:CC_NZC
+         [(match_operand 3)
+          (match_operand 4)
+          (const_int SVE_KNOWN_PTRUE)
+          (unspec:PRED_HSD
+            [(const_int SVE_WHILE_B)
+             (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+             (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
+            SVE_WHILE)]
+         UNSPEC_PTEST))
+   (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
+       (and:VNx16BI
+         (subreg:VNx16BI
+           (unspec:PRED_HSD [(const_int SVE_WHILE_B)
+                             (match_dup 1)
+                             (match_dup 2)]
+                            SVE_WHILE)
+           0)
+         (match_operand:PRED_HSD 5 "aarch64_ptrue_all_operand")))]
+  "TARGET_SVE"
+  "while<cmp_op>\t%0.<PRED_HSD:Vetype>, %<w>1, %<w>2"
+  ;; Force the compiler to drop the unused predicate operand, so that we
+  ;; don't have an unnecessary PTRUE.
+  "&& (!CONSTANT_P (operands[3]) || !CONSTANT_P (operands[4]))"
+  {
+    operands[3] = CONSTM1_RTX (VNx16BImode);
+    operands[4] = CONSTM1_RTX (<PRED_HSD:MODE>mode);
+  }
+)
+
 ;; Same, but handle the case in which only the flags result is useful.
 (define_insn_and_rewrite 
"@while_<while_optab_cmp><GPI:mode><PRED_ALL:mode>_ptest"
   [(set (reg:CC_NZC CC_REGNUM)
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index a6d6bed97e8..be6b4eb9dbd 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -6042,9 +6042,9 @@ aarch64_sve_move_pred_via_while (rtx target, machine_mode 
mode,
                                 unsigned int vl)
 {
   rtx limit = force_reg (DImode, gen_int_mode (vl, DImode));
-  target = aarch64_target_reg (target, mode);
-  emit_insn (gen_while (UNSPEC_WHILELO, DImode, mode,
-                       target, const0_rtx, limit));
+  target = aarch64_target_reg (target, VNx16BImode);
+  emit_insn (gen_aarch64_sve_while_acle (UNSPEC_WHILELO, DImode, mode,
+                                        target, const0_rtx, limit));
   return target;
 }
 
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 8533912e593..175a55336c5 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -455,6 +455,7 @@ (define_mode_iterator VLUTx2 [V2x8HI V2x8HF V2x8BF])
 (define_mode_iterator VCVTFPM [V4HF V8HF V4SF])
 
 ;; Iterators for single modes, for "@" patterns.
+(define_mode_iterator VNx16BI_ONLY [VNx16BI])
 (define_mode_iterator VNx16QI_ONLY [VNx16QI])
 (define_mode_iterator VNx16SI_ONLY [VNx16SI])
 (define_mode_iterator VNx8HI_ONLY [VNx8HI])
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 32056daf329..4d5d57f1e5d 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -1078,3 +1078,9 @@ (define_predicate "aarch64_granule16_simm9"
 (define_predicate "aarch64_maskload_else_operand"
   (and (match_code "const_vector")
        (match_test "op == CONST0_RTX (GET_MODE (op))")))
+
+;; Check for a VNx16BI predicate that is a canonical PTRUE for the given
+;; predicate mode.
+(define_special_predicate "aarch64_ptrue_all_operand"
+  (and (match_code "const_vector")
+       (match_test "aarch64_ptrue_all_mode (op) == mode")))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr121118_1.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr121118_1.c
new file mode 100644
index 00000000000..b59a972c0c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr121118_1.c
@@ -0,0 +1,16 @@
+/* { dg-options "-O2 -msve-vector-bits=512" } */
+
+typedef __SVBool_t fixed_bool __attribute__((arm_sve_vector_bits(512)));
+
+#define TEST_CONST(NAME, CONST)                                                
\
+  fixed_bool                                                           \
+  NAME ()                                                              \
+  {                                                                    \
+    union { unsigned long long i; fixed_bool pg; } u = { CONST };      \
+    return u.pg;                                                       \
+  }
+
+TEST_CONST (test1, 0x02aaaaaaaa)
+TEST_CONST (test2, 0x0155555557)
+TEST_CONST (test3, 0x0013333333333333ULL)
+TEST_CONST (test4, 0x0011111111111113ULL)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_13.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_13.c
new file mode 100644
index 00000000000..cf50dc17082
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_13.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** test1:
+**     whilele p0\.h, w0, w1
+**     ret
+*/
+svbool_t
+test1 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilele_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test2:
+**     whilele p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test2 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilele_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test3:
+**     whilels p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test3 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilele_b32 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test4:
+**     whilels p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test4 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilele_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test5:
+**     whilele p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test5 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilele_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test6:
+**     whilels p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test6 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b32 (),
+                 svwhilele_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test7:
+**     whilels p0\.d, w0, w1
+**     ret
+*/
+svbool_t
+test7 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilele_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+/*
+** test8:
+**     whilele p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test8 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilele_b64 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test9:
+**     whilels p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test9 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b64 (),
+                 svwhilele_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_6.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_6.c
new file mode 100644
index 00000000000..27bf0c28d54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_6.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** test1:
+**     whilelt p0\.h, w0, w1
+**     ret
+*/
+svbool_t
+test1 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilelt_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test2:
+**     whilelt p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test2 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilelt_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test3:
+**     whilelo p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test3 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilelt_b32 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test4:
+**     whilelo p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test4 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilelt_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test5:
+**     whilelt p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test5 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilelt_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test6:
+**     whilelo p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test6 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b32 (),
+                 svwhilelt_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test7:
+**     whilelo p0\.d, w0, w1
+**     ret
+*/
+svbool_t
+test7 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilelt_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+/*
+** test8:
+**     whilelt p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test8 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilelt_b64 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test9:
+**     whilelo p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test9 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b64 (),
+                 svwhilelt_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilege_1.c 
b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilege_1.c
new file mode 100644
index 00000000000..07b56a8138a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilege_1.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** test1:
+**     whilege p0\.h, w0, w1
+**     ret
+*/
+svbool_t
+test1 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilege_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test2:
+**     whilege p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test2 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilege_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test3:
+**     whilehs p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test3 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilege_b32 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test4:
+**     whilehs p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test4 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilege_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test5:
+**     whilege p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test5 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilege_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test6:
+**     whilehs p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test6 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b32 (),
+                 svwhilege_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test7:
+**     whilehs p0\.d, w0, w1
+**     ret
+*/
+svbool_t
+test7 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilege_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+/*
+** test8:
+**     whilege p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test8 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilege_b64 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test9:
+**     whilehs p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test9 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b64 (),
+                 svwhilege_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilegt_1.c 
b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilegt_1.c
new file mode 100644
index 00000000000..df707c39571
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilegt_1.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** test1:
+**     whilegt p0\.h, w0, w1
+**     ret
+*/
+svbool_t
+test1 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilegt_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test2:
+**     whilegt p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test2 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilegt_b16 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test3:
+**     whilehi p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test3 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilegt_b32 (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test4:
+**     whilehi p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test4 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilegt_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test5:
+**     whilegt p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test5 (int32_t x, int32_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilegt_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test6:
+**     whilehi p0\.s, w0, w1
+**     ret
+*/
+svbool_t
+test6 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b32 (),
+                 svwhilegt_b32 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test7:
+**     whilehi p0\.d, w0, w1
+**     ret
+*/
+svbool_t
+test7 (uint32_t x, uint32_t y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilegt_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+/*
+** test8:
+**     whilegt p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test8 (int64_t x, int64_t y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilegt_b64 (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test9:
+**     whilehi p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test9 (uint64_t x, uint64_t y)
+{
+  return svand_z (svptrue_b64 (),
+                 svwhilegt_b64 (x, y),
+                 svptrue_b64 ());
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilerw_5.c 
b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilerw_5.c
new file mode 100644
index 00000000000..0c24199e078
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilerw_5.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** test1:
+**     whilerw p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test1 (int16_t *x, int16_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilerw (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test2:
+**     whilerw p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test2 (uint16_t *x, uint16_t *y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilerw (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test3:
+**     whilerw p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test3 (int32_t *x, int32_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilerw (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test4:
+**     whilerw p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test4 (uint32_t *x, uint32_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilerw (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test5:
+**     whilerw p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test5 (float32_t *x, float32_t *y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilerw (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test6:
+**     whilerw p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test6 (int32_t *x, int32_t *y)
+{
+  return svand_z (svptrue_b32 (),
+                 svwhilerw (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test7:
+**     whilerw p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test7 (int64_t *x, int64_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilerw (x, y),
+                 svptrue_b64 ());
+}
+
+/*
+** test8:
+**     whilerw p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test8 (uint64_t *x, uint64_t *y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilerw (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test9:
+**     whilerw p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test9 (float64_t *x, float64_t *y)
+{
+  return svand_z (svptrue_b64 (),
+                 svwhilerw (x, y),
+                 svptrue_b64 ());
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilewr_5.c 
b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilewr_5.c
new file mode 100644
index 00000000000..38db9af47cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/general/whilewr_5.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** test1:
+**     whilewr p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test1 (int16_t *x, int16_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilewr (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test2:
+**     whilewr p0\.h, x0, x1
+**     ret
+*/
+svbool_t
+test2 (uint16_t *x, uint16_t *y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilewr (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test3:
+**     whilewr p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test3 (int32_t *x, int32_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilewr (x, y),
+                 svptrue_b16 ());
+}
+
+/*
+** test4:
+**     whilewr p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test4 (uint32_t *x, uint32_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilewr (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test5:
+**     whilewr p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test5 (float32_t *x, float32_t *y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilewr (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test6:
+**     whilewr p0\.s, x0, x1
+**     ret
+*/
+svbool_t
+test6 (int32_t *x, int32_t *y)
+{
+  return svand_z (svptrue_b32 (),
+                 svwhilewr (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test7:
+**     whilewr p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test7 (int64_t *x, int64_t *y)
+{
+  return svand_z (svptrue_b8 (),
+                 svwhilewr (x, y),
+                 svptrue_b64 ());
+}
+
+/*
+** test8:
+**     whilewr p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test8 (uint64_t *x, uint64_t *y)
+{
+  return svand_z (svptrue_b16 (),
+                 svwhilewr (x, y),
+                 svptrue_b32 ());
+}
+
+/*
+** test9:
+**     whilewr p0\.d, x0, x1
+**     ret
+*/
+svbool_t
+test9 (float64_t *x, float64_t *y)
+{
+  return svand_z (svptrue_b64 (),
+                 svwhilewr (x, y),
+                 svptrue_b64 ());
+}
+
+#ifdef __cplusplus
+}
+#endif
-- 
2.43.0

Reply via email to