<div><div dir="auto">I think your clang command line should have “-target bpf”. It needs to know you’re targeting bpf instructions not ARM instructions.</div><br><div class="gmail_quote"><div>On Thu, Oct 12, 2017 at 12:35 AM Adrian Szyndela via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
We're trying to use BPF on a 32-bit ARM. However, we have issues with<br>
llvm.bpf.pseudo.<br>
<br>
Let's consider a simple program (t.c):<br>
<br>
#include <uapi/linux/bpf.h><br>
<br>
typedef unsigned long long u64;<br>
<br>
u64 bpf_pseudo_fd(u64, u64) asm("llvm.bpf.pseudo");<br>
<br>
static void *(*bpf_map_lookup_elem)(void *map, void *key) =<br>
(void *) BPF_FUNC_map_lookup_elem;<br>
<br>
int test_ok(void *ctx) {<br>
// 0s below are for example<br>
void *v = bpf_map_lookup_elem(bpf_pseudo_fd(0,0), 0);<br>
return 0;<br>
}<br>
<br>
We put it into<br>
clang -O2 -target armv7l-unknown-linux-gnueabi -emit-llvm -S t.c<br>
<br>
to get<br>
<br>
define i32 @test_ok(i8* nocapture readnone) local_unnamed_addr #0 {<br>
%2 = tail call i64 @llvm.bpf.pseudo(i64 0, i64 0)<br>
%3 = trunc i64 %2 to i32<br>
%4 = inttoptr i32 %3 to i8*<br>
%5 = tail call i8* inttoptr (i32 1 to i8* (i8*, i8*)*)(i8* %4, i8*<br>
null) #1<br>
ret i32 0<br>
}<br>
<br>
Note the 'trunc' instruction, which is there, because return type of<br>
llvm.bpf.pseudo is i64, and it is converted to 32-bit pointer.<br>
<br>
Now, after<br>
llc -march=bpf t.ll<br>
<br>
we get<br>
test_ok: # @test_ok<br>
ld_pseudo r1, 0, 0<br>
r1 <<= 32<br>
r1 >>= 32<br>
r2 = 0<br>
call 1<br>
r0 = 0<br>
exit<br>
<br>
The return value of llvm.bpf.pseudo (u64) is truncated by shift-left +<br>
shift-right. After the operation BPF verifier does not consider the<br>
value in r1 as pointer anymore, and complains when it is passed as a<br>
pointer to bpf_map_lookup_elem (call 1).<br>
<br>
We have changed the return type of llvm.bpf.pseudo to pointer for our<br>
purposes (see below), but what is the "correct" way of handling it?<br>
<br>
include/llvm/IR/IntrinsicsBPF.td:<br>
def int_bpf_pseudo : GCCBuiltin<"__builtin_bpf_pseudo">,<br>
- Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty]>;<br>
+ Intrinsic<[llvm_ptr_ty], [llvm_i64_ty, llvm_i64_ty]>;<br>
<br>
Thanks,<br>
Adrian<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div><div dir="ltr">-- <br></div><div class="gmail_signature" data-smartmail="gmail_signature">~Craig</div>