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 >
