https://gcc.gnu.org/g:fdbe94f7c88f53f1d65e9891e6eab2fe803a6e77
commit r15-5094-gfdbe94f7c88f53f1d65e9891e6eab2fe803a6e77 Author: Richard Sandiford <richard.sandif...@arm.com> Date: Mon Nov 11 12:32:18 2024 +0000 aarch64: Add svboolx4_t This patch adds an svboolx4_t type, to go alongside the existing svboolx2_t type. It doesn't require any special ISA support beyond SVE itself and it currently has no associated instructions. gcc/ * config/aarch64/aarch64-modes.def (VNx64BI): New mode. * config/aarch64/aarch64-protos.h (aarch64_split_double_move): Generalize to... (aarch64_split_move): ...this. * config/aarch64/aarch64-sve-builtins-base.def (svcreate4, svget4) (svset4, svundef4): Add bool variants. * config/aarch64/aarch64-sve-builtins.cc (handle_arm_sve_h): Add svboolx4_t. * config/aarch64/iterators.md (SVE_STRUCT_BI): New mode iterator. * config/aarch64/aarch64-sve.md (movvnx32bi): Generalize to... (mov<SVE_STRUCT_BI:mode>): ...this. * config/aarch64/aarch64.cc (pure_scalable_type_info::piece::get_rtx): Allow num_prs to be 4. (aarch64_classify_vector_mode): Handle VNx64BI. (aarch64_hard_regno_nregs): Likewise. (aarch64_class_max_nregs): Likewise. (aarch64_array_mode): Use VNx64BI for arrays of 4 svbool_ts. (aarch64_split_double_move): Generalize to... (aarch64_split_move): ...this. (aarch64_split_128bit_move): Update call accordingly. gcc/testsuite/ * gcc.target/aarch64/sve/acle/general-c/create_5.c: Expect svcreate4 to succeed for svbool_ts. * gcc.target/aarch64/sve/acle/asm/test_sve_acle.h (TEST_UNDEF_B): New macro. * gcc.target/aarch64/sve/acle/asm/create4_1.c: Test _b form. * gcc.target/aarch64/sve/acle/asm/undef2_1.c: Likewise. * gcc.target/aarch64/sve/acle/asm/undef4_1.c: Likewise. * gcc.target/aarch64/sve/acle/asm/get4_b.c: New test. * gcc.target/aarch64/sve/acle/asm/set4_b.c: Likewise. * gcc.target/aarch64/sve/acle/general-c/svboolx4_1.c: Likewise. Diff: --- gcc/config/aarch64/aarch64-modes.def | 3 + gcc/config/aarch64/aarch64-protos.h | 2 +- gcc/config/aarch64/aarch64-sve-builtins-base.def | 4 + gcc/config/aarch64/aarch64-sve-builtins.cc | 2 +- gcc/config/aarch64/aarch64-sve.md | 8 +- gcc/config/aarch64/aarch64.cc | 50 ++++----- gcc/config/aarch64/iterators.md | 2 + .../gcc.target/aarch64/sve/acle/asm/create4_1.c | 10 ++ .../gcc.target/aarch64/sve/acle/asm/get4_b.c | 73 +++++++++++++ .../gcc.target/aarch64/sve/acle/asm/set4_b.c | 87 +++++++++++++++ .../aarch64/sve/acle/asm/test_sve_acle.h | 8 ++ .../gcc.target/aarch64/sve/acle/asm/undef2_1.c | 7 ++ .../gcc.target/aarch64/sve/acle/asm/undef4_1.c | 7 ++ .../aarch64/sve/acle/general-c/create_5.c | 2 +- .../aarch64/sve/acle/general-c/svboolx4_1.c | 117 +++++++++++++++++++++ 15 files changed, 351 insertions(+), 31 deletions(-) diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def index 25a22c1195e1..813421e1e39e 100644 --- a/gcc/config/aarch64/aarch64-modes.def +++ b/gcc/config/aarch64/aarch64-modes.def @@ -48,18 +48,21 @@ ADJUST_FLOAT_FORMAT (HF, &ieee_half_format); /* Vector modes. */ +VECTOR_BOOL_MODE (VNx64BI, 64, BI, 8); VECTOR_BOOL_MODE (VNx32BI, 32, BI, 4); VECTOR_BOOL_MODE (VNx16BI, 16, BI, 2); VECTOR_BOOL_MODE (VNx8BI, 8, BI, 2); VECTOR_BOOL_MODE (VNx4BI, 4, BI, 2); VECTOR_BOOL_MODE (VNx2BI, 2, BI, 2); +ADJUST_NUNITS (VNx64BI, aarch64_sve_vg * 32); ADJUST_NUNITS (VNx32BI, aarch64_sve_vg * 16); ADJUST_NUNITS (VNx16BI, aarch64_sve_vg * 8); ADJUST_NUNITS (VNx8BI, aarch64_sve_vg * 4); ADJUST_NUNITS (VNx4BI, aarch64_sve_vg * 2); ADJUST_NUNITS (VNx2BI, aarch64_sve_vg); +ADJUST_ALIGNMENT (VNx64BI, 2); ADJUST_ALIGNMENT (VNx32BI, 2); ADJUST_ALIGNMENT (VNx16BI, 2); ADJUST_ALIGNMENT (VNx8BI, 2); diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 6ab41a21c75d..05d3258abf7b 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -1045,7 +1045,7 @@ rtx aarch64_simd_expand_builtin (int, tree, rtx); void aarch64_simd_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT, const_tree); rtx aarch64_endian_lane_rtx (machine_mode, unsigned int); -void aarch64_split_double_move (rtx, rtx, machine_mode); +void aarch64_split_move (rtx, rtx, machine_mode); void aarch64_split_128bit_move (rtx, rtx); bool aarch64_split_128bit_move_p (rtx, rtx); diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.def b/gcc/config/aarch64/aarch64-sve-builtins-base.def index da2a0e41aa5d..0353f56e7057 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.def +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.def @@ -74,6 +74,7 @@ DEF_SVE_FUNCTION (svcreate2, create, all_data, none) DEF_SVE_FUNCTION (svcreate2, create, b, none) DEF_SVE_FUNCTION (svcreate3, create, all_data, none) DEF_SVE_FUNCTION (svcreate4, create, all_data, none) +DEF_SVE_FUNCTION (svcreate4, create, b, none) DEF_SVE_FUNCTION (svcvt, unary_convertxn, cvt, mxz) DEF_SVE_FUNCTION (svdiv, binary_opt_n, all_float_and_sd_integer, mxz) DEF_SVE_FUNCTION (svdivr, binary_opt_n, all_float_and_sd_integer, mxz) @@ -96,6 +97,7 @@ DEF_SVE_FUNCTION (svget2, get, all_data, none) DEF_SVE_FUNCTION (svget2, get, b, none) DEF_SVE_FUNCTION (svget3, get, all_data, none) DEF_SVE_FUNCTION (svget4, get, all_data, none) +DEF_SVE_FUNCTION (svget4, get, b, none) DEF_SVE_FUNCTION (svindex, binary_scalar, all_integer, none) DEF_SVE_FUNCTION (svinsr, binary_n, all_data, none) DEF_SVE_FUNCTION (svlasta, reduction, all_data, implicit) @@ -223,6 +225,7 @@ DEF_SVE_FUNCTION (svset2, set, all_data, none) DEF_SVE_FUNCTION (svset2, set, b, none) DEF_SVE_FUNCTION (svset3, set, all_data, none) DEF_SVE_FUNCTION (svset4, set, all_data, none) +DEF_SVE_FUNCTION (svset4, set, b, none) DEF_SVE_FUNCTION (svsplice, binary, all_data, implicit) DEF_SVE_FUNCTION (svsqrt, unary, all_float, mxz) DEF_SVE_FUNCTION (svst1, storexn, all_data, implicit) @@ -245,6 +248,7 @@ DEF_SVE_FUNCTION (svundef2, inherent, all_data, none) DEF_SVE_FUNCTION (svundef2, inherent, b, none) DEF_SVE_FUNCTION (svundef3, inherent, all_data, none) DEF_SVE_FUNCTION (svundef4, inherent, all_data, none) +DEF_SVE_FUNCTION (svundef4, inherent, b, none) DEF_SVE_FUNCTION (svunpkhi, unary_widen, hsd_integer, none) DEF_SVE_FUNCTION (svunpkhi, unary_widen, b, none) DEF_SVE_FUNCTION (svunpklo, unary_widen, hsd_integer, none) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 9fb0d6fd4168..259e7b7975c9 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -4697,7 +4697,7 @@ handle_arm_sve_h (bool function_nulls_p) register_vector_type (type); if (type != VECTOR_TYPE_svcount_t) for (unsigned int count = 2; count <= MAX_TUPLE_SIZE; ++count) - if (type != VECTOR_TYPE_svbool_t || count == 2) + if (type != VECTOR_TYPE_svbool_t || count == 2 || count == 4) register_tuple_type (count, type); } diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 0955a6976808..3d92a2a454fb 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -1074,9 +1074,9 @@ ;; ---- Moves of multiple predicates ;; ------------------------------------------------------------------------- -(define_insn_and_split "movvnx32bi" - [(set (match_operand:VNx32BI 0 "nonimmediate_operand") - (match_operand:VNx32BI 1 "aarch64_mov_operand"))] +(define_insn_and_split "mov<mode>" + [(set (match_operand:SVE_STRUCT_BI 0 "nonimmediate_operand") + (match_operand:SVE_STRUCT_BI 1 "aarch64_mov_operand"))] "TARGET_SVE" {@ [ cons: =0 , 1 ] [ Upa , Upa ] # @@ -1086,7 +1086,7 @@ "&& reload_completed" [(const_int 0)] { - aarch64_split_double_move (operands[0], operands[1], VNx16BImode); + aarch64_split_move (operands[0], operands[1], VNx16BImode); DONE; } ) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index f2b53475adbe..eaf1e1100ab4 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -969,7 +969,7 @@ pure_scalable_type_info::piece::get_rtx (unsigned int first_zr, if (num_zr > 0 && num_pr == 0) return gen_rtx_REG (mode, first_zr); - if (num_zr == 0 && num_pr <= 2) + if (num_zr == 0 && num_pr > 0) return gen_rtx_REG (mode, first_pr); gcc_unreachable (); @@ -1684,6 +1684,7 @@ aarch64_classify_vector_mode (machine_mode mode, bool any_target_p = false) return (TARGET_FLOAT || any_target_p) ? VEC_ADVSIMD : 0; case E_VNx32BImode: + case E_VNx64BImode: return TARGET_SVE ? VEC_SVE_PRED | VEC_STRUCT : 0; default: @@ -1815,13 +1816,15 @@ aarch64_array_mode (machine_mode mode, unsigned HOST_WIDE_INT nelems) { if (TARGET_SVE && GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) { - /* Use VNx32BI for pairs of predicates, but explicitly reject giving - a mode to other array sizes. Using integer modes requires a round - trip through memory and generates terrible code. */ + /* Use VNx32BI and VNx64BI for tuples of predicates, but explicitly + reject giving a mode to other array sizes. Using integer modes + requires a round trip through memory and generates terrible code. */ if (nelems == 1) return mode; if (mode == VNx16BImode && nelems == 2) return VNx32BImode; + if (mode == VNx16BImode && nelems == 4) + return VNx64BImode; return BLKmode; } @@ -2094,7 +2097,7 @@ aarch64_hard_regno_nregs (unsigned regno, machine_mode mode) case PR_REGS: case PR_LO_REGS: case PR_HI_REGS: - return mode == VNx32BImode ? 2 : 1; + return mode == VNx64BImode ? 4 : mode == VNx32BImode ? 2 : 1; case MOVEABLE_SYSREGS: case FFR_REGS: @@ -3270,31 +3273,30 @@ aarch64_emit_binop (rtx dest, optab binoptab, rtx op0, rtx op1) emit_move_insn (dest, tmp); } -/* Split a move from SRC to DST into two moves of mode SINGLE_MODE. */ +/* Split a move from SRC to DST into multiple moves of mode SINGLE_MODE. */ void -aarch64_split_double_move (rtx dst, rtx src, machine_mode single_mode) +aarch64_split_move (rtx dst, rtx src, machine_mode single_mode) { machine_mode mode = GET_MODE (dst); + auto npieces = exact_div (GET_MODE_SIZE (mode), + GET_MODE_SIZE (single_mode)).to_constant (); + auto_vec<rtx, 4> dst_pieces, src_pieces; - rtx dst0 = simplify_gen_subreg (single_mode, dst, mode, 0); - rtx dst1 = simplify_gen_subreg (single_mode, dst, mode, - GET_MODE_SIZE (single_mode)); - rtx src0 = simplify_gen_subreg (single_mode, src, mode, 0); - rtx src1 = simplify_gen_subreg (single_mode, src, mode, - GET_MODE_SIZE (single_mode)); - - /* At most one pairing may overlap. */ - if (reg_overlap_mentioned_p (dst0, src1)) + for (unsigned int i = 0; i < npieces; ++i) { - aarch64_emit_move (dst1, src1); - aarch64_emit_move (dst0, src0); + auto off = i * GET_MODE_SIZE (single_mode); + dst_pieces.safe_push (simplify_gen_subreg (single_mode, dst, mode, off)); + src_pieces.safe_push (simplify_gen_subreg (single_mode, src, mode, off)); } + + /* At most one pairing may overlap. */ + if (reg_overlap_mentioned_p (dst_pieces[0], src)) + for (unsigned int i = npieces; i-- > 0;) + aarch64_emit_move (dst_pieces[i], src_pieces[i]); else - { - aarch64_emit_move (dst0, src0); - aarch64_emit_move (dst1, src1); - } + for (unsigned int i = 0; i < npieces; ++i) + aarch64_emit_move (dst_pieces[i], src_pieces[i]); } /* Split a 128-bit move operation into two 64-bit move operations, @@ -3338,7 +3340,7 @@ aarch64_split_128bit_move (rtx dst, rtx src) } } - aarch64_split_double_move (dst, src, word_mode); + aarch64_split_move (dst, src, word_mode); } /* Return true if we should split a move from 128-bit value SRC @@ -13172,7 +13174,7 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode) case PR_REGS: case PR_LO_REGS: case PR_HI_REGS: - return mode == VNx32BImode ? 2 : 1; + return mode == VNx64BImode ? 4 : mode == VNx32BImode ? 2 : 1; case MOVEABLE_SYSREGS: case STACK_REG: diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 4942631aa950..b8924cdc74b8 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -556,6 +556,8 @@ ;; All SVE vector structure modes. (define_mode_iterator SVE_STRUCT [SVE_FULLx2 SVE_FULLx3 SVE_FULLx4]) +(define_mode_iterator SVE_STRUCT_BI [VNx32BI VNx64BI]) + ;; All SVE vector and structure modes. (define_mode_iterator SVE_ALL_STRUCT [SVE_ALL SVE_STRUCT]) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/create4_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/create4_1.c index b5ffd4e6aaf6..1d2ff4e871d3 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/create4_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/create4_1.c @@ -145,3 +145,13 @@ TEST_CREATE (create4_u64, svuint64x4_t, svuint64_t, TEST_CREATE (create4_f64, svfloat64x4_t, svfloat64_t, z0 = svcreate4_f64 (z5, z4, z7, z6), z0 = svcreate4 (z5, z4, z7, z6)) + +/* This is awkward to code-generate, so don't match a particular output. */ +TEST_CREATE_B (create4_b_0, svboolx4_t, + p0_res = svcreate4_b (p0, p1, p2, p3), + p0_res = svcreate4 (p0, p1, p2, p3)) + +/* This is awkward to code-generate, so don't match a particular output. */ +TEST_CREATE_B (create4_b_1, svboolx4_t, + p0_res = svcreate4_b (p3, p2, p1, p0), + p0_res = svcreate4 (p3, p2, p1, p0)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/get4_b.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/get4_b.c new file mode 100644 index 000000000000..146253aac3b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/get4_b.c @@ -0,0 +1,73 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** get4_b_p0_0: +** mov p0\.b, p4\.b +** ret +*/ +TEST_GET_B (get4_b_p0_0, svboolx4_t, + p0 = svget4_b (p4, 0), + p0 = svget4 (p4, 0)) + +/* +** get4_b_p0_1: +** mov p0\.b, p5\.b +** ret +*/ +TEST_GET_B (get4_b_p0_1, svboolx4_t, + p0 = svget4_b (p4, 1), + p0 = svget4 (p4, 1)) + +/* +** get4_b_p0_2: +** mov p0\.b, p6\.b +** ret +*/ +TEST_GET_B (get4_b_p0_2, svboolx4_t, + p0 = svget4_b (p4, 2), + p0 = svget4 (p4, 2)) + +/* +** get4_b_p0_3: +** mov p0\.b, p7\.b +** ret +*/ +TEST_GET_B (get4_b_p0_3, svboolx4_t, + p0 = svget4_b (p4, 3), + p0 = svget4 (p4, 3)) + +/* +** get4_b_p4_0: +** ret +*/ +TEST_GET_B (get4_b_p4_0, svboolx4_t, + p4_res = svget4_b (p4, 0), + p4_res = svget4 (p4, 0)) + +/* +** get4_b_p4_3: +** mov p4\.b, p7\.b +** ret +*/ +TEST_GET_B (get4_b_p4_3, svboolx4_t, + p4_res = svget4_b (p4, 3), + p4_res = svget4 (p4, 3)) + +/* +** get4_b_p5_0: +** mov p5\.b, p4\.b +** ret +*/ +TEST_GET_B (get4_b_p5_0, svboolx4_t, + p5_res = svget4_b (p4, 0), + p5_res = svget4 (p4, 0)) + +/* +** get4_b_p5_1: +** ret +*/ +TEST_GET_B (get4_b_p5_1, svboolx4_t, + p5_res = svget4_b (p4, 1), + p5_res = svget4 (p4, 1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/set4_b.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/set4_b.c new file mode 100644 index 000000000000..13efdf9bc2ed --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/set4_b.c @@ -0,0 +1,87 @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** set4_b_p8_0: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov p8\.b, p0\.b +** ret +*/ +TEST_SET_B (set4_b_p8_0, svboolx4_t, + p8 = svset4_b (p4, 0, p0), + p8 = svset4 (p4, 0, p0)) + +/* +** set4_b_p8_1: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov p9\.b, p0\.b +** ret +*/ +TEST_SET_B (set4_b_p8_1, svboolx4_t, + p8 = svset4_b (p4, 1, p0), + p8 = svset4 (p4, 1, p0)) + +/* +** set4_b_p8_2: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov p10\.b, p0\.b +** ret +*/ +TEST_SET_B (set4_b_p8_2, svboolx4_t, + p8 = svset4_b (p4, 2, p0), + p8 = svset4 (p4, 2, p0)) + +/* +** set4_b_p8_3: +** mov [^\n]+ +** mov [^\n]+ +** mov [^\n]+ +** mov p11\.b, p0\.b +** ret +*/ +TEST_SET_B (set4_b_p8_3, svboolx4_t, + p8 = svset4_b (p4, 3, p0), + p8 = svset4 (p4, 3, p0)) + +/* +** set4_b_p4_0: +** mov p4\.b, p12\.b +** ret +*/ +TEST_SET_B (set4_b_p4_0, svboolx4_t, + p4 = svset4_b (p4, 0, p12), + p4 = svset4 (p4, 0, p12)) + +/* +** set4_b_p4_1: +** mov p5\.b, p13\.b +** ret +*/ +TEST_SET_B (set4_b_p4_1, svboolx4_t, + p4 = svset4_b (p4, 1, p13), + p4 = svset4 (p4, 1, p13)) + +/* +** set4_b_p4_2: +** mov p6\.b, p12\.b +** ret +*/ +TEST_SET_B (set4_b_p4_2, svboolx4_t, + p4 = svset4_b (p4, 2, p12), + p4 = svset4 (p4, 2, p12)) + +/* +** set4_b_p4_3: +** mov p7\.b, p13\.b +** ret +*/ +TEST_SET_B (set4_b_p4_3, svboolx4_t, + p4 = svset4_b (p4, 3, p13), + p4 = svset4 (p4, 3, p13)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/test_sve_acle.h b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/test_sve_acle.h index 367024be8635..6c966a188de9 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/test_sve_acle.h +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/test_sve_acle.h @@ -543,6 +543,14 @@ return z0; \ } +#define TEST_UNDEF_B(NAME, TYPE, CODE) \ + PROTO (NAME, TYPE, (void)) \ + { \ + TYPE p0; \ + CODE; \ + return p0; \ + } + #define TEST_CREATE(NAME, TTYPE, ZTYPE, CODE1, CODE2) \ PROTO (NAME, TTYPE, (ZTYPE unused0, ZTYPE unused1, \ ZTYPE unused2, ZTYPE unused3, \ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef2_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef2_1.c index fe6c4c7c7d5c..2c520df99a36 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef2_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef2_1.c @@ -85,3 +85,10 @@ TEST_UNDEF (uint64, svuint64x2_t, */ TEST_UNDEF (float64, svfloat64x2_t, z0 = svundef2_f64 ()) + +/* +** bools: +** ret +*/ +TEST_UNDEF_B (bools, svboolx2_t, + p0 = svundef2_b ()) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef4_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef4_1.c index 4d6b86b04b59..9bda4d66e899 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef4_1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/undef4_1.c @@ -85,3 +85,10 @@ TEST_UNDEF (uint64, svuint64x4_t, */ TEST_UNDEF (float64, svfloat64x4_t, z0 = svundef4_f64 ()) + +/* +** bools: +** ret +*/ +TEST_UNDEF_B (bools, svboolx4_t, + p0 = svundef4_b ()) diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/create_5.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/create_5.c index bf3dd5d7514a..687327d7173b 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/create_5.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/create_5.c @@ -17,7 +17,7 @@ f1 (svint32x4_t *ptr, svbool_t pg, svint32_t s32, svfloat64_t f64, *ptr = svcreate4 (s32, x, s32, s32); /* { dg-error {passing 'int' to argument 2 of 'svcreate4', which expects an SVE type rather than a scalar} } */ *ptr = svcreate4 (x, s32, s32, s32); /* { dg-error {passing 'int' to argument 1 of 'svcreate4', which expects an SVE type rather than a scalar} } */ *ptr = svcreate4 (pg, s32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 2 of 'svcreate4', but argument 1 had type 'svbool_t'} } */ - *ptr = svcreate4 (pg, pg, pg, pg); /* { dg-error {'svcreate4' has no form that takes 'svbool_t' arguments} } */ + *ptr = svcreate4 (pg, pg, pg, pg); /* { dg-error {incompatible types when assigning to type 'svint32x4_t' from type 'svboolx4_t'} } */ *ptr = svcreate4 (s32, s32, s32, s32); *ptr = svcreate4 (f64, f64, f64, f64); /* { dg-error {incompatible types when assigning to type 'svint32x4_t' from type 'svfloat64x4_t'} } */ } diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/svboolx4_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/svboolx4_1.c new file mode 100644 index 000000000000..498c0fa40a8a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/svboolx4_1.c @@ -0,0 +1,117 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_sve.h> + +/* +** ret_p0: +** ret +*/ +svboolx4_t +ret_p0 (svboolx4_t p0) +{ + return p0; +} + +/* +** ret_p1: +** addvl sp, sp, #-1 +** str p4, \[sp\] +** mov p0\.b, p1\.b +** mov p1\.b, p2\.b +** mov p2\.b, p3\.b +** mov p3\.b, p4\.b +** ldr p4, \[sp\] +** addvl sp, sp, #1 +** ret +*/ +svboolx4_t +ret_p1 (void) +{ + register svboolx4_t p1 asm ("p1"); + asm volatile ("" : "=Upa" (p1)); + return p1; +} + +/* +** ret_mem: +** ( +** ldr p0, \[x0\] +** ldr p1, \[x0, #1, mul vl\] +** ldr p2, \[x0, #2, mul vl\] +** ldr p3, \[x0, #3, mul vl\] +** | +** ldr p3, \[x0, #3, mul vl\] +** ldr p2, \[x0, #2, mul vl\] +** ldr p1, \[x0, #1, mul vl\] +** ldr p0, \[x0\] +** ) +** ret +*/ +svboolx4_t +ret_mem (svboolx4_t p0, svboolx4_t mem) +{ + return mem; +} + +/* +** load: +** ( +** ldr p0, \[x0\] +** ldr p1, \[x0, #1, mul vl\] +** ldr p2, \[x0, #2, mul vl\] +** ldr p3, \[x0, #3, mul vl\] +** | +** ldr p3, \[x0, #2, mul vl\] +** ldr p2, \[x0, #3, mul vl\] +** ldr p1, \[x0, #1, mul vl\] +** ldr p0, \[x0\] +** ) +** ret +*/ +svboolx4_t +load (svboolx4_t *ptr) +{ + return *ptr; +} + +/* +** store: +** ( +** str p0, \[x0\] +** str p1, \[x0, #1, mul vl\] +** str p2, \[x0, #2, mul vl\] +** str p3, \[x0, #3, mul vl\] +** | +** str p3, \[x0, #3, mul vl\] +** str p2, \[x0, #2, mul vl\] +** str p1, \[x0, #1, mul vl\] +** str p0, \[x0\] +** ) +** ret +*/ +void +store (svboolx4_t p0, svboolx4_t *ptr) +{ + *ptr = p0; +} + +/* +** p0_to_p1: +** addvl sp, sp, #-1 +** str p4, \[sp\] +** mov p4\.b, p3\.b +** mov p3\.b, p2\.b +** mov p2\.b, p1\.b +** mov p1\.b, p0\.b +** ldr p4, \[sp\] +** addvl sp, sp, #1 +** ret +*/ +void +p0_to_p1 (svboolx4_t p0) +{ + register svboolx4_t p1 asm ("p1") = p0; + asm volatile ("" :: "Upa" (p1)); +}