[cfe-users] eBPF: Odd optimization results with clang-5.0

Alexei Starovoitov via cfe-users cfe-users at lists.llvm.org
Fri Jan 5 12:05:18 PST 2018


On Fri, Jan 5, 2018 at 7:01 AM, Charlemagne Lasse
<charlemagnelasse at gmail.com> wrote:
> Hi,
>
> just tested the clang eBPF backend. Very cool thing :)
>
> But I've noticed that the codegen creates really odd things which I
> cannot explain from my understanding of the ISA.  My test is attached
> and was compiled via:
>
> clang -O2 -target bpf -x c -c ebpf_opimizer_problems.o -o
> ebpf_opimizer_problems.o
> llvm-objdump -S ebpf_opimizer_problems.o
>
> First thing is the odd way how 8 bit loads to an uint8_t are handled
> (see bug1_sec):
>
>       0:       bf 16 00 00 00 00 00 00         r6 = r1
>       1:       30 00 00 00 00 00 00 00         r0 = *(u8 *)skb[0]
>       2:       57 00 00 00 ff ff 00 00         r0 &= 65535
>       3:       95 00 00 00 00 00 00 00         exit
>
> I have no idea why the second instruction (line "2:") would be
> required when there was just a load of 8 bit to the 64 bit register.
> This isn't generated when it is stored in an uint32_t or uint64_t
> variable (but also when storing it in an uint16_t). This can be seen
> in ok1_sec, ok1_too_a_sec and ok1_too_b_sec.
>
> The other problem is the chaining of tests which results in an extra
> store for the temporary output register (r7, see bug2_sec):
>
>       0:       bf 16 00 00 00 00 00 00         r6 = r1
>       1:       b7 07 00 00 00 00 00 00         r7 = 0
>       2:       30 00 00 00 00 00 00 00         r0 = *(u8 *)skb[0]
>       3:       55 00 04 00 01 00 00 00         if r0 != 1 goto 4
>       4:       30 00 00 00 01 00 00 00         r0 = *(u8 *)skb[1]
>       5:       b7 07 00 00 15 00 00 00         r7 = 21
>       6:       15 00 01 00 01 00 00 00         if r0 == 1 goto 1
>       7:       b7 07 00 00 00 00 00 00         r7 = 0
>
> LBB4_3:
>       8:       bf 70 00 00 00 00 00 00         r0 = r7
>       9:       95 00 00 00 00 00 00 00         exit
>
> For unknown reasons, the line "6:" was changed from an JNE to an JEQ.
> This makes it necessary to introduce link "5:" and line "7:". It would
> have been better (in my eyes) to use keep it an JNE, move line "5:"
> after the comparison and drop line "7:". This would look like this
> (removed the bytecode to make it easier for me):
>
>       0:       r6 = r1
>       1:       r7 = 0
>       2:       r0 = *(u8 *)skb[0]
>       3:       if r0 != 1 goto 3
>       4:       r0 = *(u8 *)skb[1]
>       5:       if r0 != 1 goto 1
>       6:       r7 = 21
> LBB4_3:
>       7:       r0 = r7
>       8:       exit
>
> Or a different version (not so easily readable because it is
> asymmetric) would have been:
>
>        0:       bf 16 00 00 00 00 00 00         r6 = r1
>       1:       30 00 00 00 00 00 00 00         r0 = *(u8 *)skb[0]
>       2:       55 00 03 00 01 00 00 00         if r0 != 1 goto 3
>       3:       b7 07 00 00 15 00 00 00         r7 = 21
>       4:       30 00 00 00 01 00 00 00         r0 = *(u8 *)skb[1]
>       5:       15 00 01 00 01 00 00 00         if r0 == 1 goto 1
>
> LBB4_2:
>       6:       b7 07 00 00 00 00 00 00         r7 = 0
>
> LBB4_3:
>       7:       bf 70 00 00 00 00 00 00         r0 = r7
>       8:       95 00 00 00 00 00 00 00         exit
>
>
> The used version (Debian buster amd64) is:
>
> clang version 5.0.1-2 (tags/RELEASE_501/final)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
> InstalledDir: /usr/bin

thank you for reporting these issues.
It does look odd. Not sure whether it's related to any recent changes.
Needs more investigation.



More information about the cfe-users mailing list