<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - BPF target: wrong code generation when clang + llc is used instead of clang only?"
   href="https://llvm.org/bugs/show_bug.cgi?id=26709">26709</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>BPF target: wrong code generation when clang + llc is used instead of clang only?
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>daniel@iogearbox.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>We ran into an issue where clang + llc is used as opposed to clang directly,
the generated code is different and results in verifier rejects from kernel
side when loading a tc classifier.

In the example code, R7 is UNKNOWN_VALUE which is assigned to R4 where IMM
is expected on the function call, instead. For some reason the switch statement
seems misgenerated, and also r7 = 4 is being skipped in the branch condition
that fails.

# llc --version
LLVM (<a href="http://llvm.org/">http://llvm.org/</a>):
  LLVM version 3.8.0svn
  Optimized build.
  Built Jan  9 2016 (02:08:10).
  Default target: x86_64-unknown-linux-gnu
  Host CPU: ivybridge

  Registered Targets:
    bpf    - BPF (host endian)
    bpfeb  - BPF (big endian)
    bpfel  - BPF (little endian)
    x86    - 32-bit X86: Pentium-Pro and above
    x86-64 - 64-bit X86: EM64T and AMD64


Stripped down example code:

#include "../../include/bpf_api.h"

__section_cls_entry
int imain(struct __sk_buff *skb)
{
        char foo[10] = {};
        int sfoo = 4;

        switch (skb->len) {
        case 5:
                sfoo = 1;
                break;
        case 6:
                sfoo = 2;
                break;
        case 7:
                sfoo = 3;
                break;
        }

        printt("foo1: (%d %d %d)\n", 1, 2, sfoo);
        skb_store_bytes(skb, 0, foo, sfoo, 0);

        return BPF_H_DEFAULT;
}

BPF_LICENSE("GPL");


1)

# clang -target bpf -O2 -c bpf_test.c -o bpf_test.o
# tc filter add dev wlp2s0b1 ingress bpf obj examples/bpf/bpf_test.o 


2)

# clang -O2 -emit-llvm -c bpf_test.c -o - | llc -march=bpf -filetype=obj -o
bpf_test.o
# tc filter add dev wlp2s0b1 ingress bpf obj examples/bpf/bpf_test.o 
Prog section 'classifier' rejected: Permission denied (13)!
 - Type:         3
 - Instructions: 38
 - License:      GPL

Verifier analysis:

0: (bf) r6 = r1
1: (b7) r1 = 0
2: (6b) *(u16 *)(r10 -8) = r1
3: (7b) *(u64 *)(r10 -16) = r1
4: (61) r1 = *(u32 *)(r6 +0)
5: (bf) r7 = r1
6: (07) r7 += -4
7: (07) r1 += -5
8: (67) r1 <<= 32
9: (77) r1 >>= 32
10: (b7) r2 = 3
11: (2d) if r2 > r1 goto pc+1
 R1=inv R2=imm3 R6=ctx R7=inv R10=fp
12: (b7) r7 = 4
13: (b7) r1 = 10
14: (6b) *(u16 *)(r10 -32) = r1
15: (18) r1 = 0x64252064
17: (7b) *(u64 *)(r10 -40) = r1
18: (18) r1 = 0x316f6f66
20: (7b) *(u64 *)(r10 -48) = r1
21: (bf) r1 = r10
22: (07) r1 += -48
23: (b7) r2 = 18
24: (b7) r3 = 1
25: (b7) r4 = 2
26: (bf) r5 = r7
27: (85) call 6
28: (bf) r3 = r10
29: (07) r3 += -16
30: (bf) r1 = r6
31: (b7) r2 = 0
32: (bf) r4 = r7
33: (b7) r5 = 0
34: (85) call 9
35: (18) r0 = 0xffffffff
37: (95) exit

from 11 to 13: R1=inv R2=imm3 R6=ctx R7=inv R10=fp
13: (b7) r1 = 10
14: (6b) *(u16 *)(r10 -32) = r1
15: (18) r1 = 0x64252064
17: (7b) *(u64 *)(r10 -40) = r1
18: (18) r1 = 0x316f6f66
20: (7b) *(u64 *)(r10 -48) = r1
21: (bf) r1 = r10
22: (07) r1 += -48
23: (b7) r2 = 18
24: (b7) r3 = 1
25: (b7) r4 = 2
26: (bf) r5 = r7
27: (85) call 6
28: (bf) r3 = r10
29: (07) r3 += -16
30: (bf) r1 = r6
31: (b7) r2 = 0
32: (bf) r4 = r7
33: (b7) r5 = 0
34: (85) call 9
R4 type=inv expected=imm

Error fetching program/map!
Failed to retrieve (e)BPF data!


3)

# clang -target bpf -O2 -c bpf_test.c -o bpf_test_good.o
# clang -O2 -emit-llvm -c bpf_test.c -o - | llc -march=bpf -filetype=obj -o
bpf_test_bad.o
# ls -la bpf_test_*
-rw-r--r--. 1 root root 1016 Feb 23 11:46 bpf_test_bad.o
-rw-r--r--. 1 root root 1080 Feb 23 11:46 bpf_test_good.o</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>