* Re: Function Return ABI (was Re: Argument passing and ABI: GCC vs clang)
[not found] ` <b77afbde-b6d6-4728-9090-af31027846b2@linux.dev>
@ 2026-02-20 2:41 ` Alexei Starovoitov
2026-02-20 3:38 ` Vineet Gupta
0 siblings, 1 reply; 2+ messages in thread
From: Alexei Starovoitov @ 2026-02-20 2:41 UTC (permalink / raw)
To: Vineet Gupta, bpf
Cc: Jose E. Marchesi, bpf, Alexei Starovoitov, Yonghong Song,
Andrew Pinski
On Thu, Feb 19, 2026 at 3:11 PM Vineet Gupta <vineet.gupta@linux.dev> wrote:
>
> On 2/8/26 9:11 PM, Vineet Gupta wrote:
> > On 2/6/26 03:20, Jose E. Marchesi wrote:
> >> Hello people!
> >>
> >> Yesterday evening Vineet pointed out in IRC some differences between the
> >> way GCC handles argument passing compared to clang/LLVM.
> > For illustration, here's what a simple test looks like across clang, gcc and x86
> > and aarch64
> > https://godbolt.org/z/oerG3eT6f
> >
> > typedef struct {
> > int a;
> > short b;
> > signed char c;
> > } my_t;
> >
> > void foo(signed char, short, int);
> >
> > char args_setup(my_t *s)
> > {
> > foo(s->c, s->b, s->a);
> > }
> >
> > int args_consume (signed char a, short b, int c)
> > {
> > int x = a;
> > int y = b;
> > int z = c;
> >
> > return x + y + z;
> > }
> >
> > clang: -O2 -mcpu=v4 | gcc: -O2 -mcpu=v4
> > |
> > args_setup: | args_setup:
> > r2 = *(s16 *)(r1 + 4) | r3 = *(u32 *) (r1+0)
> > w3 = *(u32 *)(r1 + 0) | r2 = *(u16 *) (r1+4)
> > r1 = *(s8 *)(r1 + 6) | r1 = *(u8 *) (r1+6)
> > call foo | call foo
> > exit | exit
> > |
> > args_consume: | args_consume:
> > w0 = w2 | r2 = (s16) r2
> > w0 += w1 | r0 = r3
> > w0 += w3 | r1 = (s8) r1
> > exit | w1 += w2
> > | w0 += w1
> > | exit
> >
> >
> > So clang is narrowing the args on caller site while gcc is doing this in caller.
> > This is not consistent and needs to fixed in one of the compilers.
> > Doing this in callee seems like a better/safer approach as doesn't assume caller
> > to always be doing the right thing, specially when mixing bpf user code with
> > kernel etc.
> >
> > BTW where is the w<N> assembler notation and semantics (32-bit, zero extension
> > etc) documented. I don't anything relevant in [1]
> > Presumably it is just a compiler notation so [1] might not be the ideal place.
> >
> > [1] https://docs.kernel.org/bpf/standardization/instruction-set.html
> So the function arguments issue is captured as PR/124171 and I have a
> tentative fix for that, but...
> There's second half of the problem which is promotion of narrow function
> return values.
>
> It seems the existing clang ABI is not symmetrical. The function
> arguments promotion is handled in callee, but function return is handled
> in caller [1] which is a bit atypical IMO and would need to be handled
> in gcc as well.
hmm. I thought we already concluded that for clang-x86 and clang-bpf
argument extension is handled in *caller*.
The same thing for returns. It's a caller responsibility.
gcc-bpf doing args in the callee only is broken and has to be fixed.
> Since we are on the topic of ABI change, I wanted to surface that as
> well before we go off and tackle that.
>
> Simple example
>
> _Bool bar_bool(void);
>
> int ret_caller(void) {
> if (bar_bool() != 1) return 0; else return 1;
> }
>
> char ret_callee(my_t *s)
> {
> return s->c; // c is a char in a struct
> }
>
> ret_caller:
> call bar_bool
> r0 &= 0xff <-- ret promotion in caller
> exit
>
> ret_callee:
> r0 = *(u8 *) (r1+6) <-- no ret promotion in callee
> exit
Exactly as it should be because x86 will populate 8-bit sub
registers in the callee and bpf side has to do r0 &= 0xff
in the caller.
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Function Return ABI (was Re: Argument passing and ABI: GCC vs clang)
2026-02-20 2:41 ` Function Return ABI (was Re: Argument passing and ABI: GCC vs clang) Alexei Starovoitov
@ 2026-02-20 3:38 ` Vineet Gupta
0 siblings, 0 replies; 2+ messages in thread
From: Vineet Gupta @ 2026-02-20 3:38 UTC (permalink / raw)
To: Alexei Starovoitov, bpf
Cc: Jose E. Marchesi, bpf, Alexei Starovoitov, Yonghong Song,
Andrew Pinski
On 2/19/26 6:41 PM, Alexei Starovoitov wrote:
>> It seems the existing clang ABI is not symmetrical. The function
>> arguments promotion is handled in callee, but function return is handled
>> in caller [1] which is a bit atypical IMO and would need to be handled
>> in gcc as well.
Ignore this as it is clearly wrong (my jetlag and waking up at 3 am is
to blame :-)
With PR/124171 gcc-bpf will promote args in caller same as llvm (not
callee)
> hmm. I thought we already concluded that for clang-x86 and clang-bpf
> argument extension is handled in*caller*.
> The same thing for returns. It's a caller responsibility.
> gcc-bpf doing args in the callee only is broken and has to be fixed.
Correct, agreed.
>> Since we are on the topic of ABI change, I wanted to surface that as
>> well before we go off and tackle that.
>>
>> Simple example
>>
>> _Bool bar_bool(void);
>>
>> int ret_caller(void) {
>> if (bar_bool() != 1) return 0; else return 1;
>> }
>>
>> char ret_callee(my_t *s)
>> {
>> return s->c; // c is a char in a struct
>> }
>>
>> ret_caller:
>> call bar_bool
>> r0 &= 0xff <-- ret promotion in caller
>> exit
>>
>> ret_callee:
>> r0 = *(u8 *) (r1+6) <-- no ret promotion in callee
>> exit
> Exactly as it should be because x86 will populate 8-bit sub
> registers in the callee and bpf side has to do r0 &= 0xff
> in the caller.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-02-20 3:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <87fr7e15l0.fsf@gnu.org>
[not found] ` <6ac7e425-cf75-4706-9906-4c23eb4f0f41@linux.dev>
[not found] ` <b77afbde-b6d6-4728-9090-af31027846b2@linux.dev>
2026-02-20 2:41 ` Function Return ABI (was Re: Argument passing and ABI: GCC vs clang) Alexei Starovoitov
2026-02-20 3:38 ` Vineet Gupta
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.