Bug in identical code folding?
Georg-Johann Lay
avr@gjlay.de
Wed Dec 3 16:52:27 GMT 2025
Am 03.12.25 um 13:21 schrieb Richard Biener:
> On Wed, Dec 3, 2025 at 10:32 AM Georg-Johann Lay via Gcc
> <gcc@gcc.gnu.org> 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
>>> <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.
>
> You likely made it a decl attribute then? I suggest to only allow the attribute
> on function types.
>
> Richard.
Ah, now I found it. The TARGET_GNU_ATTRIBUTES has an
affects_type_identity, which was false. When setting that to true,
then TARGET_COMP_TYPE_ATTRIBUTES is called as expected. Now it works.
Many thanks,
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