On Wed, Dec 3, 2025 at 10:32 AM Georg-Johann Lay via Gcc
<[email protected]> wrote:
>
> Am 02.12.25 um 23:40 schrieb Andrew Pinski:
> > 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
>
> Hi Andrew,
>
> thank you for the pointer.  Though it doesn't help.  For the test
> program, the TARGET_COMP_TYPE_ATTRIBUTES hook isn't even called.

You likely made it a decl attribute then?  I suggest to only allow the attribute
on function types.

Richard.

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