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 (&copy->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 = &copy->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))

Reply via email to