Hi, I committed the attached patch to aarch64/sve-acle-branch that implements svlsl_wide.
Thanks, Prathamesh
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.c b/gcc/config/aarch64/aarch64-sve-builtins.c index f080a67ef00..0e3db669422 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.c +++ b/gcc/config/aarch64/aarch64-sve-builtins.c @@ -123,7 +123,10 @@ enum function_shape { The final argument must be an integer constant expression in the range [1, <t0>_BITS]. */ - SHAPE_shift_right_imm + SHAPE_shift_right_imm, + + /* sv<t0>_t svfoo_wide[_t0](sv<t0>_t, svuint64_t). */ + SHAPE_binary_wide }; /* Classifies an operation into "modes"; for example, to distinguish @@ -169,6 +172,7 @@ enum function { FUNC_svdup, FUNC_sveor, FUNC_svindex, + FUNC_svlsl_wide, FUNC_svmax, FUNC_svmad, FUNC_svmin, @@ -331,6 +335,7 @@ private: void sig_qq_0000 (const function_instance &, vec<tree> &); void sig_n_0000 (const function_instance &, vec<tree> &); void sig_qq_n_0000 (const function_instance &, vec<tree> &); + void sig_00i (const function_instance &, vec<tree> &); void sig_n_00i (const function_instance &, vec<tree> &); void apply_predication (const function_instance &, vec<tree> &); @@ -371,6 +376,7 @@ public: private: tree resolve_uniform (unsigned int); tree resolve_dot (); + tree resolve_binary_wide (); tree resolve_uniform_imm (unsigned int, unsigned int); bool check_first_vector_argument (unsigned int, unsigned int &, @@ -473,6 +479,7 @@ private: rtx expand_dup (); rtx expand_eor (); rtx expand_index (); + rtx expand_lsl_wide (); rtx expand_max (); rtx expand_min (); rtx expand_mad (unsigned int); @@ -581,6 +588,12 @@ static const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1] = { #define TYPES_all_unsigned(S, D) \ S (u8), S (u16), S (u32), S (u64) +/* _s8 _s16 _s32 + _u8 _u16 _u32. */ +#define TYPES_all_bhsi(S, D) \ + S (s8), S (s16), S (s32), \ + S (u8), S (u16), S (u32) + /* _s8 _s16 _s32 _s64 _u8 _u16 _u32 _u64. */ #define TYPES_all_integer(S, D) \ @@ -625,6 +638,7 @@ DEF_SVE_TYPES_ARRAY (all_pred); DEF_SVE_TYPES_ARRAY (all_unsigned); DEF_SVE_TYPES_ARRAY (all_signed); DEF_SVE_TYPES_ARRAY (all_float); +DEF_SVE_TYPES_ARRAY (all_bhsi); DEF_SVE_TYPES_ARRAY (all_integer); DEF_SVE_TYPES_ARRAY (all_data); DEF_SVE_TYPES_ARRAY (all_sdi_and_float); @@ -891,6 +905,11 @@ arm_sve_h_builder::build (const function_group &group) add_overloaded_functions (group, MODE_n); build_all (&arm_sve_h_builder::sig_n_00i, group, MODE_n); break; + + case SHAPE_binary_wide: + add_overloaded_functions (group, MODE_none); + build_all (&arm_sve_h_builder::sig_00i, group, MODE_none); + break; } } @@ -1028,6 +1047,17 @@ arm_sve_h_builder::sig_qq_n_0000 (const function_instance &instance, types.quick_push (instance.quarter_scalar_type (0)); } +/* Describe the signature "sv<t0>_t svfoo[_t0](sv<t0>_t, svuint64_t)" + for INSTANCE in TYPES. */ +void +arm_sve_h_builder::sig_00i (const function_instance& instance, + vec<tree> &types) +{ + for (unsigned i = 0; i < 2; ++i) + types.quick_push (instance.vector_type (0)); + types.quick_push (acle_vector_types[VECTOR_TYPE_svuint64_t]); +} + /* Describe the signature "sv<t0>_t svfoo[_n_t0](sv<t0>_t, uint64_t)" for INSTANCE in TYPES. */ void @@ -1190,6 +1220,7 @@ arm_sve_h_builder::get_attributes (const function_instance &instance) case FUNC_svdup: case FUNC_sveor: case FUNC_svindex: + case FUNC_svlsl_wide: case FUNC_svmax: case FUNC_svmad: case FUNC_svmin: @@ -1246,6 +1277,7 @@ arm_sve_h_builder::get_explicit_types (function_shape shape) case SHAPE_ternary_opt_n: case SHAPE_ternary_qq_opt_n: case SHAPE_shift_right_imm: + case SHAPE_binary_wide: return 0; } gcc_unreachable (); @@ -1325,6 +1357,8 @@ function_resolver::resolve () case SHAPE_binary_scalar: case SHAPE_inherent: break; + case SHAPE_binary_wide: + return resolve_binary_wide (); } gcc_unreachable (); } @@ -1385,6 +1419,22 @@ function_resolver::resolve_dot () return require_form (m_rfn.instance.mode, get_type_suffix (type)); } +/* Resolve a function that has SHAPE_binary_wide. */ + +tree +function_resolver::resolve_binary_wide () +{ + unsigned i, nargs; + vector_type type; + + if (!check_first_vector_argument (2, i, nargs, type) + || !require_matching_type (i, type) + || !check_argument (i + 1, VECTOR_TYPE_svuint64_t)) + return error_mark_node; + + return require_form (m_rfn.instance.mode, get_type_suffix (type)); +} + /* Like resolve_uniform, except that the final NIMM arguments have type uint64_t and must be integer constant expressions. */ tree @@ -1653,6 +1703,7 @@ function_checker::check () case SHAPE_binary_scalar: case SHAPE_ternary_opt_n: case SHAPE_ternary_qq_opt_n: + case SHAPE_binary_wide: return true; } gcc_unreachable (); @@ -1842,6 +1893,7 @@ gimple_folder::fold () case FUNC_svdup: case FUNC_sveor: case FUNC_svindex: + case FUNC_svlsl_wide: case FUNC_svmax: case FUNC_svmad: case FUNC_svmin: @@ -1947,6 +1999,9 @@ function_expander::expand () case FUNC_svindex: return expand_index (); + case FUNC_svlsl_wide: + return expand_lsl_wide (); + case FUNC_svmax: return expand_max (); @@ -2114,6 +2169,24 @@ function_expander::expand_index () return expand_via_unpred_direct_optab (vec_series_optab); } +/* Expand a call to svlsl_wide. */ +rtx +function_expander::expand_lsl_wide () +{ + machine_mode mode = get_mode (0); + + if (m_fi.pred == PRED_x) + { + insn_code icode = code_for_aarch64_pred (UNSPEC_ASHIFT_WIDE, mode); + return expand_via_pred_x_insn (icode); + } + else + { + insn_code icode = code_for_cond (UNSPEC_ASHIFT_WIDE, mode); + return expand_via_pred_insn (icode); + } +} + /* Expand a call to svmax. */ rtx function_expander::expand_max () diff --git a/gcc/config/aarch64/aarch64-sve-builtins.def b/gcc/config/aarch64/aarch64-sve-builtins.def index 0977d4a2de6..7981261a295 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.def +++ b/gcc/config/aarch64/aarch64-sve-builtins.def @@ -71,6 +71,7 @@ DEF_SVE_FUNCTION (svdot, ternary_qq_opt_n, sdi, none) DEF_SVE_FUNCTION (svdup, unary_n, all_data, mxznone) DEF_SVE_FUNCTION (sveor, binary_opt_n, all_integer, mxz) DEF_SVE_FUNCTION (svindex, binary_scalar, all_data, none) +DEF_SVE_FUNCTION (svlsl_wide, binary_wide, all_bhsi, mxz) DEF_SVE_FUNCTION (svmax, binary_opt_n, all_data, mxz) DEF_SVE_FUNCTION (svmin, binary_opt_n, all_data, mxz) DEF_SVE_FUNCTION (svmad, ternary_opt_n, all_data, mxz) diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index cbf9a7fb0bf..d48028931f3 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -1549,6 +1549,65 @@ } ) +(define_insn "@aarch64_pred_<sve_int_op><mode>" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=w, ?&w") + (unspec:SVE_BHSI + [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl") + (unspec:SVE_BHSI + [(match_operand:SVE_BHSI 2 "register_operand" "0, w") + (match_operand:VNx2DI 3 "register_operand" "w, w")] + SVE_ASHIFT_WIDE)] + UNSPEC_MERGE_PTRUE))] + "TARGET_SVE" + "@ + <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d + movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d" + [(set_attr "movprfx" "*,yes")] +) + +(define_expand "@cond_<sve_int_op><mode>" + [(set (match_operand:SVE_BHSI 0 "register_operand") + (unspec:SVE_BHSI + [(match_operand:<VPRED> 1 "register_operand") + (unspec:SVE_BHSI + [(match_operand:SVE_BHSI 2 "register_operand") + (match_operand:VNx2DI 3 "register_operand")] + SVE_ASHIFT_WIDE) + (match_operand:SVE_BHSI 4 "aarch64_simd_reg_or_zero")] + UNSPEC_SEL))] + "TARGET_SVE" +) + +(define_insn "*cond<sve_int_op><mode>_m" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=w, ?&w") + (unspec:SVE_BHSI + [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl") + (unspec:SVE_BHSI + [(match_operand:SVE_BHSI 2 "register_operand" "0, w") + (match_operand:VNx2DI 3 "register_operand" "w, w")] + SVE_ASHIFT_WIDE) + (match_dup 2)] + UNSPEC_SEL))] + "TARGET_SVE" + "@ + <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d + movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d" + [(set_attr "movprfx" "*, yes")]) + +(define_insn "*cond<sve_int_op><mode>_z" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=&w") + (unspec:SVE_BHSI + [(match_operand:<VPRED> 1 "register_operand" "Upl") + (unspec:SVE_BHSI + [(match_operand:SVE_BHSI 2 "register_operand" "0w") + (match_operand:VNx2DI 3 "register_operand" "w")] + SVE_ASHIFT_WIDE) + (match_operand:SVE_BHSI 4 "aarch64_simd_imm_zero")] + UNSPEC_SEL))] + "TARGET_SVE" + "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d" + [(set_attr "movprfx" "yes")]) + ;; Test all bits of operand 1. Operand 0 is a GP that is known to hold PTRUE. ;; ;; Using UNSPEC_PTEST_PTRUE allows combine patterns to assume that the GP diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 14d6811310a..5baa9d53448 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -490,6 +490,7 @@ UNSPEC_COND_GE ; Used in aarch64-sve.md. UNSPEC_COND_GT ; Used in aarch64-sve.md. UNSPEC_LASTB ; Used in aarch64-sve.md. + UNSPEC_ASHIFT_WIDE ; Used in aarch64-sve.md. ]) ;; ------------------------------------------------------------------ @@ -1616,6 +1617,8 @@ [(UNSPECV_ATOMIC_LDOP_OR "set") (UNSPECV_ATOMIC_LDOP_BIC "clr") (UNSPECV_ATOMIC_LDOP_XOR "eor") (UNSPECV_ATOMIC_LDOP_PLUS "add")]) +(define_int_iterator SVE_ASHIFT_WIDE [UNSPEC_ASHIFT_WIDE]) + ;; ------------------------------------------------------------------- ;; Int Iterators Attributes. ;; ------------------------------------------------------------------- @@ -1880,6 +1883,8 @@ (UNSPEC_COND_GE "ge") (UNSPEC_COND_GT "gt")]) +(define_int_attr sve_int_op [(UNSPEC_ASHIFT_WIDE "lsl")]) + (define_int_attr sve_fp_op [(UNSPEC_COND_MUL "fmul") (UNSPEC_COND_DIV "fdiv") (UNSPEC_COND_FABS "fabs") diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 7eeec767445..e9d5dbe4fd1 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1996,6 +1996,7 @@ process_alt_operands (int only_alternative) if (!TEST_BIT (preferred, nalt)) continue; + bool matching_early_clobber[MAX_RECOG_OPERANDS]; curr_small_class_check++; overall = losers = addr_losers = 0; static_reject = reject = reload_nregs = reload_sum = 0; @@ -2007,6 +2008,7 @@ process_alt_operands (int only_alternative) fprintf (lra_dump_file, " Staticly defined alt reject+=%d\n", inc); static_reject += inc; + matching_early_clobber[nop] = 0; } reject += static_reject; early_clobbered_regs_num = 0; @@ -2202,7 +2204,11 @@ process_alt_operands (int only_alternative) " %d Matching earlyclobber alt:" " reject--\n", nop); - reject--; + if (!matching_early_clobber[m]) + { + reject--; + matching_early_clobber[m] = 1; + } } /* Otherwise we prefer no matching alternatives because it gives more freedom @@ -2948,15 +2954,11 @@ process_alt_operands (int only_alternative) curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = last_conflict_j; losers++; - /* Early clobber was already reflected in REJECT. */ - lra_assert (reject > 0); if (lra_dump_file != NULL) fprintf (lra_dump_file, " %d Conflict early clobber reload: reject--\n", i); - reject--; - overall += LRA_LOSER_COST_FACTOR - 1; } else { @@ -2980,17 +2982,21 @@ process_alt_operands (int only_alternative) } curr_alt_win[i] = curr_alt_match_win[i] = false; losers++; - /* Early clobber was already reflected in REJECT. */ - lra_assert (reject > 0); if (lra_dump_file != NULL) fprintf (lra_dump_file, " %d Matched conflict early clobber reloads: " "reject--\n", i); + } + /* Early clobber was already reflected in REJECT. */ + if (!matching_early_clobber[i]) + { + lra_assert (reject > 0); reject--; - overall += LRA_LOSER_COST_FACTOR - 1; + matching_early_clobber[i] = 1; } + overall += LRA_LOSER_COST_FACTOR - 1; } if (lra_dump_file != NULL) fprintf (lra_dump_file, " alt=%d,overall=%d,losers=%d,rld_nregs=%d\n", diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/lsl_wide_1.C b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/lsl_wide_1.C new file mode 100644 index 00000000000..e0084678fb3 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/lsl_wide_1.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +#pragma GCC aarch64 "arm_sve.h" + +svuint8_t +f1 (svbool_t pg, svuint8_t x, svint8_t w, svuint64_t y) +{ + svlsl_wide_u8_x (pg, x, x); /* { dg-error "cannot convert 'svuint8_t' to 'svuint64_t'" } */ + svlsl_wide_u8_x (pg, x); /* { dg-error {too few arguments to function 'svuint8_t svlsl_wide_u8_x\(svbool_t, svuint8_t, svuint64_t\)'} } */ + svlsl_wide_u8_x (pg, x, y, x); /* { dg-error {too many arguments to function 'svuint8_t svlsl_wide_u8_x\(svbool_t, svuint8_t, svuint64_t\)'} } */ + return svlsl_wide_s8_x (pg, w, y); /* { dg-error {cannot convert 'svint8_t' to 'svuint8_t' in return} } */ +} diff --git a/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/lsl_wide_2.C b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/lsl_wide_2.C new file mode 100644 index 00000000000..8df049b6558 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve-acle/general-c++/lsl_wide_2.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#pragma GCC aarch64 "arm_sve.h" + +void +f1 (svbool_t pg, svuint8_t x, svuint64_t y) +{ + svlsl_wide_x (pg, x); /* { dg-error {no matching function for call to 'svlsl_wide_x\(svbool_t&, svuint8_t&\)'} } */ + svlsl_wide_x (pg, x, x, x, x); /* { dg-error {no matching function for call to 'svlsl_wide_x\(svbool_t&, svuint8_t&, svuint8_t&, svuint8_t&, svuint8_t&\)'} } */ + svlsl_wide_x (x, x, y); /* { dg-error {no matching function for call to 'svlsl_wide_x\(svuint8_t&, svuint8_t&, svuint64_t&\)'} } */ + svlsl_wide_x (pg, 1, y); /* { dg-error {no matching function for call to 'svlsl_wide_x\(svbool_t&, int, svuint64_t&\)'} } */ + svlsl_wide_x (pg, x, x); /* { dg-error {no matching function for call to 'svlsl_wide_x\(svbool_t&, svuint8_t&, svuint8_t&\)'} } */ + svlsl_wide_x (pg, y, y); /* { dg-error {no matching function for call to 'svlsl_wide_x\(svbool_t&, svuint64_t&, svuint64_t&\)'} } */ +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s16.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s16.c new file mode 100644 index 00000000000..328b5973c2f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s16.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** lsl_wide_s16_m_tied1: +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s16_m_tied1, svint16_t, + z0 = svlsl_wide_s16_m (p0, z0, z16), + z0 = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_s16_m_untied: +** movprfx z0, z1 +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s16_m_untied, svint16_t, + z0 = svlsl_wide_s16_m (p0, z1, z16), + z0 = svlsl_wide_m (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s16_m_tied2, svint16_t, + z16_res = svlsl_wide_s16_m (p0, z0, z16), + z16_res = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_s16_z_tied1: +** movprfx z0\.h, p0/z, z0\.h +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s16_z_tied1, svint16_t, + z0 = svlsl_wide_s16_z (p0, z0, z16), + z0 = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_s16_z_untied: +** movprfx z0\.h, p0/z, z1\.h +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s16_z_untied, svint16_t, + z0 = svlsl_wide_s16_z (p0, z1, z16), + z0 = svlsl_wide_z (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s16_z_tied2, svint16_t, + z16_res = svlsl_wide_s16_z (p0, z0, z16), + z16_res = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_s16_x_tied1: +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s16_x_tied1, svint16_t, + z0 = svlsl_wide_s16_x (p0, z0, z16), + z0 = svlsl_wide_x (p0, z0, z16)) + +/* +** lsl_wide_s16_x_untied: +** movprfx z0, z1 +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s16_x_untied, svint16_t, + z0 = svlsl_wide_s16_x (p0, z1, z16), + z0 = svlsl_wide_x (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s16_x_tied2, svint16_t, + z16_res = svlsl_wide_s16_x (p0, z0, z16), + z16_res = svlsl_wide_x (p0, z0, z16)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s32.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s32.c new file mode 100644 index 00000000000..304b740f015 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s32.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** lsl_wide_s32_m_tied1: +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s32_m_tied1, svint32_t, + z0 = svlsl_wide_s32_m (p0, z0, z16), + z0 = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_s32_m_untied: +** movprfx z0, z1 +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s32_m_untied, svint32_t, + z0 = svlsl_wide_s32_m (p0, z1, z16), + z0 = svlsl_wide_m (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s32_m_tied2, svint32_t, + z16_res = svlsl_wide_s32_m (p0, z0, z16), + z16_res = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_s32_z_tied1: +** movprfx z0\.s, p0/z, z0\.s +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s32_z_tied1, svint32_t, + z0 = svlsl_wide_s32_z (p0, z0, z16), + z0 = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_s32_z_untied: +** movprfx z0\.s, p0/z, z1\.s +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s32_z_untied, svint32_t, + z0 = svlsl_wide_s32_z (p0, z1, z16), + z0 = svlsl_wide_z (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s32_z_tied2, svint32_t, + z16_res = svlsl_wide_s32_z (p0, z0, z16), + z16_res = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_s32_x_tied1: +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s32_x_tied1, svint32_t, + z0 = svlsl_wide_s32_x (p0, z0, z16), + z0 = svlsl_wide_x (p0, z0, z16)) + +/* +** lsl_wide_s32_x_untied: +** movprfx z0, z1 +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s32_x_untied, svint32_t, + z0 = svlsl_wide_s32_x (p0, z1, z16), + z0 = svlsl_wide_x (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s32_x_tied2, svint32_t, + z16_res = svlsl_wide_s32_x (p0, z0, z16), + z16_res = svlsl_wide_x (p0, z0, z16)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s8.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s8.c new file mode 100644 index 00000000000..094ab154c34 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_s8.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** lsl_wide_s8_m_tied1: +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s8_m_tied1, svint8_t, + z0 = svlsl_wide_s8_m (p0, z0, z16), + z0 = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_s8_m_untied: +** movprfx z0, z1 +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s8_m_untied, svint8_t, + z0 = svlsl_wide_s8_m (p0, z1, z16), + z0 = svlsl_wide_m (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s8_m_tied2, svint8_t, + z16_res = svlsl_wide_s8_m (p0, z0, z16), + z16_res = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_s8_z_tied1: +** movprfx z0\.b, p0/z, z0\.b +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s8_z_tied1, svint8_t, + z0 = svlsl_wide_s8_z (p0, z0, z16), + z0 = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_s8_z_untied: +** movprfx z0\.b, p0/z, z1\.b +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s8_z_untied, svint8_t, + z0 = svlsl_wide_s8_z (p0, z1, z16), + z0 = svlsl_wide_z (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s8_z_tied2, svint8_t, + z16_res = svlsl_wide_s8_z (p0, z0, z16), + z16_res = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_s8_x_tied1: +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s8_x_tied1, svint8_t, + z0 = svlsl_wide_s8_x (p0, z0, z16), + z0 = svlsl_wide_x (p0, z0, z16)) + +/* +** lsl_wide_s8_x_untied: +** movprfx z0, z1 +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_s8_x_untied, svint8_t, + z0 = svlsl_wide_s8_x (p0, z1, z16), + z0 = svlsl_wide_x (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_s8_x_tied2, svint8_t, + z16_res = svlsl_wide_s8_x (p0, z0, z16), + z16_res = svlsl_wide_x (p0, z0, z16)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u16.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u16.c new file mode 100644 index 00000000000..4f4ac169d74 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u16.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** lsl_wide_u16_m_tied1: +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u16_m_tied1, svuint16_t, + z0 = svlsl_wide_u16_m (p0, z0, z16), + z0 = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_u16_m_untied: +** movprfx z0, z1 +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u16_m_untied, svuint16_t, + z0 = svlsl_wide_u16_m (p0, z1, z16), + z0 = svlsl_wide_m (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u16_m_tied2, svuint16_t, + z16_res = svlsl_wide_u16_m (p0, z0, z16), + z16_res = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_u16_z_tied1: +** movprfx z0\.h, p0/z, z0\.h +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u16_z_tied1, svuint16_t, + z0 = svlsl_wide_u16_z (p0, z0, z16), + z0 = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_u16_z_untied: +** movprfx z0\.h, p0/z, z1\.h +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u16_z_untied, svuint16_t, + z0 = svlsl_wide_u16_z (p0, z1, z16), + z0 = svlsl_wide_z (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u16_z_tied2, svuint16_t, + z16_res = svlsl_wide_u16_z (p0, z0, z16), + z16_res = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_u16_x_tied1: +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u16_x_tied1, svuint16_t, + z0 = svlsl_wide_u16_x (p0, z0, z16), + z0 = svlsl_wide_x (p0, z0, z16)) + +/* +** lsl_wide_u16_x_untied: +** movprfx z0, z1 +** lsl z0\.h, p0/m, z0\.h, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u16_x_untied, svuint16_t, + z0 = svlsl_wide_u16_x (p0, z1, z16), + z0 = svlsl_wide_x (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u16_x_tied2, svuint16_t, + z16_res = svlsl_wide_u16_x (p0, z0, z16), + z16_res = svlsl_wide_x (p0, z0, z16)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u32.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u32.c new file mode 100644 index 00000000000..163abc8862d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u32.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** lsl_wide_u32_m_tied1: +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u32_m_tied1, svuint32_t, + z0 = svlsl_wide_u32_m (p0, z0, z16), + z0 = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_u32_m_untied: +** movprfx z0, z1 +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u32_m_untied, svuint32_t, + z0 = svlsl_wide_u32_m (p0, z1, z16), + z0 = svlsl_wide_m (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u32_m_tied2, svuint32_t, + z16_res = svlsl_wide_u32_m (p0, z0, z16), + z16_res = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_u32_z_tied1: +** movprfx z0\.s, p0/z, z0\.s +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u32_z_tied1, svuint32_t, + z0 = svlsl_wide_u32_z (p0, z0, z16), + z0 = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_u32_z_untied: +** movprfx z0\.s, p0/z, z1\.s +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u32_z_untied, svuint32_t, + z0 = svlsl_wide_u32_z (p0, z1, z16), + z0 = svlsl_wide_z (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u32_z_tied2, svuint32_t, + z16_res = svlsl_wide_u32_z (p0, z0, z16), + z16_res = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_u32_x_tied1: +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u32_x_tied1, svuint32_t, + z0 = svlsl_wide_u32_x (p0, z0, z16), + z0 = svlsl_wide_x (p0, z0, z16)) + +/* +** lsl_wide_u32_x_untied: +** movprfx z0, z1 +** lsl z0\.s, p0/m, z0\.s, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u32_x_untied, svuint32_t, + z0 = svlsl_wide_u32_x (p0, z1, z16), + z0 = svlsl_wide_x (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u32_x_tied2, svuint32_t, + z16_res = svlsl_wide_u32_x (p0, z0, z16), + z16_res = svlsl_wide_x (p0, z0, z16)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u8.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u8.c new file mode 100644 index 00000000000..505b8f3b04c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/asm/lsl_wide_u8.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +/* +** lsl_wide_u8_m_tied1: +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u8_m_tied1, svuint8_t, + z0 = svlsl_wide_u8_m (p0, z0, z16), + z0 = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_u8_m_untied: +** movprfx z0, z1 +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u8_m_untied, svuint8_t, + z0 = svlsl_wide_u8_m (p0, z1, z16), + z0 = svlsl_wide_m (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u8_m_tied2, svuint8_t, + z16_res = svlsl_wide_u8_m (p0, z0, z16), + z16_res = svlsl_wide_m (p0, z0, z16)) + +/* +** lsl_wide_u8_z_tied1: +** movprfx z0\.b, p0/z, z0\.b +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u8_z_tied1, svuint8_t, + z0 = svlsl_wide_u8_z (p0, z0, z16), + z0 = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_u8_z_untied: +** movprfx z0\.b, p0/z, z1\.b +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u8_z_untied, svuint8_t, + z0 = svlsl_wide_u8_z (p0, z1, z16), + z0 = svlsl_wide_z (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u8_z_tied2, svuint8_t, + z16_res = svlsl_wide_u8_z (p0, z0, z16), + z16_res = svlsl_wide_z (p0, z0, z16)) + +/* +** lsl_wide_u8_x_tied1: +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u8_x_tied1, svuint8_t, + z0 = svlsl_wide_u8_x (p0, z0, z16), + z0 = svlsl_wide_x (p0, z0, z16)) + +/* +** lsl_wide_u8_x_untied: +** movprfx z0, z1 +** lsl z0\.b, p0/m, z0\.b, z16\.d +** ret +*/ +TEST_WIDE_Z (lsl_wide_u8_x_untied, svuint8_t, + z0 = svlsl_wide_u8_x (p0, z1, z16), + z0 = svlsl_wide_x (p0, z1, z16)) + +/* Bad RA choice: no preferred output sequence. */ +TEST_WIDE_Z (lsl_wide_u8_x_tied2, svuint8_t, + z16_res = svlsl_wide_u8_x (p0, z0, z16), + z16_res = svlsl_wide_x (p0, z0, z16)) 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 07b110c8ad5..888f8eacfd1 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 @@ -120,6 +120,9 @@ BIND_RESULT_ZS_FROM_Z16; \ } +#define TEST_WIDE_Z(NAME, TYPE, CODE1, CODE2) \ + TEST_DUAL_Z (NAME, TYPE, svuint64_t, CODE1, CODE2) + #define TEST_UNIFORM_ZS(NAME, ZTYPE, STYPE, CODE1, CODE2) \ START (NAME) \ { \ diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/lsl_wide_1.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/lsl_wide_1.c new file mode 100644 index 00000000000..27d7581c6d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/lsl_wide_1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +#pragma GCC aarch64 "arm_sve.h" + +svuint8_t +f1 (svbool_t pg, svuint8_t x, svint8_t w, svuint64_t y) +{ + svlsl_wide_u8_x (pg, x, x); /* { dg-error "incompatible type for argument 3 of 'svlsl_wide_u8_x'" } */ + svlsl_wide_u8_x (pg, x); /* { dg-error "too few arguments to function 'svlsl_wide_u8_x'" } */ + svlsl_wide_u8_x (pg, x, y, x); /* { dg-error "too many arguments to function 'svlsl_wide_u8_x'" } */ + return svlsl_wide_s8_x (pg, w, y); /* { dg-error "incompatible types when returning type 'svint8_t' but 'svuint8_t' was expected" } */ +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/lsl_wide_2.c b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/lsl_wide_2.c new file mode 100644 index 00000000000..c0a609b1ca3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve-acle/general-c/lsl_wide_2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#pragma GCC aarch64 "arm_sve.h" + +void +f1 (svbool_t pg, svuint8_t x, svuint64_t y) +{ + svlsl_wide_x (pg, x); /* { dg-error "too few arguments to function 'svlsl_wide_x'" } */ + svlsl_wide_x (pg, x, x, x, x); /* { dg-error "too many arguments to function 'svlsl_wide_x'" } */ + svlsl_wide_x (x, x, y); /* { dg-error "passing 'svuint8_t' to argument 1 of 'svlsl_wide_x', which expects 'svbool_t'" } */ + svlsl_wide_x (pg, 1, y); /* { dg-error "passing 'int' to argument 2 of 'svlsl_wide_x', which expects an SVE vector type" } */ + svlsl_wide_x (pg, x, x); /* { dg-error "passing 'svuint8_t' to argument 3 of 'svlsl_wide_x', which expects 'svuint64_t'" } */ + svlsl_wide_x (pg, y, y); /* { dg-error "'svlsl_wide_x' has no form that takes 'svuint64_t' arguments" } */ +}