Ping! please review.
Thanks & Regards Kishan On 05/06/25 12:36 pm, Kishan Parmar wrote: > Hi All, > > The following patch has been bootstrapped and regtested on powerpc64le-linux. > > After r12-5752-gd08236359eb229, a new bif infrastructure was introduced > which stopped using opaque vector types (e.g. opaque_V4SI_type_node) > for overloaded built-in functions, which led to incorrect and > misleading diagnostics when argument types didn’t exactly match. > > This patch reinstates the opaque overload variant for entries with > multiple arguments where at least one is a vector, inserting it > at the beginning of each stanza. This helps recover the intended > fallback behavior and ensures clearer, type-generic error reporting. > > 2025-05-23 Kishan Parmar <kis...@linux.ibm.com> > > gcc: > PR target/104930 > * config/rs6000/rs6000-c.cc (altivec_resolve_overloaded_builtin): > Skip the first overload entry during iteration if it uses opaque type > parameters. > * config/rs6000/rs6000-gen-builtins.cc > (maybe_generate_opaque_variant): New function. > (parse_first_ovld_entry): New function. > (parse_ovld_stanza): call parse_first_ovld_entry. > --- > gcc/config/rs6000/rs6000-c.cc | 9 +- > gcc/config/rs6000/rs6000-gen-builtins.cc | 180 ++++++++++++++++++++++- > 2 files changed, 187 insertions(+), 2 deletions(-) > > diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc > index d3b0a566821..6217d585b40 100644 > --- a/gcc/config/rs6000/rs6000-c.cc > +++ b/gcc/config/rs6000/rs6000-c.cc > @@ -1972,7 +1972,14 @@ altivec_resolve_overloaded_builtin (location_t loc, > tree fndecl, > arg_i++) > { > tree parmtype = TREE_VALUE (nextparm); > - if (!rs6000_builtin_type_compatible (types[arg_i], parmtype)) > + /* Since we only need opaque vector type for the default > + prototype which is the same as the first instance, we > + only expect to see it in the first instance. */ > + gcc_assert (instance == > rs6000_overload_info[adj_fcode].first_instance > + || parmtype != opaque_V4SI_type_node); > + if ((instance == rs6000_overload_info[adj_fcode].first_instance > + && parmtype == opaque_V4SI_type_node) > + || !rs6000_builtin_type_compatible (types[arg_i], parmtype)) > { > mismatch = true; > break; > diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc > b/gcc/config/rs6000/rs6000-gen-builtins.cc > index f77087e0452..d442b93138e 100644 > --- a/gcc/config/rs6000/rs6000-gen-builtins.cc > +++ b/gcc/config/rs6000/rs6000-gen-builtins.cc > @@ -353,6 +353,7 @@ struct typeinfo > char isunsigned; > char isbool; > char ispixel; > + char isopaque; > char ispointer; > basetype base; > restriction restr; > @@ -579,6 +580,7 @@ static typemap type_map[] = > { "v4sf", "V4SF" }, > { "v4si", "V4SI" }, > { "v8hi", "V8HI" }, > + { "vop4si", "opaque_V4SI" }, > { "vp8hi", "pixel_V8HI" }, > }; > > @@ -1058,6 +1060,7 @@ match_type (typeinfo *typedata, int voidok) > vd vector double > v256 __vector_pair > v512 __vector_quad > + vop vector opaque > > For simplicity, We don't support "short int" and "long long int". > We don't currently support a <basetype> of "_Float16". "signed" > @@ -1496,6 +1499,12 @@ complete_vector_type (typeinfo *typeptr, char *buf, > int *bufi) > *bufi += 4; > return; > } > + else if (typeptr->isopaque) > + { > + memcpy (&buf[*bufi], "op4si", 5); > + *bufi += 5; > + return; > + } > switch (typeptr->base) > { > case BT_CHAR: > @@ -1661,7 +1670,8 @@ construct_fntype_id (prototype *protoptr) > buf[bufi++] = '_'; > if (argptr->info.isconst > && argptr->info.base == BT_INT > - && !argptr->info.ispointer) > + && !argptr->info.ispointer > + && !argptr->info.isopaque) > { > buf[bufi++] = 'c'; > buf[bufi++] = 'i'; > @@ -1969,6 +1979,168 @@ create_bif_order (void) > rbt_inorder_callback (&bifo_rbt, bifo_rbt.rbt_root, set_bif_order); > } > > +/* Attempt to generate an opaque variant if needed and valid. */ > +static void > +maybe_generate_opaque_variant (ovlddata* entry) > +{ > + /* If no vector arg, no need to create opaque variant. */ > + bool has_vector_arg = false; > + for (typelist* arg = entry->proto.args; arg; arg = arg->next) > + { > + if (arg->info.isvector) > + { > + has_vector_arg = true; > + break; > + } > + } > + > + if (!has_vector_arg || entry->proto.nargs <= 1) > + return; > + > + /* Construct the opaque variant. */ > + ovlddata* opaque_entry = &ovlds[curr_ovld]; > + memcpy (opaque_entry, entry, sizeof (*entry)); > + > + /* Deep-copy and override vector args. */ > + typelist** dst = &opaque_entry->proto.args; > + for (typelist* src = entry->proto.args; src; src = src->next) > + { > + typelist* copy = (typelist*) malloc (sizeof (typelist)); > + > + if (src->info.isvector) > + { > + memset (©->info, 0, sizeof (typeinfo)); > + copy->info.isconst = src->info.isconst; > + copy->info.isvector = 1; > + copy->info.issigned = 1; > + copy->info.isopaque = 1; > + copy->info.base = BT_INT; > + } > + else > + { > + memcpy (copy, src, sizeof (typelist)); > + } > + > + *dst = copy; > + dst = ©->next; > + } > + *dst = NULL; > + > + /* Rewrite return type if vector. */ > + if (entry->proto.rettype.isvector) > + { > + memset (&opaque_entry->proto.rettype, 0, sizeof (typeinfo)); > + opaque_entry->proto.rettype.isvector = 1; > + opaque_entry->proto.rettype.issigned = 1; > + opaque_entry->proto.rettype.isopaque = 1; > + opaque_entry->proto.rettype.base = BT_INT; > + } > + > + /* Generate unique overload ID. */ > + const char* base_id = entry->ovld_id_name; > + size_t id_len = strlen (base_id); > + const char* suffix = strchr (base_id, '_') ? "_VOP" : "__VOP"; > + char* new_id = (char*) malloc (id_len + strlen (suffix) + 1); > + memset (new_id, 0, id_len + strlen (suffix) + 1); > + > + strcpy (new_id, base_id); > + strcat (new_id, suffix); > + > + opaque_entry->ovld_id_name = new_id; > + opaque_entry->fndecl = construct_fntype_id (&opaque_entry->proto); > + > + curr_ovld = num_ovlds++; > +} > + > +/* Parse the first entry in the stanza. */ > +static parse_codes > +parse_first_ovld_entry (void) > +{ > + pos = 0; > + consume_whitespace (); > + > + if (linebuf[pos] == '[') > + return PC_EOSTANZA; > + > + if (num_ovlds >= MAXOVLDS - 1) > + { > + diag (pos, "too many overloads.\n"); > + return PC_PARSEFAIL; > + } > + > + ovlddata ovld_entry; > + memset (&ovld_entry, 0, sizeof (ovlddata)); > + curr_ovld = num_ovlds++; > + ovld_entry.stanza = curr_ovld_stanza; > + > + if (parse_prototype (&ovld_entry.proto) == PC_PARSEFAIL) > + return PC_PARSEFAIL; > + > + if (ovld_entry.proto.nargs > max_ovld_args) > + max_ovld_args = ovld_entry.proto.nargs; > + > + if (!advance_line (ovld_file)) > + { > + diag (0, "unexpected EOF.\n"); > + return PC_EOFILE; > + } > + > + pos = 0; > + consume_whitespace (); > + int oldpos = pos; > + > + char* id = match_identifier (); > + if (!id) > + { > + diag (pos, "missing overload id.\n"); > + return PC_PARSEFAIL; > + } > + > + ovld_entry.bif_id_name = id; > + ovld_entry.ovld_id_name = id; > + > +#ifdef DEBUG > + diag (pos, "ID name is '%s'.\n", id); > +#endif > + > + if (!rbt_find (&bif_rbt, id)) > + { > + diag (pos, "builtin ID '%s' not found in bif file.\n", id); > + return PC_PARSEFAIL; > + } > + > + consume_whitespace (); > + if (linebuf[pos] != '\n') > + { > + char* alt_id = match_identifier (); > + if (alt_id) > + ovld_entry.ovld_id_name = alt_id; > + consume_whitespace (); > + } > + > + /* Attempt to generate opaque variant, if eligible. */ > + maybe_generate_opaque_variant (&ovld_entry); > + > + /* Build a function type descriptor identifier from the return type > + and argument types, and store it if it does not already exist. */ > + ovld_entry.fndecl = construct_fntype_id (&ovld_entry.proto); > + > + if (!rbt_insert (&ovld_rbt, ovld_entry.ovld_id_name)) > + { > + diag (oldpos, "duplicate overload ID '%s'.\n", > ovld_entry.ovld_id_name); > + return PC_PARSEFAIL; > + } > + > + if (linebuf[pos] != '\n') > + { > + diag (pos, "garbage at end of line.\n"); > + return PC_PARSEFAIL; > + } > + > + memcpy (&ovlds[curr_ovld], &ovld_entry, sizeof ovld_entry); > + return PC_OK; > +} > + > /* Parse one two-line entry in the overload file. */ > static parse_codes > parse_ovld_entry (void) > @@ -2155,6 +2327,12 @@ parse_ovld_stanza (void) > > parse_codes result = PC_OK; > > + if (!advance_line(ovld_file)) > + return PC_EOFILE; > + result = parse_first_ovld_entry(); > + if (result == PC_EOFILE || result == PC_PARSEFAIL) > + return result; > + > while (result != PC_EOSTANZA) > { > if (!advance_line (ovld_file))