OSDN Git Service

bpf: generate better lowering code for certain select/setcc instructions
authorYonghong Song <yhs@fb.com>
Sat, 15 Jul 2017 05:41:42 +0000 (05:41 +0000)
committerYonghong Song <yhs@fb.com>
Sat, 15 Jul 2017 05:41:42 +0000 (05:41 +0000)
commit7c423e0690abde4d4bab959ed32bc6b27cc989b1
treed79341bcc05e2f6897748c1e3c61299336f06a21
parentcf17bf01efdbd773109a7d0ae7108b7f40b0033a
bpf: generate better lowering code for certain select/setcc instructions

Currently, for code like below,
===
  inner_map = bpf_map_lookup_elem(outer_map, &port_key);
  if (!inner_map) {
    inner_map = &fallback_map;
  }
===
the compiler generates (pseudo) code like the below:
===
  I1: r1 = bpf_map_lookup_elem(outer_map, &port_key);
  I2: r2 = 0
  I3: if (r1 == r2)
  I4:   r6 = &fallback_map
  I5: ...
===

During kernel verification process, After I1, r1 holds a state
map_ptr_or_null. If I3 condition is not taken
(path [I1, I2, I3, I5]), supposedly r1 should become map_ptr.
Unfortunately, kernel does not recognize this pattern
and r1 remains map_ptr_or_null at insn I5. This will cause
verificaiton failure later on.

Kernel, however, is able to recognize pattern "if (r1 == 0)"
properly and give a map_ptr state to r1 in the above case.

LLVM here generates suboptimal code which causes kernel verification
failure. This patch fixes the issue by changing BPF insn pattern
matching and lowering to generate proper codes if the righthand
parameter of the above condition is a constant. A test case
is also added.

Signed-off-by: Yonghong Song <yhs@fb.com>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308080 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/BPF/BPFISelLowering.cpp
lib/Target/BPF/BPFInstrInfo.td
test/CodeGen/BPF/select_ri.ll [new file with mode: 0644]
test/CodeGen/BPF/setcc.ll