blob: a9e4a3b8d39271784dbc923b8888821de6bbd74d [file] [edit]
; RUN: opt -S -mtriple=bpfel -passes=bpf-func-table %s | FileCheck %s
; RUN: llc -mtriple=bpfel -mcpu=v4 -mattr=+func-table %s -o - | FileCheck --check-prefix=ASM %s
;
; The kernel calls what is passed to a helper or to a kfunc as a callback.
; It wants the function and not its index in the table.
declare i32 @bpf_wq_set_callback(ptr, ptr, i32)
define internal i64 @cb(i64 %i, ptr %ctx) {
ret i64 0
}
define internal i64 @cb2(i64 %i, ptr %ctx) {
ret i64 1
}
define internal void @take(ptr %f) noinline {
%r = call i64 %f(i64 0, ptr null)
ret void
}
define i64 @helper(ptr %ctx) {
; CHECK-LABEL: @helper(
; CHECK: call i64 inttoptr (i64 181 to ptr)(i32 10, ptr @cb, ptr %ctx, i64 0)
; ASM-LABEL: helper:
; ASM: r2 = cb ll
; ASM: call 181
%r = call i64 inttoptr (i64 181 to ptr)(i32 10, ptr @cb, ptr %ctx, i64 0)
ret i64 %r
}
define i32 @kfunc(ptr %wq) {
; CHECK-LABEL: @kfunc(
; CHECK: call i32 @bpf_wq_set_callback(ptr %wq, ptr @cb, i32 0)
; ASM-LABEL: kfunc:
; ASM: r2 = cb ll
; ASM: call bpf_wq_set_callback
%r = call i32 @bpf_wq_set_callback(ptr %wq, ptr @cb, i32 0)
ret i32 %r
}
; Passed to a function of the program it is an index.
define void @own() {
; CHECK-LABEL: @own(
; CHECK: call void @take(ptr inttoptr (i64 1 to ptr))
; ASM-LABEL: own:
; ASM: r1 = 1
; ASM: call take
call void @take(ptr @cb)
ret void
}
; One of several callbacks.
define i64 @select(ptr %ctx, i1 %c) {
; CHECK-LABEL: @select(
; CHECK: select i1 %c, ptr @cb, ptr @cb2
; ASM-LABEL: select:
; ASM-DAG: r2 = cb ll
; ASM-DAG: r2 = cb2 ll
; ASM: call 181
%f = select i1 %c, ptr @cb, ptr @cb2
%r = call i64 inttoptr (i64 181 to ptr)(i32 10, ptr %f, ptr %ctx, i64 0)
ret i64 %r
}
define void @phi(ptr %ctx, i1 %c) {
; CHECK-LABEL: @phi(
; CHECK: phi ptr [ @cb, %entry ], [ @cb2, %other ], [ %f, %loop ]
entry:
br i1 %c, label %loop, label %other
other:
br label %loop
loop:
%f = phi ptr [ @cb, %entry ], [ @cb2, %other ], [ %f, %loop ]
%r = call i64 inttoptr (i64 181 to ptr)(i32 10, ptr %f, ptr %ctx, i64 0)
%again = icmp eq i64 %r, 0
br i1 %again, label %loop, label %exit
exit:
ret void
}
; The program calls the result too. That call goes through the table and wants
; an index.
define i64 @both(ptr %ctx, i1 %c) {
; CHECK-LABEL: @both(
; CHECK: select i1 %c, ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr)
%f = select i1 %c, ptr @cb, ptr @cb2
%r = call i64 inttoptr (i64 181 to ptr)(i32 10, ptr %f, ptr %ctx, i64 0)
%s = call i64 %f(i64 0, ptr %ctx)
ret i64 %s
}