Bug in identical code folding?
Georg-Johann Lay
avr@gjlay.de
Wed Dec 3 09:31:13 GMT 2025
Am 02.12.25 um 23:40 schrieb Andrew Pinski:
> On Tue, Dec 2, 2025 at 12:45 PM Georg-Johann Lay via Gcc
> <gcc@gcc.gnu.org> 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.
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
>>
More information about the Gcc
mailing list