From patchwork Wed Jan 19 17:47:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 50246 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1015B3857C66 for ; Wed, 19 Jan 2022 17:48:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1015B3857C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1642614521; bh=/ME6aJsLARLVQuUVr/Pi6OR60Vp6au8yfJ7fnd3QMjs=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=rdk2V78mYVVpqxc3dBKdZf2RZB6jXxuzxSpwxUe1UcY8KZYgfuV+4NjX7/lfSnj39 aB6aX8g2mZA+wp0jXJIq+U1ux4yg8B+iOfBe0DNGYrQJYuOBuw4YIUWvt4DkYN0OT2 gv9nuEkT8ijvGDE/PbG1OJZfmigRjvJL8LguXZtI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 43DF83858029 for ; Wed, 19 Jan 2022 17:47:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 43DF83858029 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 20JHk1QW023160; Wed, 19 Jan 2022 17:47:39 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3dppmhgyxe-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 19 Jan 2022 17:47:38 +0000 Received: from m0098394.ppops.net (m0098394.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 20JHk6No024889; Wed, 19 Jan 2022 17:47:38 GMT Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 3dppmhgyx8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 19 Jan 2022 17:47:38 +0000 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 20JHhFqX023809; Wed, 19 Jan 2022 17:47:37 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma03dal.us.ibm.com with ESMTP id 3dknwd0hdy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 19 Jan 2022 17:47:37 +0000 Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 20JHlawv35127680 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 19 Jan 2022 17:47:36 GMT Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 616F36E052; Wed, 19 Jan 2022 17:47:36 +0000 (GMT) Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1E69E6E050; Wed, 19 Jan 2022 17:47:35 +0000 (GMT) Received: from [9.211.104.235] (unknown [9.211.104.235]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 19 Jan 2022 17:47:35 +0000 (GMT) Message-ID: <4cfd2321-37c4-d6a9-5b6c-a3f31d9bd160@linux.ibm.com> Date: Wed, 19 Jan 2022 11:47:35 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 To: GCC Patches Subject: [PATCH v2] rs6000: More factoring of overload processing X-TM-AS-GCONF: 00 X-Proofpoint-GUID: cqduJfmskfyCCsTp6PgTgnyhh5sGDMog X-Proofpoint-ORIG-GUID: rkeBfSKy1lPyd_5AxLg1i2uIxivYMzgu X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-19_10,2022-01-19_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxscore=0 suspectscore=0 phishscore=0 malwarescore=0 spamscore=0 adultscore=0 priorityscore=1501 clxscore=1015 lowpriorityscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2201190099 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Bill Schmidt via Gcc-patches From: "Li, Pan2 via Gcc-patches" Reply-To: wschmidt@linux.ibm.com Cc: David Edelsohn , Segher Boessenkool Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi! [I'm resubmitting this because the filename changed with the recent conversion from .c to .cc.] This patch continues the refactoring started with r12-6014. I had previously noted that the resolve_vec* routines can be further simplified by processing the argument list earlier, so that all routines can use the arrays of arguments and types. I found that this was useful for some of the routines, but not for all of them. For several of the special-cased overloads, we don't specify all of the possible type combinations in rs6000-overload.def, because the types don't matter for the expansion we do. For these, we can't use generic error message handling when the number of arguments is incorrect, because the result is misleading error messages that indicate argument types are wrong. So this patch goes halfway and improves the factoring on the remaining special cases, but leaves vec_splats, vec_promote, vec_extract, vec_insert, and vec_step alone. Bootstrapped and tested on powerpc64le-linux-gnu. Is this okay for trunk? Thanks, Bill 2022-01-18 Bill Schmidt gcc/ * config/rs6000/rs6000-c.cc (resolve_vec_mul): Accept args and types parameters instead of arglist and nargs. Simplify accordingly. Remove unnecessary test for argument count mismatch. (resolve_vec_cmpne): Likewise. (resolve_vec_adde_sube): Likewise. (resolve_vec_addec_subec): Likewise. (altivec_resolve_overloaded_builtin): Move overload special handling after the gathering of arguments into args[] and types[] and the test for correct number of arguments. Don't perform the test for correct number of arguments for certain special cases. Call the other special cases with args and types instead of arglist and nargs. --- gcc/config/rs6000/rs6000-c.cc | 304 ++++++++++++++-------------------- 1 file changed, 127 insertions(+), 177 deletions(-) diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 145421ab8f2..35c1383f059 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -939,37 +939,25 @@ altivec_build_resolved_builtin (tree *args, int n, tree fntype, tree ret_type, enum resolution { unresolved, resolved, resolved_bad }; /* Resolve an overloaded vec_mul call and return a tree expression for the - resolved call if successful. NARGS is the number of arguments to the call. - ARGLIST contains the arguments. RES must be set to indicate the status of + resolved call if successful. ARGS contains the arguments to the call. + TYPES contains their types. RES must be set to indicate the status of the resolution attempt. LOC contains statement location information. */ static tree -resolve_vec_mul (resolution *res, vec *arglist, unsigned nargs, - location_t loc) +resolve_vec_mul (resolution *res, tree *args, tree *types, location_t loc) { /* vec_mul needs to be special cased because there are no instructions for it for the {un}signed char, {un}signed short, and {un}signed int types. */ - if (nargs != 2) - { - error ("builtin %qs only accepts 2 arguments", "vec_mul"); - *res = resolved; - return error_mark_node; - } - - tree arg0 = (*arglist)[0]; - tree arg0_type = TREE_TYPE (arg0); - tree arg1 = (*arglist)[1]; - tree arg1_type = TREE_TYPE (arg1); /* Both arguments must be vectors and the types must be compatible. */ - if (TREE_CODE (arg0_type) != VECTOR_TYPE - || !lang_hooks.types_compatible_p (arg0_type, arg1_type)) + if (TREE_CODE (types[0]) != VECTOR_TYPE + || !lang_hooks.types_compatible_p (types[0], types[1])) { *res = resolved_bad; return error_mark_node; } - switch (TYPE_MODE (TREE_TYPE (arg0_type))) + switch (TYPE_MODE (TREE_TYPE (types[0]))) { case E_QImode: case E_HImode: @@ -978,21 +966,21 @@ resolve_vec_mul (resolution *res, vec *arglist, unsigned nargs, case E_TImode: /* For scalar types just use a multiply expression. */ *res = resolved; - return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0, - fold_convert (TREE_TYPE (arg0), arg1)); + return fold_build2_loc (loc, MULT_EXPR, types[0], args[0], + fold_convert (types[0], args[1])); case E_SFmode: { /* For floats use the xvmulsp instruction directly. */ *res = resolved; tree call = rs6000_builtin_decls[RS6000_BIF_XVMULSP]; - return build_call_expr (call, 2, arg0, arg1); + return build_call_expr (call, 2, args[0], args[1]); } case E_DFmode: { /* For doubles use the xvmuldp instruction directly. */ *res = resolved; tree call = rs6000_builtin_decls[RS6000_BIF_XVMULDP]; - return build_call_expr (call, 2, arg0, arg1); + return build_call_expr (call, 2, args[0], args[1]); } /* Other types are errors. */ default: @@ -1002,37 +990,25 @@ resolve_vec_mul (resolution *res, vec *arglist, unsigned nargs, } /* Resolve an overloaded vec_cmpne call and return a tree expression for the - resolved call if successful. NARGS is the number of arguments to the call. - ARGLIST contains the arguments. RES must be set to indicate the status of + resolved call if successful. ARGS contains the arguments to the call. + TYPES contains their types. RES must be set to indicate the status of the resolution attempt. LOC contains statement location information. */ static tree -resolve_vec_cmpne (resolution *res, vec *arglist, unsigned nargs, - location_t loc) +resolve_vec_cmpne (resolution *res, tree *args, tree *types, location_t loc) { /* vec_cmpne needs to be special cased because there are no instructions for it (prior to power 9). */ - if (nargs != 2) - { - error ("builtin %qs only accepts 2 arguments", "vec_cmpne"); - *res = resolved; - return error_mark_node; - } - - tree arg0 = (*arglist)[0]; - tree arg0_type = TREE_TYPE (arg0); - tree arg1 = (*arglist)[1]; - tree arg1_type = TREE_TYPE (arg1); /* Both arguments must be vectors and the types must be compatible. */ - if (TREE_CODE (arg0_type) != VECTOR_TYPE - || !lang_hooks.types_compatible_p (arg0_type, arg1_type)) + if (TREE_CODE (types[0]) != VECTOR_TYPE + || !lang_hooks.types_compatible_p (types[0], types[1])) { *res = resolved_bad; return error_mark_node; } - machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (arg0_type)); + machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (types[0])); /* Power9 instructions provide the most efficient implementation of ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode @@ -1060,8 +1036,8 @@ resolve_vec_cmpne (resolution *res, vec *arglist, unsigned nargs, /* call = vec_cmpeq (va, vb) result = vec_nor (call, call). */ vec *params = make_tree_vector (); - vec_safe_push (params, arg0); - vec_safe_push (params, arg1); + vec_safe_push (params, args[0]); + vec_safe_push (params, args[1]); tree decl = rs6000_builtin_decls[RS6000_OVLD_VEC_CMPEQ]; tree call = altivec_resolve_overloaded_builtin (loc, decl, params); /* Use save_expr to ensure that operands used more than once @@ -1088,46 +1064,30 @@ resolve_vec_cmpne (resolution *res, vec *arglist, unsigned nargs, return error_mark_node; } -/* Resolve an overloaded vec_adde or vec_sube call and return a tree - expression for the resolved call if successful. NARGS is the number of - arguments to the call. ARGLIST contains the arguments. RES must be set - to indicate the status of the resolution attempt. LOC contains statement - location information. */ +/* Resolve an overloaded vec_adde or vec_sube call and return a tree expression + for the resolved call if successful. ARGS contains the arguments to the + call. TYPES contains their arguments. RES must be set to indicate the + status of the resolution attempt. LOC contains statement location + information. */ static tree resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode, - vec *arglist, unsigned nargs, - location_t loc) + tree *args, tree *types, location_t loc) { /* vec_adde needs to be special cased because there is no instruction for the {un}signed int version. */ - if (nargs != 3) - { - const char *name; - name = fcode == RS6000_OVLD_VEC_ADDE ? "vec_adde" : "vec_sube"; - error ("builtin %qs only accepts 3 arguments", name); - *res = resolved; - return error_mark_node; - } - - tree arg0 = (*arglist)[0]; - tree arg0_type = TREE_TYPE (arg0); - tree arg1 = (*arglist)[1]; - tree arg1_type = TREE_TYPE (arg1); - tree arg2 = (*arglist)[2]; - tree arg2_type = TREE_TYPE (arg2); /* All 3 arguments must be vectors of (signed or unsigned) (int or __int128) and the types must be compatible. */ - if (TREE_CODE (arg0_type) != VECTOR_TYPE - || !lang_hooks.types_compatible_p (arg0_type, arg1_type) - || !lang_hooks.types_compatible_p (arg1_type, arg2_type)) + if (TREE_CODE (types[0]) != VECTOR_TYPE + || !lang_hooks.types_compatible_p (types[0], types[1]) + || !lang_hooks.types_compatible_p (types[1], types[2])) { *res = resolved_bad; return error_mark_node; } - switch (TYPE_MODE (TREE_TYPE (arg0_type))) + switch (TYPE_MODE (TREE_TYPE (types[0]))) { /* For {un}signed ints, vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb), @@ -1137,8 +1097,8 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode, case E_SImode: { vec *params = make_tree_vector (); - vec_safe_push (params, arg0); - vec_safe_push (params, arg1); + vec_safe_push (params, args[0]); + vec_safe_push (params, args[1]); tree add_sub_builtin; if (fcode == RS6000_OVLD_VEC_ADDE) @@ -1148,10 +1108,10 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode, tree call = altivec_resolve_overloaded_builtin (loc, add_sub_builtin, params); - tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1); - tree ones_vector = build_vector_from_val (arg0_type, const1); - tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type, - arg2, ones_vector); + tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1); + tree ones_vector = build_vector_from_val (types[0], const1); + tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0], + args[2], ones_vector); params = make_tree_vector (); vec_safe_push (params, call); vec_safe_push (params, and_expr); @@ -1175,45 +1135,29 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode, } /* Resolve an overloaded vec_addec or vec_subec call and return a tree - expression for the resolved call if successful. NARGS is the number of - arguments to the call. ARGLIST contains the arguments. RES must be set - to indicate the status of the resolution attempt. LOC contains statement - location information. */ + expression for the resolved call if successful. ARGS contains the arguments + to the call. TYPES contains their types. RES must be set to indicate the + status of the resolution attempt. LOC contains statement location + information. */ static tree resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode, - vec *arglist, unsigned nargs, - location_t loc) + tree *args, tree *types, location_t loc) { /* vec_addec and vec_subec needs to be special cased because there is no instruction for the (un)signed int version. */ - if (nargs != 3) - { - const char *name; - name = fcode == RS6000_OVLD_VEC_ADDEC ? "vec_addec" : "vec_subec"; - error ("builtin %qs only accepts 3 arguments", name); - *res = resolved; - return error_mark_node; - } - - tree arg0 = (*arglist)[0]; - tree arg0_type = TREE_TYPE (arg0); - tree arg1 = (*arglist)[1]; - tree arg1_type = TREE_TYPE (arg1); - tree arg2 = (*arglist)[2]; - tree arg2_type = TREE_TYPE (arg2); /* All 3 arguments must be vectors of (signed or unsigned) (int or __int128) and the types must be compatible. */ - if (TREE_CODE (arg0_type) != VECTOR_TYPE - || !lang_hooks.types_compatible_p (arg0_type, arg1_type) - || !lang_hooks.types_compatible_p (arg1_type, arg2_type)) + if (TREE_CODE (types[0]) != VECTOR_TYPE + || !lang_hooks.types_compatible_p (types[0], types[1]) + || !lang_hooks.types_compatible_p (types[1], types[2])) { *res = resolved_bad; return error_mark_node; } - switch (TYPE_MODE (TREE_TYPE (arg0_type))) + switch (TYPE_MODE (TREE_TYPE (types[0]))) { /* For {un}signed ints, vec_addec (va, vb, carryv) == @@ -1224,11 +1168,11 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode, { /* Use save_expr to ensure that operands used more than once that may have side effects (like calls) are only evaluated once. */ - arg0 = save_expr (arg0); - arg1 = save_expr (arg1); + args[0] = save_expr (args[0]); + args[1] = save_expr (args[1]); vec *params = make_tree_vector (); - vec_safe_push (params, arg0); - vec_safe_push (params, arg1); + vec_safe_push (params, args[0]); + vec_safe_push (params, args[1]); tree as_c_builtin; if (fcode == RS6000_OVLD_VEC_ADDEC) @@ -1239,8 +1183,8 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode, tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin, params); params = make_tree_vector (); - vec_safe_push (params, arg0); - vec_safe_push (params, arg1); + vec_safe_push (params, args[0]); + vec_safe_push (params, args[1]); tree as_builtin; if (fcode == RS6000_OVLD_VEC_ADDEC) @@ -1250,10 +1194,10 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode, tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin, params); - tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1); - tree ones_vector = build_vector_from_val (arg0_type, const1); - tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type, - arg2, ones_vector); + tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1); + tree ones_vector = build_vector_from_val (types[0], const1); + tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0], + args[2], ones_vector); params = make_tree_vector (); vec_safe_push (params, call2); vec_safe_push (params, and_expr); @@ -1783,78 +1727,15 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, "% is deprecated for little endian; use " "assignment for unaligned loads and stores"); - /* Some overloads require special handling. */ - /* FIXME: Could we simplify the helper functions if we gathered arguments - and types into arrays first? */ - tree returned_expr = NULL; - resolution res = unresolved; - vec *arglist = static_cast *> (passed_arglist); - unsigned int nargs = vec_safe_length (arglist); - - switch (fcode) - { - case RS6000_OVLD_VEC_MUL: - returned_expr = resolve_vec_mul (&res, arglist, nargs, loc); - break; - - case RS6000_OVLD_VEC_CMPNE: - returned_expr = resolve_vec_cmpne (&res, arglist, nargs, loc); - break; - - case RS6000_OVLD_VEC_ADDE: - case RS6000_OVLD_VEC_SUBE: - returned_expr = resolve_vec_adde_sube (&res, fcode, arglist, nargs, loc); - break; - - case RS6000_OVLD_VEC_ADDEC: - case RS6000_OVLD_VEC_SUBEC: - returned_expr = resolve_vec_addec_subec (&res, fcode, arglist, nargs, - loc); - break; - - case RS6000_OVLD_VEC_SPLATS: - case RS6000_OVLD_VEC_PROMOTE: - returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs); - break; - - case RS6000_OVLD_VEC_EXTRACT: - returned_expr = resolve_vec_extract (&res, arglist, nargs, loc); - break; - - case RS6000_OVLD_VEC_INSERT: - returned_expr = resolve_vec_insert (&res, arglist, nargs, loc); - break; - - case RS6000_OVLD_VEC_STEP: - returned_expr = resolve_vec_step (&res, arglist, nargs); - break; - - default: - ; - } - - if (res == resolved) - return returned_expr; - - /* "Regular" built-in functions and overloaded functions share a namespace - for some arrays, like rs6000_builtin_decls. But rs6000_overload_info - only has information for the overloaded functions, so we need an - adjusted index for that. */ - unsigned int adj_fcode = fcode - RS6000_OVLD_NONE; - - if (res == resolved_bad) - { - const char *name = rs6000_overload_info[adj_fcode].ovld_name; - error ("invalid parameter combination for AltiVec intrinsic %qs", name); - return error_mark_node; - } - /* Gather the arguments and their types into arrays for easier handling. */ tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); tree types[MAX_OVLD_ARGS]; tree args[MAX_OVLD_ARGS]; unsigned int n; + vec *arglist = static_cast *> (passed_arglist); + unsigned int nargs = vec_safe_length (arglist); + for (n = 0; !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs; fnargs = TREE_CHAIN (fnargs), n++) @@ -1915,10 +1796,79 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, } /* If the number of arguments did not match the prototype, return NULL - and the generic code will issue the appropriate error message. */ - if (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs) + and the generic code will issue the appropriate error message. Skip + this test for functions where we don't fully describe all the possible + overload signatures in rs6000-overload.def (because they aren't relevant + to the expansion here). If we don't, we get confusing error messages. */ + if (fcode != RS6000_OVLD_VEC_PROMOTE + && fcode != RS6000_OVLD_VEC_SPLATS + && fcode != RS6000_OVLD_VEC_EXTRACT + && fcode != RS6000_OVLD_VEC_INSERT + && fcode != RS6000_OVLD_VEC_STEP + && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs)) return NULL; + /* Some overloads require special handling. */ + tree returned_expr = NULL; + resolution res = unresolved; + + switch (fcode) + { + case RS6000_OVLD_VEC_MUL: + returned_expr = resolve_vec_mul (&res, args, types, loc); + break; + + case RS6000_OVLD_VEC_CMPNE: + returned_expr = resolve_vec_cmpne (&res, args, types, loc); + break; + + case RS6000_OVLD_VEC_ADDE: + case RS6000_OVLD_VEC_SUBE: + returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc); + break; + + case RS6000_OVLD_VEC_ADDEC: + case RS6000_OVLD_VEC_SUBEC: + returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc); + break; + + case RS6000_OVLD_VEC_SPLATS: + case RS6000_OVLD_VEC_PROMOTE: + returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs); + break; + + case RS6000_OVLD_VEC_EXTRACT: + returned_expr = resolve_vec_extract (&res, arglist, nargs, loc); + break; + + case RS6000_OVLD_VEC_INSERT: + returned_expr = resolve_vec_insert (&res, arglist, nargs, loc); + break; + + case RS6000_OVLD_VEC_STEP: + returned_expr = resolve_vec_step (&res, arglist, nargs); + break; + + default: + ; + } + + if (res == resolved) + return returned_expr; + + /* "Regular" built-in functions and overloaded functions share a namespace + for some arrays, like rs6000_builtin_decls. But rs6000_overload_info + only has information for the overloaded functions, so we need an + adjusted index for that. */ + unsigned int adj_fcode = fcode - RS6000_OVLD_NONE; + + if (res == resolved_bad) + { + const char *name = rs6000_overload_info[adj_fcode].ovld_name; + error ("invalid parameter combination for AltiVec intrinsic %qs", name); + return error_mark_node; + } + bool unsupported_builtin = false; rs6000_gen_builtins instance_code; bool supported = false;