LGTM, thanks for implement this :)
On Tue, Sep 12, 2023 at 10:16 AM juzhe.zh...@rivai.ai <juzhe.zh...@rivai.ai> wrote: > > Thanks for support it. > LGTM from my side. > Wait for kito's more comments. > > > > juzhe.zh...@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 <xu...@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 > >