Message ID | 20230912020825.12497-1-xuli1@eswincomputing.com |
---|---|
State | New |
Headers | show |
Series | RISC-V: Add vcreate intrinsics for RVV tuple types | expand |
Thanks for support it. LGTM from my side. Wait for kito's more comments. juzhe.zhong@rivai.ai From: Li Xu Date: 2023-09-12 10:08 To: gcc-patches CC: kito.cheng; palmer; juzhe.zhong; pan2.li; gaofei; wangfeng; xuli Subject: [PATCH] RISC-V: Add vcreate intrinsics for RVV tuple types From: xuli <xuli1@eswincomputing.com> gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc (class vcreate): (BASE): New class. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vcreate): Add vcreate support. * config/riscv/riscv-vector-builtins-shapes.cc (struct vcreate_def): Ditto. (SHAPE): Ditto. * config/riscv/riscv-vector-builtins-shapes.h: Ditto. * config/riscv/riscv-vector-builtins.cc: Add args type. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/tuple_create.c: New test. --- .../riscv/riscv-vector-builtins-bases.cc | 40 ++++++ .../riscv/riscv-vector-builtins-bases.h | 1 + .../riscv/riscv-vector-builtins-functions.def | 1 + .../riscv/riscv-vector-builtins-shapes.cc | 50 +++++++ .../riscv/riscv-vector-builtins-shapes.h | 1 + gcc/config/riscv/riscv-vector-builtins.cc | 12 ++ .../gcc.target/riscv/rvv/base/tuple_create.c | 123 ++++++++++++++++++ 7 files changed, 228 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 8e679f72392..be3df2c1ea2 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -1824,6 +1824,44 @@ public: } }; +class vcreate : public function_base +{ +public: + gimple *fold (gimple_folder &f) const override + { + unsigned int nargs = gimple_call_num_args (f.call); + tree lhs_type = TREE_TYPE (f.lhs); + + /* Replace the call with a clobber of the result (to prevent it from + becoming upwards exposed) followed by stores into each individual + vector of tuple. + + The fold routines expect the replacement statement to have the + same lhs as the original call, so return the clobber statement + rather than the final vector store. */ + gassign *clobber = gimple_build_assign (f.lhs, build_clobber (lhs_type)); + + for (unsigned int i = nargs; i-- > 0; ) + { + tree rhs_vector = gimple_call_arg (f.call, i); + tree field = tuple_type_field (TREE_TYPE (f.lhs)); + tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field), + unshare_expr (f.lhs), field, NULL_TREE); + tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), + lhs_array, size_int (i), + NULL_TREE, NULL_TREE); + gassign *assign = gimple_build_assign (lhs_vector, rhs_vector); + gsi_insert_after (f.gsi, assign, GSI_SAME_STMT); + } + return clobber; + } + + rtx expand (function_expander &e) const override + { + return NULL_RTX; + } +}; + class read_vl : public function_base { public: @@ -2285,6 +2323,7 @@ static CONSTEXPR const vlmul_ext vlmul_ext_obj; static CONSTEXPR const vlmul_trunc vlmul_trunc_obj; static CONSTEXPR const vset vset_obj; static CONSTEXPR const vget vget_obj; +static CONSTEXPR const vcreate vcreate_obj; static CONSTEXPR const read_vl read_vl_obj; static CONSTEXPR const vleff vleff_obj; static CONSTEXPR const vlenb vlenb_obj; @@ -2546,6 +2585,7 @@ BASE (vlmul_ext) BASE (vlmul_trunc) BASE (vset) BASE (vget) +BASE (vcreate) BASE (read_vl) BASE (vleff) BASE (vlenb) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index 69d4562091f..131041ea66f 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -267,6 +267,7 @@ extern const function_base *const vlmul_ext; extern const function_base *const vlmul_trunc; extern const function_base *const vset; extern const function_base *const vget; +extern const function_base *const vcreate; extern const function_base *const read_vl; extern const function_base *const vleff; extern const function_base *const vlenb; diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def index 3ce06dc60b7..18ed2c2b8f6 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -621,6 +621,7 @@ DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_lmul4_x2_ops) // Tuple types DEF_RVV_FUNCTION (vset, vset, none_preds, all_v_vset_tuple_ops) DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_tuple_ops) +DEF_RVV_FUNCTION (vcreate, vcreate, none_preds, all_v_vcreate_tuple_ops) DEF_RVV_FUNCTION (vlseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ops) DEF_RVV_FUNCTION (vsseg, seg_loadstore, none_m_preds, tuple_v_scalar_ptr_ops) DEF_RVV_FUNCTION (vlsseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ptrdiff_ops) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index f8fdec863e6..0bda934ae16 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -706,6 +706,55 @@ struct vget_def : public misc_def } }; +/* vcreate_def class. */ +struct vcreate_def : public build_base +{ + void build (function_builder &b, + const function_group_info &group) const override + { + for (unsigned int vec_type_idx = 0; + group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES; + ++vec_type_idx) + { + auto_vec<tree, 8> argument_types; + function_instance function_instance (group.base_name, *group.base, + *group.shape, + group.ops_infos.types[vec_type_idx], + group.preds[0], &group.ops_infos); + + tree return_type = group.ops_infos.ret.get_tree_type ( + group.ops_infos.types[vec_type_idx].index); + + if (!return_type) + continue; + + machine_mode mode = TYPE_MODE (return_type); + unsigned int nf = get_nf (mode); + + for (unsigned int i = 0; i < nf; i++) + argument_types.quick_push ( + function_instance.op_info->args[0].get_tree_type ( + function_instance.type.index)); + + b.add_unique_function (function_instance, (*group.shape), return_type, + argument_types); + } + } + + char *get_name (function_builder &b, const function_instance &instance, + bool overloaded_p) const override + { + if (overloaded_p) + return nullptr; + b.append_base_name (instance.base_name); + b.append_name (operand_suffixes[instance.op_info->op]); + vector_type_index ret_type_idx + = instance.op_info->ret.get_function_type_index (instance.type.index); + b.append_name (type_suffixes[ret_type_idx].vector); + return b.finish_name (); + } +}; + /* read_vl_def class. */ struct read_vl_def : public function_shape { @@ -942,6 +991,7 @@ SHAPE(vundefined, vundefined) SHAPE(misc, misc) SHAPE(vset, vset) SHAPE(vget, vget) +SHAPE(vcreate, vcreate) SHAPE(read_vl, read_vl) SHAPE(fault_load, fault_load) SHAPE(vlenb, vlenb) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h index 92eb8bc9d71..df9884bb572 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -45,6 +45,7 @@ extern const function_shape *const vundefined; extern const function_shape *const misc; extern const function_shape *const vset; extern const function_shape *const vget; +extern const function_shape *const vcreate; extern const function_shape *const read_vl; extern const function_shape *const fault_load; extern const function_shape *const vlenb; diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 6d99f970ead..5318651138a 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -873,6 +873,10 @@ static CONSTEXPR const rvv_arg_type_info tuple_vset_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; +/* A list of args for vector_type func (vector_type) function. */ +static CONSTEXPR const rvv_arg_type_info tuple_vcreate_args[] + = {rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; + /* A list of none preds that will be registered for intrinsic functions. */ static CONSTEXPR const predication_type_index none_preds[] = {PRED_TYPE_none, NUM_PRED_TYPES}; @@ -2497,6 +2501,14 @@ static CONSTEXPR const rvv_op_info tuple_v_scalar_const_ptr_size_ptr_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ scalar_const_ptr_size_ptr_args /* Args */}; +/* A static operand information for vector_type func (vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info all_v_vcreate_tuple_ops + = {tuple_ops, /* Types */ + OP_TYPE_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + tuple_vcreate_args /* Args */}; + /* A list of all RVV base function types. */ static CONSTEXPR const function_type_info function_types[] = { #define DEF_RVV_TYPE_INDEX( \ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c new file mode 100644 index 00000000000..b252b2f3cd4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c @@ -0,0 +1,123 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat16mf4x2_t test_vcreate_v_f16mf4x2(vfloat16mf4_t v0, vfloat16mf4_t v1) { + return __riscv_vcreate_v_f16mf4x2(v0, v1); +} + +vfloat16mf4x3_t test_vcreate_v_f16mf4x3(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2) { + return __riscv_vcreate_v_f16mf4x3(v0, v1, v2); +} + +vfloat16mf4x4_t test_vcreate_v_f16mf4x4(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3) { + return __riscv_vcreate_v_f16mf4x4(v0, v1, v2, v3); +} + +vfloat16mf4x5_t test_vcreate_v_f16mf4x5(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4) { + return __riscv_vcreate_v_f16mf4x5(v0, v1, v2, v3, v4); +} + +vfloat16mf4x6_t test_vcreate_v_f16mf4x6(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5) { + return __riscv_vcreate_v_f16mf4x6(v0, v1, v2, v3, v4, v5); +} + +vfloat16mf4x7_t test_vcreate_v_f16mf4x7(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6) { + return __riscv_vcreate_v_f16mf4x7(v0, v1, v2, v3, v4, v5, v6); +} + +vfloat16mf4x8_t test_vcreate_v_f16mf4x8(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6, vfloat16mf4_t v7) { + return __riscv_vcreate_v_f16mf4x8(v0, v1, v2, v3, v4, v5, v6, v7); +} + +vfloat32m1x2_t test_vcreate_v_f32m1x2(vfloat32m1_t v0, vfloat32m1_t v1) { + return __riscv_vcreate_v_f32m1x2(v0, v1); +} + +vfloat32m1x3_t test_vcreate_v_f32m1x3(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2) { + return __riscv_vcreate_v_f32m1x3(v0, v1, v2); +} + +vfloat32m1x4_t test_vcreate_v_f32m1x4(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3) { + return __riscv_vcreate_v_f32m1x4(v0, v1, v2, v3); +} + +vfloat32m1x5_t test_vcreate_v_f32m1x5(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4) { + return __riscv_vcreate_v_f32m1x5(v0, v1, v2, v3, v4); +} + +vfloat32m1x6_t test_vcreate_v_f32m1x6(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5) { + return __riscv_vcreate_v_f32m1x6(v0, v1, v2, v3, v4, v5); +} + +vfloat32m1x7_t test_vcreate_v_f32m1x7(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6) { + return __riscv_vcreate_v_f32m1x7(v0, v1, v2, v3, v4, v5, v6); +} + +vfloat32m1x8_t test_vcreate_v_f32m1x8(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6, vfloat32m1_t v7) { + return __riscv_vcreate_v_f32m1x8(v0, v1, v2, v3, v4, v5, v6, v7); +} + +vfloat64m2x2_t test_vcreate_v_f64m2x2(vfloat64m2_t v0, vfloat64m2_t v1) { + return __riscv_vcreate_v_f64m2x2(v0, v1); +} + +vfloat64m2x3_t test_vcreate_v_f64m2x3(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2) { + return __riscv_vcreate_v_f64m2x3(v0, v1, v2); +} + +vfloat64m2x4_t test_vcreate_v_f64m2x4(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2, vfloat64m2_t v3) { + return __riscv_vcreate_v_f64m2x4(v0, v1, v2, v3); +} + +vfloat64m4x2_t test_vcreate_v_f64m4x2(vfloat64m4_t v0, vfloat64m4_t v1) { + return __riscv_vcreate_v_f64m4x2(v0, v1); +} + +vint8m2x2_t test_vcreate_v_i8m2x2(vint8m2_t v0, vint8m2_t v1) { + return __riscv_vcreate_v_i8m2x2(v0, v1); +} + +vint8m2x3_t test_vcreate_v_i8m2x3(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2) { + return __riscv_vcreate_v_i8m2x3(v0, v1, v2); +} + +vint8m2x4_t test_vcreate_v_i8m2x4(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2, vint8m2_t v3) { + return __riscv_vcreate_v_i8m2x4(v0, v1, v2, v3); +} + +vint8m4x2_t test_vcreate_v_i8m4x2(vint8m4_t v0, vint8m4_t v1) { + return __riscv_vcreate_v_i8m4x2(v0, v1); +} + +vint16m4x2_t test_vcreate_v_i16m4x2(vint16m4_t v0, vint16m4_t v1) { + return __riscv_vcreate_v_i16m4x2(v0, v1); +} + +vint32m4x2_t test_vcreate_v_i32m4x2(vint32m4_t v0, vint32m4_t v1) { + return __riscv_vcreate_v_i32m4x2(v0, v1); +} + +vint64m2x2_t test_vcreate_v_i64m2x2(vint64m2_t v0, vint64m2_t v1) { + return __riscv_vcreate_v_i64m2x2(v0, v1); +} + +vint64m2x3_t test_vcreate_v_i64m2x3(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2) { + return __riscv_vcreate_v_i64m2x3(v0, v1, v2); +} + +vint64m2x4_t test_vcreate_v_i64m2x4(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2, vint64m2_t v3) { + return __riscv_vcreate_v_i64m2x4(v0, v1, v2, v3); +} + +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e16,\s*mf4,\s*t[au],\s*m[au]} 7 } } */ +/* { dg-final { scan-assembler-times {vle16\.v\s+v[0-9]+,\s*0\([0-9ax]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vse16\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vl2re8\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 9 } } */ +/* { dg-final { scan-assembler-times {vl1re32\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vl2re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */ +/* { dg-final { scan-assembler-times {vl4re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 2 } } */ +/* { dg-final { scan-assembler-times {vs1r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vs2r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 27 } } */ +/* { dg-final { scan-assembler-times {vs4r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 8 } } */
LGTM, thanks for implement this :) On Tue, Sep 12, 2023 at 10:16 AM juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> wrote: > > Thanks for support it. > LGTM from my side. > Wait for kito's more comments. > > > > juzhe.zhong@rivai.ai > > From: Li Xu > Date: 2023-09-12 10:08 > To: gcc-patches > CC: kito.cheng; palmer; juzhe.zhong; pan2.li; gaofei; wangfeng; xuli > Subject: [PATCH] RISC-V: Add vcreate intrinsics for RVV tuple types > From: xuli <xuli1@eswincomputing.com> > > gcc/ChangeLog: > > * config/riscv/riscv-vector-builtins-bases.cc (class vcreate): > (BASE): New class. > * config/riscv/riscv-vector-builtins-bases.h: Ditto. > * config/riscv/riscv-vector-builtins-functions.def (vcreate): Add vcreate support. > * config/riscv/riscv-vector-builtins-shapes.cc (struct vcreate_def): Ditto. > (SHAPE): Ditto. > * config/riscv/riscv-vector-builtins-shapes.h: Ditto. > * config/riscv/riscv-vector-builtins.cc: Add args type. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/tuple_create.c: New test. > --- > .../riscv/riscv-vector-builtins-bases.cc | 40 ++++++ > .../riscv/riscv-vector-builtins-bases.h | 1 + > .../riscv/riscv-vector-builtins-functions.def | 1 + > .../riscv/riscv-vector-builtins-shapes.cc | 50 +++++++ > .../riscv/riscv-vector-builtins-shapes.h | 1 + > gcc/config/riscv/riscv-vector-builtins.cc | 12 ++ > .../gcc.target/riscv/rvv/base/tuple_create.c | 123 ++++++++++++++++++ > 7 files changed, 228 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c > > diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc > index 8e679f72392..be3df2c1ea2 100644 > --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc > +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc > @@ -1824,6 +1824,44 @@ public: > } > }; > +class vcreate : public function_base > +{ > +public: > + gimple *fold (gimple_folder &f) const override > + { > + unsigned int nargs = gimple_call_num_args (f.call); > + tree lhs_type = TREE_TYPE (f.lhs); > + > + /* Replace the call with a clobber of the result (to prevent it from > + becoming upwards exposed) followed by stores into each individual > + vector of tuple. > + > + The fold routines expect the replacement statement to have the > + same lhs as the original call, so return the clobber statement > + rather than the final vector store. */ > + gassign *clobber = gimple_build_assign (f.lhs, build_clobber (lhs_type)); > + > + for (unsigned int i = nargs; i-- > 0; ) > + { > + tree rhs_vector = gimple_call_arg (f.call, i); > + tree field = tuple_type_field (TREE_TYPE (f.lhs)); > + tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field), > + unshare_expr (f.lhs), field, NULL_TREE); > + tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), > + lhs_array, size_int (i), > + NULL_TREE, NULL_TREE); > + gassign *assign = gimple_build_assign (lhs_vector, rhs_vector); > + gsi_insert_after (f.gsi, assign, GSI_SAME_STMT); > + } > + return clobber; > + } > + > + rtx expand (function_expander &e) const override > + { > + return NULL_RTX; > + } > +}; > + > class read_vl : public function_base > { > public: > @@ -2285,6 +2323,7 @@ static CONSTEXPR const vlmul_ext vlmul_ext_obj; > static CONSTEXPR const vlmul_trunc vlmul_trunc_obj; > static CONSTEXPR const vset vset_obj; > static CONSTEXPR const vget vget_obj; > +static CONSTEXPR const vcreate vcreate_obj; > static CONSTEXPR const read_vl read_vl_obj; > static CONSTEXPR const vleff vleff_obj; > static CONSTEXPR const vlenb vlenb_obj; > @@ -2546,6 +2585,7 @@ BASE (vlmul_ext) > BASE (vlmul_trunc) > BASE (vset) > BASE (vget) > +BASE (vcreate) > BASE (read_vl) > BASE (vleff) > BASE (vlenb) > diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h > index 69d4562091f..131041ea66f 100644 > --- a/gcc/config/riscv/riscv-vector-builtins-bases.h > +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h > @@ -267,6 +267,7 @@ extern const function_base *const vlmul_ext; > extern const function_base *const vlmul_trunc; > extern const function_base *const vset; > extern const function_base *const vget; > +extern const function_base *const vcreate; > extern const function_base *const read_vl; > extern const function_base *const vleff; > extern const function_base *const vlenb; > diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def > index 3ce06dc60b7..18ed2c2b8f6 100644 > --- a/gcc/config/riscv/riscv-vector-builtins-functions.def > +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def > @@ -621,6 +621,7 @@ DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_lmul4_x2_ops) > // Tuple types > DEF_RVV_FUNCTION (vset, vset, none_preds, all_v_vset_tuple_ops) > DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_tuple_ops) > +DEF_RVV_FUNCTION (vcreate, vcreate, none_preds, all_v_vcreate_tuple_ops) > DEF_RVV_FUNCTION (vlseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ops) > DEF_RVV_FUNCTION (vsseg, seg_loadstore, none_m_preds, tuple_v_scalar_ptr_ops) > DEF_RVV_FUNCTION (vlsseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ptrdiff_ops) > diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc > index f8fdec863e6..0bda934ae16 100644 > --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc > +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc > @@ -706,6 +706,55 @@ struct vget_def : public misc_def > } > }; > +/* vcreate_def class. */ > +struct vcreate_def : public build_base > +{ > + void build (function_builder &b, > + const function_group_info &group) const override > + { > + for (unsigned int vec_type_idx = 0; > + group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES; > + ++vec_type_idx) > + { > + auto_vec<tree, 8> argument_types; > + function_instance function_instance (group.base_name, *group.base, > + *group.shape, > + group.ops_infos.types[vec_type_idx], > + group.preds[0], &group.ops_infos); > + > + tree return_type = group.ops_infos.ret.get_tree_type ( > + group.ops_infos.types[vec_type_idx].index); > + > + if (!return_type) > + continue; > + > + machine_mode mode = TYPE_MODE (return_type); > + unsigned int nf = get_nf (mode); > + > + for (unsigned int i = 0; i < nf; i++) > + argument_types.quick_push ( > + function_instance.op_info->args[0].get_tree_type ( > + function_instance.type.index)); > + > + b.add_unique_function (function_instance, (*group.shape), return_type, > + argument_types); > + } > + } > + > + char *get_name (function_builder &b, const function_instance &instance, > + bool overloaded_p) const override > + { > + if (overloaded_p) > + return nullptr; > + b.append_base_name (instance.base_name); > + b.append_name (operand_suffixes[instance.op_info->op]); > + vector_type_index ret_type_idx > + = instance.op_info->ret.get_function_type_index (instance.type.index); > + b.append_name (type_suffixes[ret_type_idx].vector); > + return b.finish_name (); > + } > +}; > + > /* read_vl_def class. */ > struct read_vl_def : public function_shape > { > @@ -942,6 +991,7 @@ SHAPE(vundefined, vundefined) > SHAPE(misc, misc) > SHAPE(vset, vset) > SHAPE(vget, vget) > +SHAPE(vcreate, vcreate) > SHAPE(read_vl, read_vl) > SHAPE(fault_load, fault_load) > SHAPE(vlenb, vlenb) > diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h > index 92eb8bc9d71..df9884bb572 100644 > --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h > +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h > @@ -45,6 +45,7 @@ extern const function_shape *const vundefined; > extern const function_shape *const misc; > extern const function_shape *const vset; > extern const function_shape *const vget; > +extern const function_shape *const vcreate; > extern const function_shape *const read_vl; > extern const function_shape *const fault_load; > extern const function_shape *const vlenb; > diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc > index 6d99f970ead..5318651138a 100644 > --- a/gcc/config/riscv/riscv-vector-builtins.cc > +++ b/gcc/config/riscv/riscv-vector-builtins.cc > @@ -873,6 +873,10 @@ static CONSTEXPR const rvv_arg_type_info tuple_vset_args[] > = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size), > rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; > +/* A list of args for vector_type func (vector_type) function. */ > +static CONSTEXPR const rvv_arg_type_info tuple_vcreate_args[] > + = {rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; > + > /* A list of none preds that will be registered for intrinsic functions. */ > static CONSTEXPR const predication_type_index none_preds[] > = {PRED_TYPE_none, NUM_PRED_TYPES}; > @@ -2497,6 +2501,14 @@ static CONSTEXPR const rvv_op_info tuple_v_scalar_const_ptr_size_ptr_ops > rvv_arg_type_info (RVV_BASE_vector), /* Return type */ > scalar_const_ptr_size_ptr_args /* Args */}; > +/* A static operand information for vector_type func (vector_type) > + * function registration. */ > +static CONSTEXPR const rvv_op_info all_v_vcreate_tuple_ops > + = {tuple_ops, /* Types */ > + OP_TYPE_v, /* Suffix */ > + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ > + tuple_vcreate_args /* Args */}; > + > /* A list of all RVV base function types. */ > static CONSTEXPR const function_type_info function_types[] = { > #define DEF_RVV_TYPE_INDEX( \ > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c > new file mode 100644 > index 00000000000..b252b2f3cd4 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c > @@ -0,0 +1,123 @@ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ > + > +#include "riscv_vector.h" > + > +vfloat16mf4x2_t test_vcreate_v_f16mf4x2(vfloat16mf4_t v0, vfloat16mf4_t v1) { > + return __riscv_vcreate_v_f16mf4x2(v0, v1); > +} > + > +vfloat16mf4x3_t test_vcreate_v_f16mf4x3(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2) { > + return __riscv_vcreate_v_f16mf4x3(v0, v1, v2); > +} > + > +vfloat16mf4x4_t test_vcreate_v_f16mf4x4(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3) { > + return __riscv_vcreate_v_f16mf4x4(v0, v1, v2, v3); > +} > + > +vfloat16mf4x5_t test_vcreate_v_f16mf4x5(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4) { > + return __riscv_vcreate_v_f16mf4x5(v0, v1, v2, v3, v4); > +} > + > +vfloat16mf4x6_t test_vcreate_v_f16mf4x6(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5) { > + return __riscv_vcreate_v_f16mf4x6(v0, v1, v2, v3, v4, v5); > +} > + > +vfloat16mf4x7_t test_vcreate_v_f16mf4x7(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6) { > + return __riscv_vcreate_v_f16mf4x7(v0, v1, v2, v3, v4, v5, v6); > +} > + > +vfloat16mf4x8_t test_vcreate_v_f16mf4x8(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6, vfloat16mf4_t v7) { > + return __riscv_vcreate_v_f16mf4x8(v0, v1, v2, v3, v4, v5, v6, v7); > +} > + > +vfloat32m1x2_t test_vcreate_v_f32m1x2(vfloat32m1_t v0, vfloat32m1_t v1) { > + return __riscv_vcreate_v_f32m1x2(v0, v1); > +} > + > +vfloat32m1x3_t test_vcreate_v_f32m1x3(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2) { > + return __riscv_vcreate_v_f32m1x3(v0, v1, v2); > +} > + > +vfloat32m1x4_t test_vcreate_v_f32m1x4(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3) { > + return __riscv_vcreate_v_f32m1x4(v0, v1, v2, v3); > +} > + > +vfloat32m1x5_t test_vcreate_v_f32m1x5(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4) { > + return __riscv_vcreate_v_f32m1x5(v0, v1, v2, v3, v4); > +} > + > +vfloat32m1x6_t test_vcreate_v_f32m1x6(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5) { > + return __riscv_vcreate_v_f32m1x6(v0, v1, v2, v3, v4, v5); > +} > + > +vfloat32m1x7_t test_vcreate_v_f32m1x7(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6) { > + return __riscv_vcreate_v_f32m1x7(v0, v1, v2, v3, v4, v5, v6); > +} > + > +vfloat32m1x8_t test_vcreate_v_f32m1x8(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6, vfloat32m1_t v7) { > + return __riscv_vcreate_v_f32m1x8(v0, v1, v2, v3, v4, v5, v6, v7); > +} > + > +vfloat64m2x2_t test_vcreate_v_f64m2x2(vfloat64m2_t v0, vfloat64m2_t v1) { > + return __riscv_vcreate_v_f64m2x2(v0, v1); > +} > + > +vfloat64m2x3_t test_vcreate_v_f64m2x3(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2) { > + return __riscv_vcreate_v_f64m2x3(v0, v1, v2); > +} > + > +vfloat64m2x4_t test_vcreate_v_f64m2x4(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2, vfloat64m2_t v3) { > + return __riscv_vcreate_v_f64m2x4(v0, v1, v2, v3); > +} > + > +vfloat64m4x2_t test_vcreate_v_f64m4x2(vfloat64m4_t v0, vfloat64m4_t v1) { > + return __riscv_vcreate_v_f64m4x2(v0, v1); > +} > + > +vint8m2x2_t test_vcreate_v_i8m2x2(vint8m2_t v0, vint8m2_t v1) { > + return __riscv_vcreate_v_i8m2x2(v0, v1); > +} > + > +vint8m2x3_t test_vcreate_v_i8m2x3(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2) { > + return __riscv_vcreate_v_i8m2x3(v0, v1, v2); > +} > + > +vint8m2x4_t test_vcreate_v_i8m2x4(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2, vint8m2_t v3) { > + return __riscv_vcreate_v_i8m2x4(v0, v1, v2, v3); > +} > + > +vint8m4x2_t test_vcreate_v_i8m4x2(vint8m4_t v0, vint8m4_t v1) { > + return __riscv_vcreate_v_i8m4x2(v0, v1); > +} > + > +vint16m4x2_t test_vcreate_v_i16m4x2(vint16m4_t v0, vint16m4_t v1) { > + return __riscv_vcreate_v_i16m4x2(v0, v1); > +} > + > +vint32m4x2_t test_vcreate_v_i32m4x2(vint32m4_t v0, vint32m4_t v1) { > + return __riscv_vcreate_v_i32m4x2(v0, v1); > +} > + > +vint64m2x2_t test_vcreate_v_i64m2x2(vint64m2_t v0, vint64m2_t v1) { > + return __riscv_vcreate_v_i64m2x2(v0, v1); > +} > + > +vint64m2x3_t test_vcreate_v_i64m2x3(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2) { > + return __riscv_vcreate_v_i64m2x3(v0, v1, v2); > +} > + > +vint64m2x4_t test_vcreate_v_i64m2x4(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2, vint64m2_t v3) { > + return __riscv_vcreate_v_i64m2x4(v0, v1, v2, v3); > +} > + > +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e16,\s*mf4,\s*t[au],\s*m[au]} 7 } } */ > +/* { dg-final { scan-assembler-times {vle16\.v\s+v[0-9]+,\s*0\([0-9ax]+\)} 35 } } */ > +/* { dg-final { scan-assembler-times {vse16\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ > +/* { dg-final { scan-assembler-times {vl2re8\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 9 } } */ > +/* { dg-final { scan-assembler-times {vl1re32\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ > +/* { dg-final { scan-assembler-times {vl2re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */ > +/* { dg-final { scan-assembler-times {vl4re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 2 } } */ > +/* { dg-final { scan-assembler-times {vs1r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ > +/* { dg-final { scan-assembler-times {vs2r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 27 } } */ > +/* { dg-final { scan-assembler-times {vs4r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 8 } } */ > -- > 2.17.1 > >
Committed, thanks juzhe and kito. -------------- Li Xu >LGTM, thanks for implement this :) > >On Tue, Sep 12, 2023 at 10:16 AM juzhe.zhong@rivai.ai ><juzhe.zhong@rivai.ai> wrote: >> >> Thanks for support it. >> LGTM from my side. >> Wait for kito's more comments. >> >> >> >> juzhe.zhong@rivai.ai >> >> From: Li Xu >> Date: 2023-09-12 10:08 >> To: gcc-patches >> CC: kito.cheng; palmer; juzhe.zhong; pan2.li; gaofei; wangfeng; xuli >> Subject: [PATCH] RISC-V: Add vcreate intrinsics for RVV tuple types >> From: xuli <xuli1@eswincomputing.com> >> >> gcc/ChangeLog: >> >> * config/riscv/riscv-vector-builtins-bases.cc (class vcreate): >> (BASE): New class. >> * config/riscv/riscv-vector-builtins-bases.h: Ditto. >> * config/riscv/riscv-vector-builtins-functions.def (vcreate): Add vcreate support. >> * config/riscv/riscv-vector-builtins-shapes.cc (struct vcreate_def): Ditto. >> (SHAPE): Ditto. >> * config/riscv/riscv-vector-builtins-shapes.h: Ditto. >> * config/riscv/riscv-vector-builtins.cc: Add args type. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.target/riscv/rvv/base/tuple_create.c: New test. >> --- >> .../riscv/riscv-vector-builtins-bases.cc | 40 ++++++ >> .../riscv/riscv-vector-builtins-bases.h | 1 + >> .../riscv/riscv-vector-builtins-functions.def | 1 + >> .../riscv/riscv-vector-builtins-shapes.cc | 50 +++++++ >> .../riscv/riscv-vector-builtins-shapes.h | 1 + >> gcc/config/riscv/riscv-vector-builtins.cc | 12 ++ >> .../gcc.target/riscv/rvv/base/tuple_create.c | 123 ++++++++++++++++++ >> 7 files changed, 228 insertions(+) >> create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c >> >> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc >> index 8e679f72392..be3df2c1ea2 100644 >> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc >> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc >> @@ -1824,6 +1824,44 @@ public: >> } >> }; >> +class vcreate : public function_base >> +{ >> +public: >> + gimple *fold (gimple_folder &f) const override >> + { >> + unsigned int nargs = gimple_call_num_args (f.call); >> + tree lhs_type = TREE_TYPE (f.lhs); >> + >> + /* Replace the call with a clobber of the result (to prevent it from >> + becoming upwards exposed) followed by stores into each individual >> + vector of tuple. >> + >> + The fold routines expect the replacement statement to have the >> + same lhs as the original call, so return the clobber statement >> + rather than the final vector store. */ >> + gassign *clobber = gimple_build_assign (f.lhs, build_clobber (lhs_type)); >> + >> + for (unsigned int i = nargs; i-- > 0; ) >> + { >> + tree rhs_vector = gimple_call_arg (f.call, i); >> + tree field = tuple_type_field (TREE_TYPE (f.lhs)); >> + tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field), >> + unshare_expr (f.lhs), field, NULL_TREE); >> + tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), >> + lhs_array, size_int (i), >> + NULL_TREE, NULL_TREE); >> + gassign *assign = gimple_build_assign (lhs_vector, rhs_vector); >> + gsi_insert_after (f.gsi, assign, GSI_SAME_STMT); >> + } >> + return clobber; >> + } >> + >> + rtx expand (function_expander &e) const override >> + { >> + return NULL_RTX; >> + } >> +}; >> + >> class read_vl : public function_base >> { >> public: >> @@ -2285,6 +2323,7 @@ static CONSTEXPR const vlmul_ext vlmul_ext_obj; >> static CONSTEXPR const vlmul_trunc vlmul_trunc_obj; >> static CONSTEXPR const vset vset_obj; >> static CONSTEXPR const vget vget_obj; >> +static CONSTEXPR const vcreate vcreate_obj; >> static CONSTEXPR const read_vl read_vl_obj; >> static CONSTEXPR const vleff vleff_obj; >> static CONSTEXPR const vlenb vlenb_obj; >> @@ -2546,6 +2585,7 @@ BASE (vlmul_ext) >> BASE (vlmul_trunc) >> BASE (vset) >> BASE (vget) >> +BASE (vcreate) >> BASE (read_vl) >> BASE (vleff) >> BASE (vlenb) >> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h >> index 69d4562091f..131041ea66f 100644 >> --- a/gcc/config/riscv/riscv-vector-builtins-bases.h >> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h >> @@ -267,6 +267,7 @@ extern const function_base *const vlmul_ext; >> extern const function_base *const vlmul_trunc; >> extern const function_base *const vset; >> extern const function_base *const vget; >> +extern const function_base *const vcreate; >> extern const function_base *const read_vl; >> extern const function_base *const vleff; >> extern const function_base *const vlenb; >> diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def >> index 3ce06dc60b7..18ed2c2b8f6 100644 >> --- a/gcc/config/riscv/riscv-vector-builtins-functions.def >> +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def >> @@ -621,6 +621,7 @@ DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_lmul4_x2_ops) >> // Tuple types >> DEF_RVV_FUNCTION (vset, vset, none_preds, all_v_vset_tuple_ops) >> DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_tuple_ops) >> +DEF_RVV_FUNCTION (vcreate, vcreate, none_preds, all_v_vcreate_tuple_ops) >> DEF_RVV_FUNCTION (vlseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ops) >> DEF_RVV_FUNCTION (vsseg, seg_loadstore, none_m_preds, tuple_v_scalar_ptr_ops) >> DEF_RVV_FUNCTION (vlsseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ptrdiff_ops) >> diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc >> index f8fdec863e6..0bda934ae16 100644 >> --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc >> +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc >> @@ -706,6 +706,55 @@ struct vget_def : public misc_def >> } >> }; >> +/* vcreate_def class. */ >> +struct vcreate_def : public build_base >> +{ >> + void build (function_builder &b, >> + const function_group_info &group) const override >> + { >> + for (unsigned int vec_type_idx = 0; >> + group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES; >> + ++vec_type_idx) >> + { >> + auto_vec<tree, 8> argument_types; >> + function_instance function_instance (group.base_name, *group.base, >> + *group.shape, >> + group.ops_infos.types[vec_type_idx], >> + group.preds[0], &group.ops_infos); >> + >> + tree return_type = group.ops_infos.ret.get_tree_type ( >> + group.ops_infos.types[vec_type_idx].index); >> + >> + if (!return_type) >> + continue; >> + >> + machine_mode mode = TYPE_MODE (return_type); >> + unsigned int nf = get_nf (mode); >> + >> + for (unsigned int i = 0; i < nf; i++) >> + argument_types.quick_push ( >> + function_instance.op_info->args[0].get_tree_type ( >> + function_instance.type.index)); >> + >> + b.add_unique_function (function_instance, (*group.shape), return_type, >> + argument_types); >> + } >> + } >> + >> + char *get_name (function_builder &b, const function_instance &instance, >> + bool overloaded_p) const override >> + { >> + if (overloaded_p) >> + return nullptr; >> + b.append_base_name (instance.base_name); >> + b.append_name (operand_suffixes[instance.op_info->op]); >> + vector_type_index ret_type_idx >> + = instance.op_info->ret.get_function_type_index (instance.type.index); >> + b.append_name (type_suffixes[ret_type_idx].vector); >> + return b.finish_name (); >> + } >> +}; >> + >> /* read_vl_def class. */ >> struct read_vl_def : public function_shape >> { >> @@ -942,6 +991,7 @@ SHAPE(vundefined, vundefined) >> SHAPE(misc, misc) >> SHAPE(vset, vset) >> SHAPE(vget, vget) >> +SHAPE(vcreate, vcreate) >> SHAPE(read_vl, read_vl) >> SHAPE(fault_load, fault_load) >> SHAPE(vlenb, vlenb) >> diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h >> index 92eb8bc9d71..df9884bb572 100644 >> --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h >> +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h >> @@ -45,6 +45,7 @@ extern const function_shape *const vundefined; >> extern const function_shape *const misc; >> extern const function_shape *const vset; >> extern const function_shape *const vget; >> +extern const function_shape *const vcreate; >> extern const function_shape *const read_vl; >> extern const function_shape *const fault_load; >> extern const function_shape *const vlenb; >> diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc >> index 6d99f970ead..5318651138a 100644 >> --- a/gcc/config/riscv/riscv-vector-builtins.cc >> +++ b/gcc/config/riscv/riscv-vector-builtins.cc >> @@ -873,6 +873,10 @@ static CONSTEXPR const rvv_arg_type_info tuple_vset_args[] >> = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size), >> rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; >> +/* A list of args for vector_type func (vector_type) function. */ >> +static CONSTEXPR const rvv_arg_type_info tuple_vcreate_args[] >> + = {rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; >> + >> /* A list of none preds that will be registered for intrinsic functions. */ >> static CONSTEXPR const predication_type_index none_preds[] >> = {PRED_TYPE_none, NUM_PRED_TYPES}; >> @@ -2497,6 +2501,14 @@ static CONSTEXPR const rvv_op_info tuple_v_scalar_const_ptr_size_ptr_ops >> rvv_arg_type_info (RVV_BASE_vector), /* Return type */ >> scalar_const_ptr_size_ptr_args /* Args */}; >> +/* A static operand information for vector_type func (vector_type) >> + * function registration. */ >> +static CONSTEXPR const rvv_op_info all_v_vcreate_tuple_ops >> + = {tuple_ops, /* Types */ >> + OP_TYPE_v, /* Suffix */ >> + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ >> + tuple_vcreate_args /* Args */}; >> + >> /* A list of all RVV base function types. */ >> static CONSTEXPR const function_type_info function_types[] = { >> #define DEF_RVV_TYPE_INDEX( \ >> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c >> new file mode 100644 >> index 00000000000..b252b2f3cd4 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c >> @@ -0,0 +1,123 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >> + >> +#include "riscv_vector.h" >> + >> +vfloat16mf4x2_t test_vcreate_v_f16mf4x2(vfloat16mf4_t v0, vfloat16mf4_t v1) { >> + return __riscv_vcreate_v_f16mf4x2(v0, v1); >> +} >> + >> +vfloat16mf4x3_t test_vcreate_v_f16mf4x3(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2) { >> + return __riscv_vcreate_v_f16mf4x3(v0, v1, v2); >> +} >> + >> +vfloat16mf4x4_t test_vcreate_v_f16mf4x4(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3) { >> + return __riscv_vcreate_v_f16mf4x4(v0, v1, v2, v3); >> +} >> + >> +vfloat16mf4x5_t test_vcreate_v_f16mf4x5(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4) { >> + return __riscv_vcreate_v_f16mf4x5(v0, v1, v2, v3, v4); >> +} >> + >> +vfloat16mf4x6_t test_vcreate_v_f16mf4x6(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5) { >> + return __riscv_vcreate_v_f16mf4x6(v0, v1, v2, v3, v4, v5); >> +} >> + >> +vfloat16mf4x7_t test_vcreate_v_f16mf4x7(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6) { >> + return __riscv_vcreate_v_f16mf4x7(v0, v1, v2, v3, v4, v5, v6); >> +} >> + >> +vfloat16mf4x8_t test_vcreate_v_f16mf4x8(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6, vfloat16mf4_t v7) { >> + return __riscv_vcreate_v_f16mf4x8(v0, v1, v2, v3, v4, v5, v6, v7); >> +} >> + >> +vfloat32m1x2_t test_vcreate_v_f32m1x2(vfloat32m1_t v0, vfloat32m1_t v1) { >> + return __riscv_vcreate_v_f32m1x2(v0, v1); >> +} >> + >> +vfloat32m1x3_t test_vcreate_v_f32m1x3(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2) { >> + return __riscv_vcreate_v_f32m1x3(v0, v1, v2); >> +} >> + >> +vfloat32m1x4_t test_vcreate_v_f32m1x4(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3) { >> + return __riscv_vcreate_v_f32m1x4(v0, v1, v2, v3); >> +} >> + >> +vfloat32m1x5_t test_vcreate_v_f32m1x5(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4) { >> + return __riscv_vcreate_v_f32m1x5(v0, v1, v2, v3, v4); >> +} >> + >> +vfloat32m1x6_t test_vcreate_v_f32m1x6(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5) { >> + return __riscv_vcreate_v_f32m1x6(v0, v1, v2, v3, v4, v5); >> +} >> + >> +vfloat32m1x7_t test_vcreate_v_f32m1x7(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6) { >> + return __riscv_vcreate_v_f32m1x7(v0, v1, v2, v3, v4, v5, v6); >> +} >> + >> +vfloat32m1x8_t test_vcreate_v_f32m1x8(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6, vfloat32m1_t v7) { >> + return __riscv_vcreate_v_f32m1x8(v0, v1, v2, v3, v4, v5, v6, v7); >> +} >> + >> +vfloat64m2x2_t test_vcreate_v_f64m2x2(vfloat64m2_t v0, vfloat64m2_t v1) { >> + return __riscv_vcreate_v_f64m2x2(v0, v1); >> +} >> + >> +vfloat64m2x3_t test_vcreate_v_f64m2x3(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2) { >> + return __riscv_vcreate_v_f64m2x3(v0, v1, v2); >> +} >> + >> +vfloat64m2x4_t test_vcreate_v_f64m2x4(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2, vfloat64m2_t v3) { >> + return __riscv_vcreate_v_f64m2x4(v0, v1, v2, v3); >> +} >> + >> +vfloat64m4x2_t test_vcreate_v_f64m4x2(vfloat64m4_t v0, vfloat64m4_t v1) { >> + return __riscv_vcreate_v_f64m4x2(v0, v1); >> +} >> + >> +vint8m2x2_t test_vcreate_v_i8m2x2(vint8m2_t v0, vint8m2_t v1) { >> + return __riscv_vcreate_v_i8m2x2(v0, v1); >> +} >> + >> +vint8m2x3_t test_vcreate_v_i8m2x3(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2) { >> + return __riscv_vcreate_v_i8m2x3(v0, v1, v2); >> +} >> + >> +vint8m2x4_t test_vcreate_v_i8m2x4(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2, vint8m2_t v3) { >> + return __riscv_vcreate_v_i8m2x4(v0, v1, v2, v3); >> +} >> + >> +vint8m4x2_t test_vcreate_v_i8m4x2(vint8m4_t v0, vint8m4_t v1) { >> + return __riscv_vcreate_v_i8m4x2(v0, v1); >> +} >> + >> +vint16m4x2_t test_vcreate_v_i16m4x2(vint16m4_t v0, vint16m4_t v1) { >> + return __riscv_vcreate_v_i16m4x2(v0, v1); >> +} >> + >> +vint32m4x2_t test_vcreate_v_i32m4x2(vint32m4_t v0, vint32m4_t v1) { >> + return __riscv_vcreate_v_i32m4x2(v0, v1); >> +} >> + >> +vint64m2x2_t test_vcreate_v_i64m2x2(vint64m2_t v0, vint64m2_t v1) { >> + return __riscv_vcreate_v_i64m2x2(v0, v1); >> +} >> + >> +vint64m2x3_t test_vcreate_v_i64m2x3(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2) { >> + return __riscv_vcreate_v_i64m2x3(v0, v1, v2); >> +} >> + >> +vint64m2x4_t test_vcreate_v_i64m2x4(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2, vint64m2_t v3) { >> + return __riscv_vcreate_v_i64m2x4(v0, v1, v2, v3); >> +} >> + >> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e16,\s*mf4,\s*t[au],\s*m[au]} 7 } } */ >> +/* { dg-final { scan-assembler-times {vle16\.v\s+v[0-9]+,\s*0\([0-9ax]+\)} 35 } } */ >> +/* { dg-final { scan-assembler-times {vse16\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ >> +/* { dg-final { scan-assembler-times {vl2re8\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 9 } } */ >> +/* { dg-final { scan-assembler-times {vl1re32\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ >> +/* { dg-final { scan-assembler-times {vl2re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */ >> +/* { dg-final { scan-assembler-times {vl4re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 2 } } */ >> +/* { dg-final { scan-assembler-times {vs1r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ >> +/* { dg-final { scan-assembler-times {vs2r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 27 } } */ >> +/* { dg-final { scan-assembler-times {vs4r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 8 } } */ >> -- >> 2.17.1 >> >>
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 8e679f72392..be3df2c1ea2 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -1824,6 +1824,44 @@ public: } }; +class vcreate : public function_base +{ +public: + gimple *fold (gimple_folder &f) const override + { + unsigned int nargs = gimple_call_num_args (f.call); + tree lhs_type = TREE_TYPE (f.lhs); + + /* Replace the call with a clobber of the result (to prevent it from + becoming upwards exposed) followed by stores into each individual + vector of tuple. + + The fold routines expect the replacement statement to have the + same lhs as the original call, so return the clobber statement + rather than the final vector store. */ + gassign *clobber = gimple_build_assign (f.lhs, build_clobber (lhs_type)); + + for (unsigned int i = nargs; i-- > 0; ) + { + tree rhs_vector = gimple_call_arg (f.call, i); + tree field = tuple_type_field (TREE_TYPE (f.lhs)); + tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field), + unshare_expr (f.lhs), field, NULL_TREE); + tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), + lhs_array, size_int (i), + NULL_TREE, NULL_TREE); + gassign *assign = gimple_build_assign (lhs_vector, rhs_vector); + gsi_insert_after (f.gsi, assign, GSI_SAME_STMT); + } + return clobber; + } + + rtx expand (function_expander &e) const override + { + return NULL_RTX; + } +}; + class read_vl : public function_base { public: @@ -2285,6 +2323,7 @@ static CONSTEXPR const vlmul_ext vlmul_ext_obj; static CONSTEXPR const vlmul_trunc vlmul_trunc_obj; static CONSTEXPR const vset vset_obj; static CONSTEXPR const vget vget_obj; +static CONSTEXPR const vcreate vcreate_obj; static CONSTEXPR const read_vl read_vl_obj; static CONSTEXPR const vleff vleff_obj; static CONSTEXPR const vlenb vlenb_obj; @@ -2546,6 +2585,7 @@ BASE (vlmul_ext) BASE (vlmul_trunc) BASE (vset) BASE (vget) +BASE (vcreate) BASE (read_vl) BASE (vleff) BASE (vlenb) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index 69d4562091f..131041ea66f 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -267,6 +267,7 @@ extern const function_base *const vlmul_ext; extern const function_base *const vlmul_trunc; extern const function_base *const vset; extern const function_base *const vget; +extern const function_base *const vcreate; extern const function_base *const read_vl; extern const function_base *const vleff; extern const function_base *const vlenb; diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def index 3ce06dc60b7..18ed2c2b8f6 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -621,6 +621,7 @@ DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_lmul4_x2_ops) // Tuple types DEF_RVV_FUNCTION (vset, vset, none_preds, all_v_vset_tuple_ops) DEF_RVV_FUNCTION (vget, vget, none_preds, all_v_vget_tuple_ops) +DEF_RVV_FUNCTION (vcreate, vcreate, none_preds, all_v_vcreate_tuple_ops) DEF_RVV_FUNCTION (vlseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ops) DEF_RVV_FUNCTION (vsseg, seg_loadstore, none_m_preds, tuple_v_scalar_ptr_ops) DEF_RVV_FUNCTION (vlsseg, seg_loadstore, full_preds, tuple_v_scalar_const_ptr_ptrdiff_ops) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index f8fdec863e6..0bda934ae16 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -706,6 +706,55 @@ struct vget_def : public misc_def } }; +/* vcreate_def class. */ +struct vcreate_def : public build_base +{ + void build (function_builder &b, + const function_group_info &group) const override + { + for (unsigned int vec_type_idx = 0; + group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES; + ++vec_type_idx) + { + auto_vec<tree, 8> argument_types; + function_instance function_instance (group.base_name, *group.base, + *group.shape, + group.ops_infos.types[vec_type_idx], + group.preds[0], &group.ops_infos); + + tree return_type = group.ops_infos.ret.get_tree_type ( + group.ops_infos.types[vec_type_idx].index); + + if (!return_type) + continue; + + machine_mode mode = TYPE_MODE (return_type); + unsigned int nf = get_nf (mode); + + for (unsigned int i = 0; i < nf; i++) + argument_types.quick_push ( + function_instance.op_info->args[0].get_tree_type ( + function_instance.type.index)); + + b.add_unique_function (function_instance, (*group.shape), return_type, + argument_types); + } + } + + char *get_name (function_builder &b, const function_instance &instance, + bool overloaded_p) const override + { + if (overloaded_p) + return nullptr; + b.append_base_name (instance.base_name); + b.append_name (operand_suffixes[instance.op_info->op]); + vector_type_index ret_type_idx + = instance.op_info->ret.get_function_type_index (instance.type.index); + b.append_name (type_suffixes[ret_type_idx].vector); + return b.finish_name (); + } +}; + /* read_vl_def class. */ struct read_vl_def : public function_shape { @@ -942,6 +991,7 @@ SHAPE(vundefined, vundefined) SHAPE(misc, misc) SHAPE(vset, vset) SHAPE(vget, vget) +SHAPE(vcreate, vcreate) SHAPE(read_vl, read_vl) SHAPE(fault_load, fault_load) SHAPE(vlenb, vlenb) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h index 92eb8bc9d71..df9884bb572 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -45,6 +45,7 @@ extern const function_shape *const vundefined; extern const function_shape *const misc; extern const function_shape *const vset; extern const function_shape *const vget; +extern const function_shape *const vcreate; extern const function_shape *const read_vl; extern const function_shape *const fault_load; extern const function_shape *const vlenb; diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 6d99f970ead..5318651138a 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -873,6 +873,10 @@ static CONSTEXPR const rvv_arg_type_info tuple_vset_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; +/* A list of args for vector_type func (vector_type) function. */ +static CONSTEXPR const rvv_arg_type_info tuple_vcreate_args[] + = {rvv_arg_type_info (RVV_BASE_tuple_subpart), rvv_arg_type_info_end}; + /* A list of none preds that will be registered for intrinsic functions. */ static CONSTEXPR const predication_type_index none_preds[] = {PRED_TYPE_none, NUM_PRED_TYPES}; @@ -2497,6 +2501,14 @@ static CONSTEXPR const rvv_op_info tuple_v_scalar_const_ptr_size_ptr_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ scalar_const_ptr_size_ptr_args /* Args */}; +/* A static operand information for vector_type func (vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info all_v_vcreate_tuple_ops + = {tuple_ops, /* Types */ + OP_TYPE_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + tuple_vcreate_args /* Args */}; + /* A list of all RVV base function types. */ static CONSTEXPR const function_type_info function_types[] = { #define DEF_RVV_TYPE_INDEX( \ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c new file mode 100644 index 00000000000..b252b2f3cd4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c @@ -0,0 +1,123 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat16mf4x2_t test_vcreate_v_f16mf4x2(vfloat16mf4_t v0, vfloat16mf4_t v1) { + return __riscv_vcreate_v_f16mf4x2(v0, v1); +} + +vfloat16mf4x3_t test_vcreate_v_f16mf4x3(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2) { + return __riscv_vcreate_v_f16mf4x3(v0, v1, v2); +} + +vfloat16mf4x4_t test_vcreate_v_f16mf4x4(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3) { + return __riscv_vcreate_v_f16mf4x4(v0, v1, v2, v3); +} + +vfloat16mf4x5_t test_vcreate_v_f16mf4x5(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4) { + return __riscv_vcreate_v_f16mf4x5(v0, v1, v2, v3, v4); +} + +vfloat16mf4x6_t test_vcreate_v_f16mf4x6(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5) { + return __riscv_vcreate_v_f16mf4x6(v0, v1, v2, v3, v4, v5); +} + +vfloat16mf4x7_t test_vcreate_v_f16mf4x7(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6) { + return __riscv_vcreate_v_f16mf4x7(v0, v1, v2, v3, v4, v5, v6); +} + +vfloat16mf4x8_t test_vcreate_v_f16mf4x8(vfloat16mf4_t v0, vfloat16mf4_t v1, vfloat16mf4_t v2, vfloat16mf4_t v3, vfloat16mf4_t v4, vfloat16mf4_t v5, vfloat16mf4_t v6, vfloat16mf4_t v7) { + return __riscv_vcreate_v_f16mf4x8(v0, v1, v2, v3, v4, v5, v6, v7); +} + +vfloat32m1x2_t test_vcreate_v_f32m1x2(vfloat32m1_t v0, vfloat32m1_t v1) { + return __riscv_vcreate_v_f32m1x2(v0, v1); +} + +vfloat32m1x3_t test_vcreate_v_f32m1x3(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2) { + return __riscv_vcreate_v_f32m1x3(v0, v1, v2); +} + +vfloat32m1x4_t test_vcreate_v_f32m1x4(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3) { + return __riscv_vcreate_v_f32m1x4(v0, v1, v2, v3); +} + +vfloat32m1x5_t test_vcreate_v_f32m1x5(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4) { + return __riscv_vcreate_v_f32m1x5(v0, v1, v2, v3, v4); +} + +vfloat32m1x6_t test_vcreate_v_f32m1x6(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5) { + return __riscv_vcreate_v_f32m1x6(v0, v1, v2, v3, v4, v5); +} + +vfloat32m1x7_t test_vcreate_v_f32m1x7(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6) { + return __riscv_vcreate_v_f32m1x7(v0, v1, v2, v3, v4, v5, v6); +} + +vfloat32m1x8_t test_vcreate_v_f32m1x8(vfloat32m1_t v0, vfloat32m1_t v1, vfloat32m1_t v2, vfloat32m1_t v3, vfloat32m1_t v4, vfloat32m1_t v5, vfloat32m1_t v6, vfloat32m1_t v7) { + return __riscv_vcreate_v_f32m1x8(v0, v1, v2, v3, v4, v5, v6, v7); +} + +vfloat64m2x2_t test_vcreate_v_f64m2x2(vfloat64m2_t v0, vfloat64m2_t v1) { + return __riscv_vcreate_v_f64m2x2(v0, v1); +} + +vfloat64m2x3_t test_vcreate_v_f64m2x3(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2) { + return __riscv_vcreate_v_f64m2x3(v0, v1, v2); +} + +vfloat64m2x4_t test_vcreate_v_f64m2x4(vfloat64m2_t v0, vfloat64m2_t v1, vfloat64m2_t v2, vfloat64m2_t v3) { + return __riscv_vcreate_v_f64m2x4(v0, v1, v2, v3); +} + +vfloat64m4x2_t test_vcreate_v_f64m4x2(vfloat64m4_t v0, vfloat64m4_t v1) { + return __riscv_vcreate_v_f64m4x2(v0, v1); +} + +vint8m2x2_t test_vcreate_v_i8m2x2(vint8m2_t v0, vint8m2_t v1) { + return __riscv_vcreate_v_i8m2x2(v0, v1); +} + +vint8m2x3_t test_vcreate_v_i8m2x3(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2) { + return __riscv_vcreate_v_i8m2x3(v0, v1, v2); +} + +vint8m2x4_t test_vcreate_v_i8m2x4(vint8m2_t v0, vint8m2_t v1, vint8m2_t v2, vint8m2_t v3) { + return __riscv_vcreate_v_i8m2x4(v0, v1, v2, v3); +} + +vint8m4x2_t test_vcreate_v_i8m4x2(vint8m4_t v0, vint8m4_t v1) { + return __riscv_vcreate_v_i8m4x2(v0, v1); +} + +vint16m4x2_t test_vcreate_v_i16m4x2(vint16m4_t v0, vint16m4_t v1) { + return __riscv_vcreate_v_i16m4x2(v0, v1); +} + +vint32m4x2_t test_vcreate_v_i32m4x2(vint32m4_t v0, vint32m4_t v1) { + return __riscv_vcreate_v_i32m4x2(v0, v1); +} + +vint64m2x2_t test_vcreate_v_i64m2x2(vint64m2_t v0, vint64m2_t v1) { + return __riscv_vcreate_v_i64m2x2(v0, v1); +} + +vint64m2x3_t test_vcreate_v_i64m2x3(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2) { + return __riscv_vcreate_v_i64m2x3(v0, v1, v2); +} + +vint64m2x4_t test_vcreate_v_i64m2x4(vint64m2_t v0, vint64m2_t v1, vint64m2_t v2, vint64m2_t v3) { + return __riscv_vcreate_v_i64m2x4(v0, v1, v2, v3); +} + +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e16,\s*mf4,\s*t[au],\s*m[au]} 7 } } */ +/* { dg-final { scan-assembler-times {vle16\.v\s+v[0-9]+,\s*0\([0-9ax]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vse16\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vl2re8\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 9 } } */ +/* { dg-final { scan-assembler-times {vl1re32\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vl2re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */ +/* { dg-final { scan-assembler-times {vl4re64\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 2 } } */ +/* { dg-final { scan-assembler-times {vs1r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 35 } } */ +/* { dg-final { scan-assembler-times {vs2r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 27 } } */ +/* { dg-final { scan-assembler-times {vs4r\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 8 } } */
From: xuli <xuli1@eswincomputing.com> gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc (class vcreate): (BASE): New class. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vcreate): Add vcreate support. * config/riscv/riscv-vector-builtins-shapes.cc (struct vcreate_def): Ditto. (SHAPE): Ditto. * config/riscv/riscv-vector-builtins-shapes.h: Ditto. * config/riscv/riscv-vector-builtins.cc: Add args type. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/tuple_create.c: New test. --- .../riscv/riscv-vector-builtins-bases.cc | 40 ++++++ .../riscv/riscv-vector-builtins-bases.h | 1 + .../riscv/riscv-vector-builtins-functions.def | 1 + .../riscv/riscv-vector-builtins-shapes.cc | 50 +++++++ .../riscv/riscv-vector-builtins-shapes.h | 1 + gcc/config/riscv/riscv-vector-builtins.cc | 12 ++ .../gcc.target/riscv/rvv/base/tuple_create.c | 123 ++++++++++++++++++ 7 files changed, 228 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/tuple_create.c