https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123555
--- Comment #4 from David Faust <dfaust at gcc dot gnu.org> ---
So the problem here is the verifier is unnecessarily strict regarding %r1, the
context pointer, in subprograms.
The offending code construct is the poor innocent (if !ctx) return 0; in:
__attribute__((noinline))
int prog0(struct xdp_md *ctx) {
volatile int ret = 31;
if (!ctx)
return 0;
return ret;
}
We generate:
0000000000000000 <prog0>:
0: 62 0a fc ff 1f 00 00 00 stw [%r10-4],31
8: 15 01 02 00 00 00 00 00 jeq %r1,0,2
10: 81 a0 fc ff 00 00 00 00 ldxsw %r0,[%r10-4]
18: 95 00 00 00 00 00 00 00 exit
20: bf 10 00 00 00 00 00 00 mov %r0,%r1
28: 95 00 00 00 00 00 00 00 exit
But the verifier only knows %r1 as the context pointer, which is not the same
as a scalar value, even if it is guaranteed to be 0 at that point in the
program (doubly obvious during the branch-taken analysis)
Validating prog0() func#1...
3: R1=ctx() R10=fp0
3: (62) *(u32 *)(r10 -4) = 31 ; R10=fp0 fp-8=mmmm????
4: (15) if r1 == 0x0 goto pc+2 7: R1=ctx() R10=fp0 fp-8=mmmm????
7: (bf) r0 = r1 ; R0=ctx() R1=ctx()
8: (95) exit
At subprogram exit the register R0 is not a scalar value (ctx)