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

--- Comment #25 from rguenther at suse dot de <rguenther at suse dot de> ---
On Thu, 20 Nov 2025, rsandifo at gcc dot gnu.org wrote:

> 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.

Hmm, IMO that's broken by design.

> 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.

OK, for varargs I'd agree, but then this should ideally be nailed down
before or at gimplification, after that the actual value type shouldn't
come into play.

That this all makes two identical value types incompatible on GIMPLE
for SVE is quite unfortunate.

Reply via email to