https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122762

--- Comment #24 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #21)
> (In reply to Richard Sandiford from comment #17)
> > (In reply to Richard Biener from comment #11)
> > > (In reply to Richard Sandiford from comment #10)
> [...]
> > > > As for why it does that, see the commit message for
> > > > g:482b2b43e5101921ad94e51e052a18b353f8a3f5, which introduced the check.
> > >
> > > Hm, but that talks about argument passing / return ABIs?
> > > useless_type_conversion_p applies to value types, at most its check
> > > for FUNCTION_TYPE compatibility would need to use this check?
> > 
> > Wouldn't that be bad for composability though?  It would seem odd for "T1
> > f()" vs "T2 g()" to impose stricter rules than T1 vs T2.
> 
> Sure, but useless_type_conversion_p is generally the wrong place to address
> ABI compatibility issues.  What breaks when not having this check in
> useless_type_conversion_p?  The testcases added, if they break, would
> point to places where we use this function wrongly.  It's by far
> "complete" to check whether two FUNCTION_TYPE have the same ABI.

I think the FUNCTION_TYPE thing is a bit of a red herring.  The main reason for
the check is to preserve the types of vector values.  That's because
code-generation of calls depends on the gimple type of the value being passed,
rather than the argument type recorded in the FUNCTION_TYPE.  For example, see
calls.cc:

    FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
      {
        tree argtype = TREE_TYPE (arg);

        if (targetm.calls.split_complex_arg…)
          …
        else
          args[j].tree_value = arg;

as used in:

  for (argpos = 0; argpos < num_actuals; i--, argpos++)
    {
      tree type = TREE_TYPE (args[i].tree_value);
      …
      function_arg_info arg (type, argpos < n_named_args);
      if (pass_by_reference (args_so_far_pnt, arg))
        …
    }

where the way that something is passed is keyed off the type of the gimple
value.  The FUNCTION_TYPE's TYPE_ARG_TYPES is only used to distinguish
prototyped from unprototyped functions and to determine which arguments are
named and which are varargs.

And I think it has to be that way.  The different passing of SVE vs. non-SVE
types extends to varargs.  If gimple didn't preserve the difference, then we
wouldn't know which convention to use.

Reply via email to