https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124171
Bug ID: 124171
Summary: bpf: procedure calling convention ABI incompatible
with clang (argument/return value promotion)
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: vineetg at gcc dot gnu.org
Reporter: vineetg at gcc dot gnu.org
Target Milestone: ---
Target: bpf
Currently gcc and clang differ in where function arguments promotion
(zero/sign) happens: gcc does this in caller, while clang does this in callee:
cfr [1][2]
1. Arguments: caller and callee
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
This was discussed with bpf community and the conclusion [3] is to change gcc
to follow llvm behavior since it has been out in the wild for much longer and
for typical bpf production deloyments llvm is used for both kernel and bpf.
[1] https://gcc.gnu.org/pipermail/bpf/2026-February/000016.html
[2] https://godbolt.org/z/oerG3eT6f
[3] https://gcc.gnu.org/pipermail/bpf/2026-February/000031.html