From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sgoci-sdnproxy-4.icoremail.net (sgoci-sdnproxy-4.icoremail.net [129.150.39.64]) by sourceware.org (Postfix) with ESMTP id 5E82A3858D33 for ; Tue, 31 Oct 2023 02:24:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5E82A3858D33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5E82A3858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=129.150.39.64 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698719104; cv=none; b=QHIuPTeXoj67fZFR8Re5kzbQ/6X4O4j0xNrrbAgrV7/98fMYvAX8InkWxWOGXXDyGuWHYhLOspt2Meal3bex8+V+dhmMyqHB5s6RhJeQA/ApNmqYZLWOtbwORyW0AC/vZShJra6XPGCjGGiBjAgnFZ5vGJPjLDjaiUUyk6PE03g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698719104; c=relaxed/simple; bh=ciuA4ia0mbgmiLaXnFP/L4eMVOS+LN+paRGWpE1BcOw=; h=From:To:Subject:Date:Message-Id; b=TkgWJHTu6a+OO7+OtlHfpRNNIdxWtFLoryHv/AWdgctLYaPC0XLmnQ3vdvfRPY4Q3194A998NlbJcIIHePwYtwoqFwmB6MyPvPYuIpZ1j8lAMWJvS9Fu0lBgjPc75Dzt6hFZ314G0pp7Y6sQ3BuWPBFb6GlThE/D6079TJ/rQ1w= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from host014-ubuntu-1804.lxd (unknown [10.12.130.31]) by app1 (Coremail) with SMTP id TAJkCgAHbkVlZUBlpH4BAA--.9066S4; Tue, 31 Oct 2023 10:24:38 +0800 (CST) From: Li Xu To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, palmer@dabbelt.com, juzhe.zhong@rivai.ai, xuli Subject: [PATCH V5] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Date: Tue, 31 Oct 2023 02:24:36 +0000 Message-Id: <20231031022436.18525-1-xuli1@eswincomputing.com> X-Mailer: git-send-email 2.17.1 X-CM-TRANSID:TAJkCgAHbkVlZUBlpH4BAA--.9066S4 X-Coremail-Antispam: 1UD129KBjvAXoWDAw43KrW7uFWDtr43XFyDtrb_yoWrKw47Go Z3ursYyFW3Wr1I9rs8K34xWrs8Gr40krsxXFZ3ZFyUGFn7A3Z0ya4fKw1fur13ur4ftFW3 u3sxAFW8Aa48JF1rn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUY87AC8VAFwI0_Gr0_Xr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8 Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26r xl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj 6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr 0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm-wCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7VUbXdbUUUUUU== X-CM-SenderInfo: 50xoxi46hv4xpqfrz1xxwl0woofrz/ X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_ASCII_DIVIDERS,KAM_DMARC_STATUS,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SCC_10_SHORT_WORD_LINES,SCC_5_SHORT_WORD_LINES,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: xuli Update in v5: * Split has_vxrm_or_frm_p into maybe_require_frm_p and maybe_require_vxrm_p. * Adjust comments. Update in v4: * Remove class function_resolver. * Remove function get_non_overloaded_instance. * Add overloaded hash traits for non-overloaded intrinsic. * All overloaded intrinsics are implemented, and the tests pass. Update in v3: * Rewrite comment for overloaded function add. * Move get_non_overloaded_instance to function_base. Update in v2: * Add get_non_overloaded_instance for function instance. * Fix overload check for policy function. * Enrich the test cases check. Original log: This patch would like add the framework to support the RVV overloaded intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did. However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN with below steps. * Register overloaded functions. * Add function_resolver for overloaded function resolving. * Add resolve API for function shape with default implementation. * Implement HOOK for navigating the overloaded API to non-overloaded API. gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook. (riscv_register_pragmas): Register the hook. * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl. * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Register overloaded function. * config/riscv/riscv-vector-builtins.cc (struct non_overloaded_registered_function_hasher): New hash table. (function_builder::add_function): Add overloaded arg. (function_builder::add_unique_function): Map overloaded function to non-overloaded function. (function_builder::add_overloaded_function): New API impl. (registered_function::overloaded_hash): Calculate hash value. (maybe_require_frm_p): New function impl. (maybe_require_vxrm_p): Ditto. (has_vxrm_or_frm_p): Ditto. (non_overloaded_registered_function_hasher::hash): Ditto. (non_overloaded_registered_function_hasher::equal): Ditto. (handle_pragma_vector): Allocate space for hash table. (resolve_overloaded_builtin): New function impl. * config/riscv/riscv-vector-builtins.h: Add additional parameters to add_function. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c: New test. * gcc.target/riscv/rvv/base/overloaded_vadd.h: New test. * gcc.target/riscv/rvv/base/overloaded_vfadd.h: New test. * gcc.target/riscv/rvv/base/overloaded_vget_vset.h: New test. * gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h: New test. * gcc.target/riscv/rvv/base/overloaded_vmv.h: New test. * gcc.target/riscv/rvv/base/overloaded_vreinterpret.h: New test. Signed-off-by: Li Xu Co-Authored-By: Pan Li --- gcc/config/riscv/riscv-c.cc | 36 ++- gcc/config/riscv/riscv-protos.h | 1 + .../riscv/riscv-vector-builtins-shapes.cc | 1 + gcc/config/riscv/riscv-vector-builtins.cc | 259 +++++++++++++++++- gcc/config/riscv/riscv-vector-builtins.h | 5 +- .../riscv/rvv/base/overloaded_rv32_vadd.c | 12 + .../riscv/rvv/base/overloaded_rv32_vfadd.c | 12 + .../rvv/base/overloaded_rv32_vget_vset.c | 7 + .../rvv/base/overloaded_rv32_vloxseg2ei16.c | 11 + .../riscv/rvv/base/overloaded_rv32_vmv.c | 10 + .../rvv/base/overloaded_rv32_vreinterpret.c | 10 + .../riscv/rvv/base/overloaded_rv64_vadd.c | 11 + .../riscv/rvv/base/overloaded_rv64_vfadd.c | 11 + .../rvv/base/overloaded_rv64_vget_vset.c | 6 + .../rvv/base/overloaded_rv64_vloxseg2ei16.c | 10 + .../riscv/rvv/base/overloaded_rv64_vmv.c | 10 + .../rvv/base/overloaded_rv64_vreinterpret.c | 9 + .../riscv/rvv/base/overloaded_vadd.h | 59 ++++ .../riscv/rvv/base/overloaded_vfadd.h | 67 +++++ .../riscv/rvv/base/overloaded_vget_vset.h | 27 ++ .../riscv/rvv/base/overloaded_vloxseg2ei16.h | 39 +++ .../riscv/rvv/base/overloaded_vmv.h | 26 ++ .../riscv/rvv/base/overloaded_vreinterpret.h | 29 ++ 23 files changed, 659 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index 283052ae313..bedf7217390 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -215,16 +215,50 @@ riscv_check_builtin_call (location_t loc, vec arg_loc, tree fndecl, case RISCV_BUILTIN_VECTOR: return riscv_vector::check_builtin_call (loc, arg_loc, subcode, - orig_fndecl, nargs, args); + fndecl, nargs, args); } gcc_unreachable (); } +/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */ +static tree +riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl, + void *uncast_arglist) +{ + vec empty = {}; + location_t loc = (location_t) uncast_location; + vec *arglist = (vec *) uncast_arglist; + unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); + unsigned int subcode = code >> RISCV_BUILTIN_SHIFT; + tree new_fndecl = NULL_TREE; + + if (!arglist) + arglist = ∅ + + switch (code & RISCV_BUILTIN_CLASS) + { + case RISCV_BUILTIN_GENERAL: + break; + case RISCV_BUILTIN_VECTOR: + new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist); + break; + default: + gcc_unreachable (); + } + + if (new_fndecl == NULL_TREE) + return new_fndecl; + + return build_function_call_vec (loc, vNULL, new_fndecl, arglist, NULL, + fndecl); +} + /* Implement REGISTER_TARGET_PRAGMAS. */ void riscv_register_pragmas (void) { + targetm.resolve_overloaded_builtin = riscv_resolve_overloaded_builtin; targetm.check_builtin_call = riscv_check_builtin_call; c_register_pragma ("riscv", "intrinsic", riscv_pragma_intrinsic); } diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 2926d5d50d5..5836333bc5d 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -430,6 +430,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *); rtx expand_builtin (unsigned int, tree, rtx); bool check_builtin_call (location_t, vec, unsigned int, tree, unsigned int, tree *); +tree resolve_overloaded_builtin (unsigned int, vec *); bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT); bool legitimize_move (rtx, rtx *); void emit_vlmax_vsetvl (machine_mode, rtx); diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index 0bda934ae16..ee570458ce9 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -49,6 +49,7 @@ build_one (function_builder &b, const function_group_info &group, group.ops_infos.types[vec_type_idx].index); b.allocate_argument_types (function_instance, argument_types); b.apply_predication (function_instance, return_type, argument_types); + b.add_overloaded_function (function_instance, *group.shape); b.add_unique_function (function_instance, (*group.shape), return_type, argument_types); } diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 5d4dc264fa6..5c70f7a9c6c 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -80,6 +80,32 @@ public: /* The decl itself. */ tree GTY ((skip)) decl; + + /* The overload hash of non-overloaded intrinsic is determined by + the overload name and argument list. Adding the overload name to + the hash is also to address the following situations: + vint16mf4_t __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src); + vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src); + The base, shape and argument list of the vreinterpret instance are + the same, only the overload name is different. Therefore, it is + enough to add overload_name and argument list to the hash value.*/ + const char *overload_name; + + /* The argument list part of the hash value. Add the unsigned/signed type + and machine mode of each argument to the hash value. */ + vec GTY ((skip)) argument_types; + + /* True if the decl represents an overloaded function that needs to be + resolved. */ + bool overloaded_p; + + /* The hash value to indicate the non-overloaded function. Generate hash value + based on overload_name and argument_types. */ + hashval_t overloaded_hash () const; + + /* Generate hash value based on the overload_name and the argument list passed + by the user when calling. */ + hashval_t overloaded_hash (const vec &); }; /* Hash traits for registered_function. */ @@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash static bool equal (value_type, const compare_type &); }; +/* Hash traits for overload registered_function. */ +struct non_overloaded_registered_function_hasher + : nofree_ptr_hash +{ + static hashval_t hash (value_type); + static bool equal (value_type, const compare_type &); +}; + /* Static information about each RVV type. */ static CONSTEXPR const vector_type_info vector_types[] = { #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...) \ @@ -2611,6 +2645,12 @@ static GTY (()) vec *registered_functions; overloaded functions. */ static hash_table *function_table; +/* All registered function decls, hashed on overload_name and argument list + of the registered_function. This is used for looking up implementations + of non-overloaded functions. */ +static hash_table + *non_overloaded_function_table; + /* RAII class for enabling enough RVV features to define the built-in types and implement the riscv_vector.h pragma. @@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance) registered_function & function_builder::add_function (const function_instance &instance, const char *name, tree fntype, tree attrs, - bool placeholder_p) + bool placeholder_p, const char *overload_name, + const vec &argument_types, + bool overloaded_p = false) { unsigned int code = vec_safe_length (registered_functions); code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR; @@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance, registered_function &rfn = *ggc_alloc (); rfn.instance = instance; rfn.decl = decl; + rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL; + rfn.argument_types = argument_types; + rfn.overloaded_p = overloaded_p; vec_safe_push (registered_functions, &rfn); return rfn; @@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance, if (!check_required_extensions (instance)) return; + /* Also add the function under its overloaded alias, if we want + a separate decl for each instance of an overloaded function. */ + char *overload_name = shape->get_name (*this, instance, true); + /* Add the function under its full (unique) name. */ char *name = shape->get_name (*this, instance, false); tree fntype @@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance, argument_types.address ()); tree attrs = get_attributes (instance); registered_function &rfn - = add_function (instance, name, fntype, attrs, false); + = add_function (instance, name, fntype, attrs, false, overload_name, + argument_types.copy ()); /* Enter the function into the hash table. */ hashval_t hash = instance.hash (); @@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance, gcc_assert (!*rfn_slot); *rfn_slot = &rfn; - /* Also add the function under its overloaded alias, if we want - a separate decl for each instance of an overloaded function. */ - char *overload_name = shape->get_name (*this, instance, true); if (overload_name) { /* Attribute lists shouldn't be shared. */ tree attrs = get_attributes (instance); bool placeholder_p = !m_direct_overloads; - add_function (instance, overload_name, fntype, attrs, placeholder_p); + add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL, + vNULL); + + /* Enter the function into the non-overloaded hash table. */ + hash = rfn.overloaded_hash (); + rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash, + INSERT); + gcc_assert (!*rfn_slot); + *rfn_slot = &rfn; } obstack_free (&m_string_obstack, name); } +/* Add overloaded function for gcc. */ +void +function_builder::add_overloaded_function (const function_instance &instance, + const function_shape *shape) +{ + if (!check_required_extensions (instance)) + return; + + char *name = shape->get_name (*this, instance, true); + + if (name) + { + /* To avoid API conflicting, take void return type and void argument + for the overloaded function. */ + tree fntype = build_function_type (void_type_node, void_list_node); + add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name, + vNULL, true); + obstack_free (&m_string_obstack, name); + } +} + function_call_info::function_call_info (location_t location_in, const function_instance &instance_in, tree fndecl_in) @@ -3991,6 +4067,155 @@ registered_function_hasher::equal (value_type value, const compare_type &key) return value->instance == key; } +hashval_t +registered_function::overloaded_hash () const +{ + inchash::hash h; + tree type; + unsigned int unsigned_p, mode_p; + h.add (overload_name, strlen (overload_name)); + for (unsigned int i = 0; i < argument_types.length (); i++) + { + type = argument_types[i]; + unsigned_p = POINTER_TYPE_P (type) ? TYPE_UNSIGNED (TREE_TYPE (type)) + : TYPE_UNSIGNED (type); + mode_p = POINTER_TYPE_P (type) ? TYPE_MODE (TREE_TYPE (type)) + : TYPE_MODE (type); + h.add_int (unsigned_p); + h.add_int (mode_p); + } + + return h.end (); +} + +static bool +maybe_require_frm_p (function_instance &instance) +{ + return instance.base == bases::vfwredusum + || instance.base == bases::vfwredosum || instance.base == bases::vfadd + || instance.base == bases::vfwsub || instance.base == bases::vfwnmsac + || instance.base == bases::vfwnmacc || instance.base == bases::vfwmul + || instance.base == bases::vfcvt_x || instance.base == bases::vfcvt_f + || instance.base == bases::vfcvt_xu || instance.base == bases::vfwmsac + || instance.base == bases::vfwmacc || instance.base == bases::vfwcvt_x + || instance.base == bases::vfwadd || instance.base == bases::vfsub + || instance.base == bases::vfsqrt || instance.base == bases::vfredusum + || instance.base == bases::vfrsub || instance.base == bases::vfredosum + || instance.base == bases::vfrec7 || instance.base == bases::vfrdiv + || instance.base == bases::vfnmsub || instance.base == bases::vfnmsac + || instance.base == bases::vfnmadd || instance.base == bases::vfnmacc + || instance.base == bases::vfncvt_f || instance.base == bases::vfncvt_x + || instance.base == bases::vfncvt_xu || instance.base == bases::vfmul + || instance.base == bases::vfmsub || instance.base == bases::vfmsac + || instance.base == bases::vfmadd || instance.base == bases::vfmacc + || instance.base == bases::vfdiv || instance.base == bases::vfwcvt_xu; +} + +static bool +maybe_require_vxrm_p (function_instance &instance) +{ + return instance.base == bases::vaadd || instance.base == bases::vaaddu + || instance.base == bases::vasub || instance.base == bases::vasubu + || instance.base == bases::vssrl || instance.base == bases::vssra + || instance.base == bases::vsmul || instance.base == bases::vnclipu + || instance.base == bases::vnclip; +} + +bool +has_vxrm_or_frm_p (function_instance &instance, const vec &arglist) +{ + if (maybe_require_vxrm_p (instance) + || (maybe_require_frm_p (instance) + && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2])) + == INTEGER_TYPE))) + return true; + return false; +} + +hashval_t +registered_function::overloaded_hash (const vec &arglist) +{ + argument_types = vNULL; + unsigned int len = arglist.length (); + + for (unsigned int i = 0; i < len; i++) + { + /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index); + When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1) + form is used. The compiler recognizes that the parameter index is signed + int, which is inconsistent with size_t, so the index is converted to + size_t type in order to get correct hash value. vint8m2_t + __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason + is the same as above. */ + if ((instance.base == bases::vget && (i == (len - 1))) + || (instance.base == bases::vset && (i == (len - 2)))) + argument_types.safe_push (size_type_node); + /* Vector fixed-point arithmetic instructions requiring argument vxrm. + For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2, + vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu + intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler + recognizes that the parameter vxrm is a signed int, which is inconsistent + with the parameter unsigned int vxrm declared by intrinsic, so the + parameter vxrm is converted to an unsigned int type in order to get + correct hash value. + + Vector Floating-Point Instructions requiring argument frm. + DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops) + DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops) + Taking vfadd as an example, theoretically we can add base or shape to the + hash value to distinguish whether the frm parameter is required. + vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl); + vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int + frm, size_t vl); + + However, the current registration mechanism of overloaded intinsic for gcc + limits the intrinsic obtained by entering the hook to always be vfadd, not + vfadd_frm. Therefore, the correct hash value cannot be obtained through the + parameter list and overload name, base or shape. + +--------+---------------------------+-------------------+ + | index | name | kind | + +--------+---------------------------+-------------------+ + | 124733 | __riscv_vfadd | Overloaded | <- Hook fun code + +--------+---------------------------+-------------------+ + | 124735 | __riscv_vfadd_vv_f32m1 | Non-overloaded | + +--------+---------------------------+-------------------+ + | 124737 | __riscv_vfadd | Placeholder | + +--------+---------------------------+-------------------+ + | ... | + +--------+---------------------------+-------------------+ + | ... | + +--------+---------------------------+-------------------+ + | 125739 | __riscv_vfadd | Overloaded | + +--------+---------------------------+-------------------+ + | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded | + +--------+---------------------------+-------------------+ + | 125743 | __riscv_vfadd | Placeholder | + +--------+---------------------------+-------------------+ + + Therefore, the hash value cannot be added with base or shape, and needs + to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */ + else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2))) + argument_types.safe_push (unsigned_type_node); + else + argument_types.safe_push (TREE_TYPE (arglist[i])); + } + return overloaded_hash (); +} + +inline hashval_t +non_overloaded_registered_function_hasher::hash (value_type value) +{ + return value->overloaded_hash (); +} + +inline bool +non_overloaded_registered_function_hasher::equal (value_type value, + const compare_type &key) +{ + return ((strcmp (value->overload_name, key->overload_name) == 0) + && value->overloaded_hash () == key->overloaded_hash ()); +} + /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name, otherwise return NULL. */ const char * @@ -4139,7 +4364,7 @@ register_frm () void handle_pragma_vector () { - if (function_table) + if (function_table || non_overloaded_function_table) { error ("duplicate definition of %qs", "riscv_vector.h"); return; @@ -4156,6 +4381,8 @@ handle_pragma_vector () /* Define the functions. */ function_table = new hash_table (1023); + non_overloaded_function_table + = new hash_table (1023); function_builder builder; for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i) builder.register_function_group (function_groups[i]); @@ -4208,6 +4435,24 @@ check_builtin_call (location_t location, vec, unsigned int code, TREE_TYPE (rfn.decl), nargs, args).check (); } +tree +resolve_overloaded_builtin (unsigned int code, vec *arglist) +{ + if (code >= vec_safe_length (registered_functions)) + return NULL_TREE; + + registered_function *rfun = (*registered_functions)[code]; + + if (!rfun || !rfun->overloaded_p) + return NULL_TREE; + + hashval_t hash = rfun->overloaded_hash (*arglist); + registered_function *rfn + = non_overloaded_function_table->find_with_hash (rfun, hash); + gcc_assert (rfn); + return rfn->decl; +} + function_instance get_read_vl_instance (void) { diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index e358a8e4d91..4f41e880ac3 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -277,6 +277,8 @@ public: void apply_predication (const function_instance &, tree, vec &) const; void add_unique_function (const function_instance &, const function_shape *, tree, vec &); + void add_overloaded_function (const function_instance &, + const function_shape *); void register_function_group (const function_group_info &); void append_name (const char *); void append_base_name (const char *); @@ -288,7 +290,8 @@ private: tree get_attributes (const function_instance &); registered_function &add_function (const function_instance &, const char *, - tree, tree, bool); + tree, tree, bool, const char *, + const vec &, bool); /* True if we should create a separate decl for each instance of an overloaded function, instead of using function_builder. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c new file mode 100644 index 00000000000..5f10aa9bf35 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ + +#include "overloaded_vadd.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 6 } } */ +/* { dg-final { scan-assembler-times {vadd\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[ax][0-9]+} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c new file mode 100644 index 00000000000..bea35a13a7b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ + +#include "overloaded_vfadd.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf4,\s*ta,\s*ma} 16 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c new file mode 100644 index 00000000000..6b0ba142b90 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ + +#include "overloaded_vget_vset.h" + +/* { dg-final { scan-assembler-times {vl[0-9]+re[0-9]+\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 14 } } */ +/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 13 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c new file mode 100644 index 00000000000..a20e4a3bb4f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ + +#include "overloaded_vloxseg2ei16.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*mu} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*mu} 1 } } */ +/* { dg-final { scan-assembler-times {vloxseg2ei16\.v\s+v[0-9]+,\s*\([ax][0-9]+\),\s*v[0-9]+} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c new file mode 100644 index 00000000000..237b34dbe91 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ + +#include "overloaded_vmv.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*tu,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*0,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c new file mode 100644 index 00000000000..42d50589246 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ + +#include "overloaded_vreinterpret.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf2,\s*ta,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c new file mode 100644 index 00000000000..c4555e3f477 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c @@ -0,0 +1,11 @@ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "overloaded_vadd.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 6 } } */ +/* { dg-final { scan-assembler-times {vadd\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[ax][0-9]+} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c new file mode 100644 index 00000000000..ca98136ce9b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c @@ -0,0 +1,11 @@ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "overloaded_vfadd.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf4,\s*ta,\s*ma} 16 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 8 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*mu} 2 } } */ +/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 12 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c new file mode 100644 index 00000000000..1cb4225084c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c @@ -0,0 +1,6 @@ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "overloaded_vget_vset.h" + +/* { dg-final { scan-assembler-times {vl[0-9]+re[0-9]+\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 14 } } */ +/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 13 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c new file mode 100644 index 00000000000..ea73170444d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c @@ -0,0 +1,10 @@ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "overloaded_vloxseg2ei16.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*mu} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*mu} 1 } } */ +/* { dg-final { scan-assembler-times {vloxseg2ei16\.v\s+v[0-9]+,\s*\([ax][0-9]+\),\s*v[0-9]+} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c new file mode 100644 index 00000000000..c5da6bbfca8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "overloaded_vmv.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*tu,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*0,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c new file mode 100644 index 00000000000..3b8399c126d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c @@ -0,0 +1,9 @@ +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "overloaded_vreinterpret.h" + +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf2,\s*ta,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h new file mode 100644 index 00000000000..3b41cff1b62 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h @@ -0,0 +1,59 @@ +#include "riscv_vector.h" + +vint8m1_t test_vadd_vv_i8m1(vint8m1_t vs2, vint8m1_t vs1, size_t vl) { + return __riscv_vadd(vs2, vs1, vl); +} + +vint8m1_t test_vadd_vx_i8m1(vint8m1_t vs2, int8_t rs1, size_t vl) { + return __riscv_vadd(vs2, rs1, vl); +} + +vint8m1_t test_vadd_vv_i8m1_m(vbool8_t vm, vint8m1_t vs2, vint8m1_t vs1, + size_t vl) { + return __riscv_vadd(vm, vs2, vs1, vl); +} + +vint8m1_t test_vadd_vx_i8m1_m(vbool8_t vm, vint8m1_t vs2, int8_t rs1, + size_t vl) { + return __riscv_vadd(vm, vs2, rs1, vl); +} + +vint8m1_t test_vadd_vv_i8m1_tu(vint8m1_t vd, vint8m1_t vs2, vint8m1_t vs1, + size_t vl) { + return __riscv_vadd_tu(vd, vs2, vs1, vl); +} + +vint8m1_t test_vadd_vx_i8m1_tu(vint8m1_t vd, vint8m1_t vs2, int8_t rs1, + size_t vl) { + return __riscv_vadd_tu(vd, vs2, rs1, vl); +} + +vint8m1_t test_vadd_vv_i8m1_tum(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, + vint8m1_t vs1, size_t vl) { + return __riscv_vadd_tum(vm, vd, vs2, vs1, vl); +} + +vint8m1_t test_vadd_vx_i8m1_tum(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, + int8_t rs1, size_t vl) { + return __riscv_vadd_tum(vm, vd, vs2, rs1, vl); +} + +vint8m1_t test_vadd_vv_i8m1_mu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, + vint8m1_t vs1, size_t vl) { + return __riscv_vadd_mu(vm, vd, vs2, vs1, vl); +} + +vint8m1_t test_vadd_vx_i8m1_mu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, + int8_t rs1, size_t vl) { + return __riscv_vadd_mu(vm, vd, vs2, rs1, vl); +} + +vint8m1_t test_vadd_vv_i8m1_tumu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, + vint8m1_t vs1, size_t vl) { + return __riscv_vadd_tumu(vm, vd, vs2, vs1, vl); +} + +vint8m1_t test_vadd_vx_i8m1_tumu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, + int8_t rs1, size_t vl) { + return __riscv_vadd_tumu(vm, vd, vs2, rs1, vl); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h new file mode 100644 index 00000000000..798af420f2d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h @@ -0,0 +1,67 @@ +#include "riscv_vector.h" + +vfloat16mf4_t test_vfadd_vv_f16mf4(vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd(vs2, vs1, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_m(vbool64_t vm, vfloat16mf4_t vs2, + vfloat16mf4_t vs1, size_t vl) { + return __riscv_vfadd(vm, vs2, vs1, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_tu(vfloat16mf4_t vd, vfloat16mf4_t vs2, + vfloat16mf4_t vs1, size_t vl) { + return __riscv_vfadd_tu(vd, vs2, vs1, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_tum(vbool64_t vm, vfloat16mf4_t vd, + vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd_tum(vm, vd, vs2, vs1, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_tumu(vbool64_t vm, vfloat16mf4_t vd, + vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd_tumu(vm, vd, vs2, vs1, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_mu(vbool64_t vm, vfloat16mf4_t vd, + vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd_mu(vm, vd, vs2, vs1, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_rm(vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd(vs2, vs1, __RISCV_FRM_RNE, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_rm_m(vbool64_t vm, vfloat16mf4_t vs2, + vfloat16mf4_t vs1, size_t vl) { + return __riscv_vfadd(vm, vs2, vs1, __RISCV_FRM_RNE, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_rm_tu(vfloat16mf4_t vd, vfloat16mf4_t vs2, + vfloat16mf4_t vs1, size_t vl) { + return __riscv_vfadd_tu(vd, vs2, vs1, __RISCV_FRM_RNE, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_rm_tum(vbool64_t vm, vfloat16mf4_t vd, + vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd_tum(vm, vd, vs2, vs1, __RISCV_FRM_RNE, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_rm_tumu(vbool64_t vm, vfloat16mf4_t vd, + vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd_tumu(vm, vd, vs2, vs1, __RISCV_FRM_RNE, vl); +} + +vfloat16mf4_t test_vfadd_vv_f16mf4_rm_mu(vbool64_t vm, vfloat16mf4_t vd, + vfloat16mf4_t vs2, vfloat16mf4_t vs1, + size_t vl) { + return __riscv_vfadd_mu(vm, vd, vs2, vs1, __RISCV_FRM_RNE, vl); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h new file mode 100644 index 00000000000..01e072eb38f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h @@ -0,0 +1,27 @@ +#include "riscv_vector.h" + +vfloat16m1_t test_vget_v_f16m2_f16m1(vfloat16m2_t src, size_t index) { + return __riscv_vget_f16m1(src, 0); +} + +vint64m1_t test_vget_v_i64m4_i64m1(vint64m4_t src, size_t index) { + return __riscv_vget_i64m1(src, 0); +} + +vfloat16m1_t test_vget_v_f16m1x4_f16m1(vfloat16m1x4_t src, size_t index) { + return __riscv_vget_f16m1(src, 0); +} + +vint8m2_t test_vget_v_i8m2x3_i8m2(vint8m2x3_t src, size_t index) { + return __riscv_vget_i8m2(src, 0); +} + +vfloat16m2_t test_vset_v_f16m1_f16m2(vfloat16m2_t dest, size_t index, + vfloat16m1_t value) { + return __riscv_vset(dest, 0, value); +} + +vfloat64m1x7_t test_vset_v_f64m1_f64m1x7(vfloat64m1x7_t dest, size_t index, + vfloat64m1_t value) { + return __riscv_vset(dest, 0, value); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h new file mode 100644 index 00000000000..2ebcdb41795 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h @@ -0,0 +1,39 @@ +#include "riscv_vector.h" + +typedef _Float16 float16_t; +typedef float float32_t; +typedef double float64_t; + +vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2(const float64_t *rs1, + vuint16m1_t rs2, size_t vl) { + return __riscv_vloxseg2ei16(rs1, rs2, vl); +} + +vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_m(vbool16_t vm, const float64_t *rs1, + vuint16m1_t rs2, size_t vl) { + return __riscv_vloxseg2ei16(vm, rs1, rs2, vl); +} + +vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_tum(vbool16_t vm, vfloat64m4x2_t vd, + const float64_t *rs1, + vuint16m1_t rs2, size_t vl) { + return __riscv_vloxseg2ei16_tum(vm, vd, rs1, rs2, vl); +} + +vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_tumu(vbool16_t vm, vfloat64m4x2_t vd, + const float64_t *rs1, + vuint16m1_t rs2, size_t vl) { + return __riscv_vloxseg2ei16_tumu(vm, vd, rs1, rs2, vl); +} + +vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_mu(vbool16_t vm, vfloat64m4x2_t vd, + const float64_t *rs1, + vuint16m1_t rs2, size_t vl) { + return __riscv_vloxseg2ei16_mu(vm, vd, rs1, rs2, vl); +} + +vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_tu(vfloat64m4x2_t vd, + const float64_t *rs1, + vuint16m1_t rs2, size_t vl) { + return __riscv_vloxseg2ei16_tu(vd, rs1, rs2, vl); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h new file mode 100644 index 00000000000..fd3f1d28c0a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h @@ -0,0 +1,26 @@ +#include "riscv_vector.h" + +vint8m1_t test_vmv_v_v_i8m1 (vint8m1_t vs1, size_t vl) { + return __riscv_vmv_v (vs1, vl); +} + +vint8m1_t test_vmv_v_v_i8m1_tu (vint8m1_t vd, vint8m1_t vs1, size_t vl) { + return __riscv_vmv_v_tu(vd, vs1, vl); +} + +vfloat16m1_t test_vmv_v_v_f16m1 (vfloat16m1_t vs1, size_t vl) { + return __riscv_vmv_v (vs1, vl); +} + +vfloat16m1_t test_vmv_v_v_f16m1_tu (vfloat16m1_t vd, vfloat16m1_t vs1, + size_t vl) { + return __riscv_vmv_v_tu (vd, vs1, vl); +} + +int8_t test_vmv_x_s_i8m1_i8(vint8m1_t vs1) { + return __riscv_vmv_x (vs1); +} + +vint8m1_t test_vmv_s_x_i8m1_tu(vint8m1_t vd, int8_t rs1, size_t vl) { + return __riscv_vmv_s_tu(vd, rs1, vl); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h new file mode 100644 index 00000000000..904b0ceee72 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h @@ -0,0 +1,29 @@ +#include "riscv_vector.h" + +vuint16m1_t test_vreinterpret_v_b2_u16m1(vbool2_t src) { + return __riscv_vreinterpret_u16m1(src); +} + +vbool4_t test_vreinterpret_v_i32m1_b4(vint32m1_t src) { + return __riscv_vreinterpret_b4(src); +} + +vint8mf2_t test_vreinterpret_v_i16mf2_i8mf2(vint16mf2_t src) { + return __riscv_vreinterpret_i8mf2(src); +} + +vint32mf2_t test_vreinterpret_v_i16mf2_i32mf2(vint16mf2_t src) { + return __riscv_vreinterpret_i32mf2(src); +} + +vint32m1_t test_vreinterpret_v_i16m1_i32m1(vint16m1_t src) { + return __riscv_vreinterpret_i32m1(src); +} + +vint8m4_t test_vreinterpret_v_i32m4_i8m4(vint32m4_t src) { + return __riscv_vreinterpret_i8m4(src); +} + +vuint8m8_t test_vreinterpret_v_u32m8_u8m8(vuint32m8_t src) { + return __riscv_vreinterpret_u8m8(src); +} -- 2.17.1