diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 00476f9b4c34fc7d18ece7b5948feeb12cb55164..65be0ac43e2e92750f87bfea045d491736cfa2d9 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -1668,18 +1668,19 @@ resolve_vec_step (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs) /* Look for a matching instance in a chain of instances. INSTANCE points to the chain of instances; INSTANCE_CODE is the code identifying the specific built-in being searched for; FCODE is the overloaded function code; TYPES - contains an array of two types that must match the types of the instance's - parameters; and ARGS contains an array of two arguments to be passed to - the instance. If found, resolve the built-in and return it, unless the - built-in is not supported in context. In that case, set - UNSUPPORTED_BUILTIN to true. If we don't match, return error_mark_node - and leave UNSUPPORTED_BUILTIN alone. */ + contains an array of NARGS types that must match the types of the + instance's parameters; ARGS contains an array of NARGS arguments to be + passed to the instance; and NARGS is the number of built-in arguments to + check. If found, resolve the built-in and return it, unless the built-in + is not supported in context. In that case, set UNSUPPORTED_BUILTIN to + true. If we don't match, return error_mark_node and leave + UNSUPPORTED_BUILTIN alone. */ tree find_instance (bool *unsupported_builtin, ovlddata **instance, rs6000_gen_builtins instance_code, rs6000_gen_builtins fcode, - tree *types, tree *args) + tree *types, tree *args, int nargs) { while (*instance && (*instance)->bifid != instance_code) *instance = (*instance)->next; @@ -1691,17 +1692,27 @@ find_instance (bool *unsupported_builtin, ovlddata **instance, if (!inst->fntype) return error_mark_node; tree fntype = rs6000_builtin_info[inst->bifid].fntype; - tree parmtype0 = TREE_VALUE (TYPE_ARG_TYPES (fntype)); - tree parmtype1 = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (fntype))); + tree argtype = TYPE_ARG_TYPES (fntype); + bool args_compatible = true; - if (rs6000_builtin_type_compatible (types[0], parmtype0) - && rs6000_builtin_type_compatible (types[1], parmtype1)) + for (int i = 0; i < nargs; i++) + { + tree parmtype = TREE_VALUE (argtype); + if (!rs6000_builtin_type_compatible (types[i], parmtype)) + { + args_compatible = false; + break; + } + argtype = TREE_CHAIN (argtype); + } + + if (args_compatible) { if (rs6000_builtin_decl (inst->bifid, false) != error_mark_node && rs6000_builtin_is_supported (inst->bifid)) { tree ret_type = TREE_TYPE (inst->fntype); - return altivec_build_resolved_builtin (args, 2, fntype, ret_type, + return altivec_build_resolved_builtin (args, nargs, fntype, ret_type, inst->bifid, fcode); } else @@ -1921,7 +1932,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, instance_code = RS6000_BIF_CMPB_32; tree call = find_instance (&unsupported_builtin, &instance, - instance_code, fcode, types, args); + instance_code, fcode, types, args, nargs); if (call != error_mark_node) return call; break; @@ -1981,7 +1992,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, break; tree call = find_instance (&unsupported_builtin, &instance, - instance_code, fcode, types, args); + instance_code, fcode, types, args, nargs); if (call != error_mark_node) return call; break;