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 9 define 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 106 parse_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 309 flow_dissector.exit.thread: ; preds = %86, %12, %196, %199 310 ret i32 0 311 ; CHECK-LABEL: bpf_prog2: 312 ; CHECK: ldabs_h r0, r6.data + 12 # encoding: [0x28,0x00,0x00,0x00,0x0c,0x00,0x00,0x00] 313 ; CHECK: ldabs_h r0, r6.data + 16 # encoding: [0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00] 314 ; CHECK: implicit-def: %R1 315 ; CHECK: ld_64 r1 316 ; CHECK-NOT: ori 317 ; CHECK: call 1 # encoding: [0x85,0x00,0x00,0x00,0x01,0x00,0x00,0x00] 318 ; CHECK: call 2 # encoding: [0x85,0x00,0x00,0x00,0x02,0x00,0x00,0x00] 319 } 320 321 declare i64 @llvm.bpf.load.half(i8*, i64) #1 322 323 declare i64 @llvm.bpf.load.word(i8*, i64) #1 324 325 declare i64 @llvm.bpf.load.byte(i8*, i64) #1 326