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)

Reply via email to