> -----Original Message----- > From: Richard Sandiford <richard.sandif...@arm.com> > Sent: Tuesday, July 29, 2025 4:33 PM > To: gcc-patches@gcc.gnu.org > Cc: Alex Coplan <alex.cop...@arm.com>; Alice Carlotti > <alice.carlo...@arm.com>; > pins...@gmail.com; ktkac...@nvidia.com; Richard Earnshaw > <richard.earns...@arm.com>; Tamar Christina <tamar.christ...@arm.com>; > Wilco Dijkstra <wilco.dijks...@arm.com> > Subject: [PATCH] aarch64: Use VNx16BI for more SVE WHILE* results [PR121118] > > 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. >
For my own understanding, *what* is the representation of svbool_t? ACLE just seems to say it has "enough bits" [1] [1] https://arm-software.github.io/acle/main/acle.html#sve-predicate-types > 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? OK thanks. I was wondering if we couldn't do anything special for the cases where both operands of the while* are zero. But it looks like PTRUES are as bad as WHILE* and we have no PFALSES anyway ☹ Thanks, Tamar > > 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>_a > cle" > + [(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