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:
* After g:
965564eafb721f8000013a3112f1bba8d8fae32b, 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.
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.
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
{
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;
"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")
+ (unspec:VNx16BI_ONLY
+ [(const_int SVE_WHILE_B)
+ (match_operand:GPI 1 "aarch64_reg_or_zero")
+ (match_operand:GPI 2 "aarch64_reg_or_zero")]
+ 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.
}
)
+(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)
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;
}
(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])
(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")))
--- /dev/null
+/* { 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)
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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