| ; RUN: llc -march=bpf -mcpu=v4 < %s | FileCheck %s |
| |
| ; The real jump table (@__const.foo.jt, all BlockAddress) is converted into a |
| ; .jumptables entry and its global is removed. |
| ; CHECK-LABEL: foo: |
| ; CHECK: r2 = BPF.JT.0.0 ll |
| ; CHECK: gotox r1 |
| ; CHECK: .section .jumptables |
| ; CHECK: BPF.JT.0.0: |
| |
| ; The function-pointer array is preserved and still emitted. |
| ; CHECK-LABEL: get: |
| ; CHECK: r2 = .Lkfuncs ll |
| ; CHECK: .Lkfuncs: |
| ; CHECK: .size .Lkfuncs, 16 |
| |
| @__const.foo.jt = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@foo, %l1), ptr blockaddress(@foo, %l2)], align 8 |
| @kfuncs = private unnamed_addr constant [2 x ptr] [ptr @ext1, ptr @ext2], align 8 |
| |
| declare void @ext1() |
| declare void @ext2() |
| |
| define i32 @foo(i32 %a) { |
| entry: |
| %rem = and i32 %a, 1 |
| %idx = zext nneg i32 %rem to i64 |
| %g = getelementptr inbounds nuw [2 x ptr], ptr @__const.foo.jt, i64 0, i64 %idx |
| %t = load ptr, ptr %g, align 8 |
| indirectbr ptr %t, [label %l1, label %l2] |
| l1: |
| br label %l2 |
| l2: |
| %ret = phi i32 [ 4, %l1 ], [ 3, %entry ] |
| ret i32 %ret |
| } |
| |
| define ptr @get(i64 %i) { |
| %p = getelementptr inbounds [2 x ptr], ptr @kfuncs, i64 0, i64 %i |
| %v = load ptr, ptr %p, align 8 |
| ret ptr %v |
| } |