1; RUN: llc < %s -march=bpfel -show-mc-encoding | FileCheck %s
2
3%struct.bpf_map_def = type { i32, i32, i32, i32 }
4%struct.sk_buff = type opaque
5
6@hash_map = global %struct.bpf_map_def { i32 1, i32 4, i32 8, i32 1024 }, section "maps", align 4
7
8; Function Attrs: nounwind uwtable
9define i32 @bpf_prog2(%struct.sk_buff* %skb) #0 section "socket2" {
10  %key = alloca i32, align 4
11  %val = alloca i64, align 8
12  %1 = bitcast %struct.sk_buff* %skb to i8*
13  %2 = call i64 @llvm.bpf.load.half(i8* %1, i64 12) #2
14  %3 = icmp eq i64 %2, 34984
15  br i1 %3, label %4, label %6
16
17; <label>:4                                       ; preds = %0
18  %5 = call i64 @llvm.bpf.load.half(i8* %1, i64 16) #2
19  br label %6
20
21; <label>:6                                       ; preds = %4, %0
22  %proto.0.i = phi i64 [ %5, %4 ], [ %2, %0 ]
23  %nhoff.0.i = phi i64 [ 18, %4 ], [ 14, %0 ]
24  %7 = icmp eq i64 %proto.0.i, 33024
25  br i1 %7, label %8, label %12
26
27; <label>:8                                       ; preds = %6
28  %9 = add i64 %nhoff.0.i, 2
29  %10 = call i64 @llvm.bpf.load.half(i8* %1, i64 %9) #2
30  %11 = add i64 %nhoff.0.i, 4
31  br label %12
32
33; <label>:12                                      ; preds = %8, %6
34  %proto.1.i = phi i64 [ %10, %8 ], [ %proto.0.i, %6 ]
35  %nhoff.1.i = phi i64 [ %11, %8 ], [ %nhoff.0.i, %6 ]
36  switch i64 %proto.1.i, label %flow_dissector.exit.thread [
37    i64 2048, label %13
38    i64 34525, label %39
39  ]
40
41; <label>:13                                      ; preds = %12
42  %14 = add i64 %nhoff.1.i, 6
43  %15 = call i64 @llvm.bpf.load.half(i8* %1, i64 %14) #2
44  %16 = and i64 %15, 16383
45  %17 = icmp eq i64 %16, 0
46  br i1 %17, label %18, label %.thread.i.i
47
48; <label>:18                                      ; preds = %13
49  %19 = add i64 %nhoff.1.i, 9
50  %20 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %19) #2
51  %21 = icmp eq i64 %20, 47
52  br i1 %21, label %28, label %.thread.i.i
53
54.thread.i.i:                                      ; preds = %18, %13
55  %22 = phi i64 [ %20, %18 ], [ 0, %13 ]
56  %23 = add i64 %nhoff.1.i, 12
57  %24 = call i64 @llvm.bpf.load.word(i8* %1, i64 %23) #2
58  %25 = add i64 %nhoff.1.i, 16
59  %26 = call i64 @llvm.bpf.load.word(i8* %1, i64 %25) #2
60  %27 = trunc i64 %26 to i32
61  br label %28
62
63; <label>:28                                      ; preds = %.thread.i.i, %18
64  %29 = phi i32 [ %27, %.thread.i.i ], [ undef, %18 ]
65  %30 = phi i64 [ %22, %.thread.i.i ], [ 47, %18 ]
66  %31 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %nhoff.1.i) #2
67  %32 = icmp eq i64 %31, 69
68  br i1 %32, label %33, label %35
69
70; <label>:33                                      ; preds = %28
71  %34 = add i64 %nhoff.1.i, 20
72  br label %parse_ip.exit.i
73
74; <label>:35                                      ; preds = %28
75  %36 = shl i64 %31, 2
76  %37 = and i64 %36, 60
77  %38 = add i64 %37, %nhoff.1.i
78  br label %parse_ip.exit.i
79
80; <label>:39                                      ; preds = %12
81  %40 = add i64 %nhoff.1.i, 6
82  %41 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %40) #2
83  %42 = add i64 %nhoff.1.i, 8
84  %43 = call i64 @llvm.bpf.load.word(i8* %1, i64 %42) #2
85  %44 = add i64 %nhoff.1.i, 12
86  %45 = call i64 @llvm.bpf.load.word(i8* %1, i64 %44) #2
87  %46 = add i64 %nhoff.1.i, 16
88  %47 = call i64 @llvm.bpf.load.word(i8* %1, i64 %46) #2
89  %48 = add i64 %nhoff.1.i, 20
90  %49 = call i64 @llvm.bpf.load.word(i8* %1, i64 %48) #2
91  %50 = add i64 %nhoff.1.i, 24
92  %51 = call i64 @llvm.bpf.load.word(i8* %1, i64 %50) #2
93  %52 = add i64 %nhoff.1.i, 28
94  %53 = call i64 @llvm.bpf.load.word(i8* %1, i64 %52) #2
95  %54 = add i64 %nhoff.1.i, 32
96  %55 = call i64 @llvm.bpf.load.word(i8* %1, i64 %54) #2
97  %56 = add i64 %nhoff.1.i, 36
98  %57 = call i64 @llvm.bpf.load.word(i8* %1, i64 %56) #2
99  %58 = xor i64 %53, %51
100  %59 = xor i64 %58, %55
101  %60 = xor i64 %59, %57
102  %61 = trunc i64 %60 to i32
103  %62 = add i64 %nhoff.1.i, 40
104  br label %parse_ip.exit.i
105
106parse_ip.exit.i:                                  ; preds = %39, %35, %33
107  %63 = phi i32 [ %61, %39 ], [ %29, %33 ], [ %29, %35 ]
108  %64 = phi i64 [ %41, %39 ], [ %30, %33 ], [ %30, %35 ]
109  %nhoff.2.i = phi i64 [ %62, %39 ], [ %34, %33 ], [ %38, %35 ]
110  switch i64 %64, label %187 [
111    i64 47, label %65
112    i64 4, label %137
113    i64 41, label %163
114  ]
115
116; <label>:65                                      ; preds = %parse_ip.exit.i
117  %66 = call i64 @llvm.bpf.load.half(i8* %1, i64 %nhoff.2.i) #2
118  %67 = add i64 %nhoff.2.i, 2
119  %68 = call i64 @llvm.bpf.load.half(i8* %1, i64 %67) #2
120  %69 = and i64 %66, 1856
121  %70 = icmp eq i64 %69, 0
122  br i1 %70, label %71, label %187
123
124; <label>:71                                      ; preds = %65
125  %72 = lshr i64 %66, 5
126  %73 = and i64 %72, 4
127  %74 = add i64 %nhoff.2.i, 4
128  %..i = add i64 %74, %73
129  %75 = and i64 %66, 32
130  %76 = icmp eq i64 %75, 0
131  %77 = add i64 %..i, 4
132  %nhoff.4.i = select i1 %76, i64 %..i, i64 %77
133  %78 = and i64 %66, 16
134  %79 = icmp eq i64 %78, 0
135  %80 = add i64 %nhoff.4.i, 4
136  %nhoff.4..i = select i1 %79, i64 %nhoff.4.i, i64 %80
137  %81 = icmp eq i64 %68, 33024
138  br i1 %81, label %82, label %86
139
140; <label>:82                                      ; preds = %71
141  %83 = add i64 %nhoff.4..i, 2
142  %84 = call i64 @llvm.bpf.load.half(i8* %1, i64 %83) #2
143  %85 = add i64 %nhoff.4..i, 4
144  br label %86
145
146; <label>:86                                      ; preds = %82, %71
147  %proto.2.i = phi i64 [ %84, %82 ], [ %68, %71 ]
148  %nhoff.6.i = phi i64 [ %85, %82 ], [ %nhoff.4..i, %71 ]
149  switch i64 %proto.2.i, label %flow_dissector.exit.thread [
150    i64 2048, label %87
151    i64 34525, label %113
152  ]
153
154; <label>:87                                      ; preds = %86
155  %88 = add i64 %nhoff.6.i, 6
156  %89 = call i64 @llvm.bpf.load.half(i8* %1, i64 %88) #2
157  %90 = and i64 %89, 16383
158  %91 = icmp eq i64 %90, 0
159  br i1 %91, label %92, label %.thread.i4.i
160
161; <label>:92                                      ; preds = %87
162  %93 = add i64 %nhoff.6.i, 9
163  %94 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %93) #2
164  %95 = icmp eq i64 %94, 47
165  br i1 %95, label %102, label %.thread.i4.i
166
167.thread.i4.i:                                     ; preds = %92, %87
168  %96 = phi i64 [ %94, %92 ], [ 0, %87 ]
169  %97 = add i64 %nhoff.6.i, 12
170  %98 = call i64 @llvm.bpf.load.word(i8* %1, i64 %97) #2
171  %99 = add i64 %nhoff.6.i, 16
172  %100 = call i64 @llvm.bpf.load.word(i8* %1, i64 %99) #2
173  %101 = trunc i64 %100 to i32
174  br label %102
175
176; <label>:102                                     ; preds = %.thread.i4.i, %92
177  %103 = phi i32 [ %101, %.thread.i4.i ], [ %63, %92 ]
178  %104 = phi i64 [ %96, %.thread.i4.i ], [ 47, %92 ]
179  %105 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %nhoff.6.i) #2
180  %106 = icmp eq i64 %105, 69
181  br i1 %106, label %107, label %109
182
183; <label>:107                                     ; preds = %102
184  %108 = add i64 %nhoff.6.i, 20
185  br label %187
186
187; <label>:109                                     ; preds = %102
188  %110 = shl i64 %105, 2
189  %111 = and i64 %110, 60
190  %112 = add i64 %111, %nhoff.6.i
191  br label %187
192
193; <label>:113                                     ; preds = %86
194  %114 = add i64 %nhoff.6.i, 6
195  %115 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %114) #2
196  %116 = add i64 %nhoff.6.i, 8
197  %117 = call i64 @llvm.bpf.load.word(i8* %1, i64 %116) #2
198  %118 = add i64 %nhoff.6.i, 12
199  %119 = call i64 @llvm.bpf.load.word(i8* %1, i64 %118) #2
200  %120 = add i64 %nhoff.6.i, 16
201  %121 = call i64 @llvm.bpf.load.word(i8* %1, i64 %120) #2
202  %122 = add i64 %nhoff.6.i, 20
203  %123 = call i64 @llvm.bpf.load.word(i8* %1, i64 %122) #2
204  %124 = add i64 %nhoff.6.i, 24
205  %125 = call i64 @llvm.bpf.load.word(i8* %1, i64 %124) #2
206  %126 = add i64 %nhoff.6.i, 28
207  %127 = call i64 @llvm.bpf.load.word(i8* %1, i64 %126) #2
208  %128 = add i64 %nhoff.6.i, 32
209  %129 = call i64 @llvm.bpf.load.word(i8* %1, i64 %128) #2
210  %130 = add i64 %nhoff.6.i, 36
211  %131 = call i64 @llvm.bpf.load.word(i8* %1, i64 %130) #2
212  %132 = xor i64 %127, %125
213  %133 = xor i64 %132, %129
214  %134 = xor i64 %133, %131
215  %135 = trunc i64 %134 to i32
216  %136 = add i64 %nhoff.6.i, 40
217  br label %187
218
219; <label>:137                                     ; preds = %parse_ip.exit.i
220  %138 = add i64 %nhoff.2.i, 6
221  %139 = call i64 @llvm.bpf.load.half(i8* %1, i64 %138) #2
222  %140 = and i64 %139, 16383
223  %141 = icmp eq i64 %140, 0
224  br i1 %141, label %142, label %.thread.i1.i
225
226; <label>:142                                     ; preds = %137
227  %143 = add i64 %nhoff.2.i, 9
228  %144 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %143) #2
229  %145 = icmp eq i64 %144, 47
230  br i1 %145, label %152, label %.thread.i1.i
231
232.thread.i1.i:                                     ; preds = %142, %137
233  %146 = phi i64 [ %144, %142 ], [ 0, %137 ]
234  %147 = add i64 %nhoff.2.i, 12
235  %148 = call i64 @llvm.bpf.load.word(i8* %1, i64 %147) #2
236  %149 = add i64 %nhoff.2.i, 16
237  %150 = call i64 @llvm.bpf.load.word(i8* %1, i64 %149) #2
238  %151 = trunc i64 %150 to i32
239  br label %152
240
241; <label>:152                                     ; preds = %.thread.i1.i, %142
242  %153 = phi i32 [ %151, %.thread.i1.i ], [ %63, %142 ]
243  %154 = phi i64 [ %146, %.thread.i1.i ], [ 47, %142 ]
244  %155 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %nhoff.2.i) #2
245  %156 = icmp eq i64 %155, 69
246  br i1 %156, label %157, label %159
247
248; <label>:157                                     ; preds = %152
249  %158 = add i64 %nhoff.2.i, 20
250  br label %187
251
252; <label>:159                                     ; preds = %152
253  %160 = shl i64 %155, 2
254  %161 = and i64 %160, 60
255  %162 = add i64 %161, %nhoff.2.i
256  br label %187
257
258; <label>:163                                     ; preds = %parse_ip.exit.i
259  %164 = add i64 %nhoff.2.i, 6
260  %165 = call i64 @llvm.bpf.load.byte(i8* %1, i64 %164) #2
261  %166 = add i64 %nhoff.2.i, 8
262  %167 = call i64 @llvm.bpf.load.word(i8* %1, i64 %166) #2
263  %168 = add i64 %nhoff.2.i, 12
264  %169 = call i64 @llvm.bpf.load.word(i8* %1, i64 %168) #2
265  %170 = add i64 %nhoff.2.i, 16
266  %171 = call i64 @llvm.bpf.load.word(i8* %1, i64 %170) #2
267  %172 = add i64 %nhoff.2.i, 20
268  %173 = call i64 @llvm.bpf.load.word(i8* %1, i64 %172) #2
269  %174 = add i64 %nhoff.2.i, 24
270  %175 = call i64 @llvm.bpf.load.word(i8* %1, i64 %174) #2
271  %176 = add i64 %nhoff.2.i, 28
272  %177 = call i64 @llvm.bpf.load.word(i8* %1, i64 %176) #2
273  %178 = add i64 %nhoff.2.i, 32
274  %179 = call i64 @llvm.bpf.load.word(i8* %1, i64 %178) #2
275  %180 = add i64 %nhoff.2.i, 36
276  %181 = call i64 @llvm.bpf.load.word(i8* %1, i64 %180) #2
277  %182 = xor i64 %177, %175
278  %183 = xor i64 %182, %179
279  %184 = xor i64 %183, %181
280  %185 = trunc i64 %184 to i32
281  %186 = add i64 %nhoff.2.i, 40
282  br label %187
283
284; <label>:187                                     ; preds = %163, %159, %157, %113, %109, %107, %65, %parse_ip.exit.i
285  %188 = phi i32 [ %63, %parse_ip.exit.i ], [ %185, %163 ], [ %63, %65 ], [ %135, %113 ], [ %103, %107 ], [ %103, %109 ], [ %153, %157 ], [ %153, %159 ]
286  %189 = phi i64 [ %64, %parse_ip.exit.i ], [ %165, %163 ], [ 47, %65 ], [ %115, %113 ], [ %104, %107 ], [ %104, %109 ], [ %154, %157 ], [ %154, %159 ]
287  %nhoff.7.i = phi i64 [ %nhoff.2.i, %parse_ip.exit.i ], [ %186, %163 ], [ %nhoff.2.i, %65 ], [ %136, %113 ], [ %108, %107 ], [ %112, %109 ], [ %158, %157 ], [ %162, %159 ]
288  %cond.i.i = icmp eq i64 %189, 51
289  %190 = select i1 %cond.i.i, i64 4, i64 0
290  %191 = add i64 %190, %nhoff.7.i
291  %192 = call i64 @llvm.bpf.load.word(i8* %1, i64 %191) #2
292  store i32 %188, i32* %key, align 4
293  %193 = bitcast i32* %key to i8*
294  %194 = call i8* inttoptr (i64 1 to i8* (i8*, i8*)*)(i8* bitcast (%struct.bpf_map_def* @hash_map to i8*), i8* %193) #2
295  %195 = icmp eq i8* %194, null
296  br i1 %195, label %199, label %196
297
298; <label>:196                                     ; preds = %187
299  %197 = bitcast i8* %194 to i64*
300  %198 = atomicrmw add i64* %197, i64 1 seq_cst
301  br label %flow_dissector.exit.thread
302
303; <label>:199                                     ; preds = %187
304  store i64 1, i64* %val, align 8
305  %200 = bitcast i64* %val to i8*
306  %201 = call i32 inttoptr (i64 2 to i32 (i8*, i8*, i8*, i64)*)(i8* bitcast (%struct.bpf_map_def* @hash_map to i8*), i8* %193, i8* %200, i64 0) #2
307  br label %flow_dissector.exit.thread
308
309flow_dissector.exit.thread:                       ; preds = %86, %12, %196, %199
310  ret i32 0
311; CHECK-LABEL: bpf_prog2:
312; CHECK: r0 = *(u16 *)skb[12] # encoding: [0x28,0x00,0x00,0x00,0x0c,0x00,0x00,0x00]
313; CHECK: r0 = *(u16 *)skb[16] # encoding: [0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00]
314; CHECK: implicit-def: $r1
315; CHECK: r1 =
316; CHECK: call 1 # encoding: [0x85,0x00,0x00,0x00,0x01,0x00,0x00,0x00]
317; CHECK: call 2 # encoding: [0x85,0x00,0x00,0x00,0x02,0x00,0x00,0x00]
318}
319
320declare i64 @llvm.bpf.load.half(i8*, i64) #1
321
322declare i64 @llvm.bpf.load.word(i8*, i64) #1
323
324declare i64 @llvm.bpf.load.byte(i8*, i64) #1
325