On Tue, Dec 2, 2025 at 12:45 PM Georg-Johann Lay via Gcc
<[email protected]> wrote:
>
> Playing with a new avr function attribute, I stumbled upon this problem:
>
> On avr, all varargs arguments are passed on the stack, even the named
> ones. So I added a "rargs" function attribute that passes named args in
> registers if possible.  One test case looks like this:
>
> #define RA __attribute__((rargs))
>
> void call_rafun_cast1 (void (*f)(char, ...))
> {
>      ((RA void(*)(char,...)) f) (10);
> }
>
> void call_rafun_cast0 (RA void (*f)(char, ...))
> {
>      ((void(*)(char,...)) f) (20);
> }
>
> The code compiles as expected:
>
> // rargs: no push/pop
> call_rafun_cast1:
>         movw r30,r24     ;  20  [c=4 l=1]  *movhi/0
>         ldi r24,lo8(10)  ;  14  [c=4 l=1]  movqi_insn/1
>         ijmp             ;  7   [c=0 l=1]  call_insn/2
>
> // default: push/pop.
> call_rafun_cast0:
>         ldi r18,lo8(20)  ;  15  [c=4 l=1]  movqi_insn/1
>         push r18                 ;  7   [c=4 l=1]  pushqi1/0
>         movw r30,r24     ;  23  [c=4 l=1]  *movhi/0
>         icall            ;  8   [c=0 l=1]  call_insn/0
>          ; SP += 1       ;  9   [c=8 l=1]  *addhi3_sp
>         pop __tmp_reg__
>         ret              ;  19  [c=0 l=1]  return
>
> Notice that cast0 has a push / pop of the argument as expected, while
> cast1 hasn't, also as expected. This is all fine.  Now change the code
> slightly so that the function bodies become the same (pass 10 instead of
> 20):
>
> void call_rafun_cast0 (RA void (*f)(char, ...))
> {
>      ((void(*)(char,...)) f) (10);
> }
>
> The code compiles to:
>
> call_rafun_cast0:
>         rjmp call_rafun_cast1    ;  7   [c=0 l=1]  call_insn/3
>
> which is wrong IMO.  The bodies of the functions are the same, but the
> prototypes are not, so performing ICF is wrong.
>
> I am not completely sure about a function pointer cast adding / removing
> a function attribute.  Though GCC seems to compile it as expected
> without ICF.
>
> So is this an ICF bug or am I missing some target hook?

Looking into the code, and looking into how fastcall works for i686
(since replacing rargs with fastcall works there), the target hook
comp_type_attributes is needed to make sure to return false for the
attribute mismatch on the types with/without the attribute.

Thanks,
Andrew Pinski

> For now I only changed the cumulative args hooks, but there are some
> VA_LIST and VA_ARG hooks in
> https://gcc.gnu.org/onlinedocs/gccint/Register-Arguments.html where I
> don't know what to do with them.
>
> All unnamed args are passed the same way in either case; the attribute
> only affects passing of named args.
>
> GCC is current trunk.
>
> Johann
>

Reply via email to