Home | History | Annotate | Download | only in BPF
      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