Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -march=x86-64 -mattr=+bmi,+bmi2 | FileCheck %s
      2 
      3 declare i8 @llvm.cttz.i8(i8, i1) nounwind readnone
      4 declare i16 @llvm.cttz.i16(i16, i1) nounwind readnone
      5 declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
      6 declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone
      7 
      8 define i8 @t1(i8 %x) nounwind  {
      9   %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 false )
     10   ret i8 %tmp
     11 ; CHECK-LABEL: t1:
     12 ; CHECK: tzcntl
     13 }
     14 
     15 define i16 @t2(i16 %x) nounwind  {
     16   %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 false )
     17   ret i16 %tmp
     18 ; CHECK-LABEL: t2:
     19 ; CHECK: tzcntw
     20 }
     21 
     22 define i32 @t3(i32 %x) nounwind  {
     23   %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 false )
     24   ret i32 %tmp
     25 ; CHECK-LABEL: t3:
     26 ; CHECK: tzcntl
     27 }
     28 
     29 define i32 @tzcnt32_load(i32* %x) nounwind  {
     30   %x1 = load i32, i32* %x
     31   %tmp = tail call i32 @llvm.cttz.i32(i32 %x1, i1 false )
     32   ret i32 %tmp
     33 ; CHECK-LABEL: tzcnt32_load:
     34 ; CHECK: tzcntl ({{.*}})
     35 }
     36 
     37 define i64 @t4(i64 %x) nounwind  {
     38   %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 false )
     39   ret i64 %tmp
     40 ; CHECK-LABEL: t4:
     41 ; CHECK: tzcntq
     42 }
     43 
     44 define i8 @t5(i8 %x) nounwind  {
     45   %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 true )
     46   ret i8 %tmp
     47 ; CHECK-LABEL: t5:
     48 ; CHECK: tzcntl
     49 }
     50 
     51 define i16 @t6(i16 %x) nounwind  {
     52   %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 true )
     53   ret i16 %tmp
     54 ; CHECK-LABEL: t6:
     55 ; CHECK: tzcntw
     56 }
     57 
     58 define i32 @t7(i32 %x) nounwind  {
     59   %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 true )
     60   ret i32 %tmp
     61 ; CHECK-LABEL: t7:
     62 ; CHECK: tzcntl
     63 }
     64 
     65 define i64 @t8(i64 %x) nounwind  {
     66   %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 true )
     67   ret i64 %tmp
     68 ; CHECK-LABEL: t8:
     69 ; CHECK: tzcntq
     70 }
     71 
     72 define i32 @andn32(i32 %x, i32 %y) nounwind readnone {
     73   %tmp1 = xor i32 %x, -1
     74   %tmp2 = and i32 %y, %tmp1
     75   ret i32 %tmp2
     76 ; CHECK-LABEL: andn32:
     77 ; CHECK: andnl
     78 }
     79 
     80 define i32 @andn32_load(i32 %x, i32* %y) nounwind readnone {
     81   %y1 = load i32, i32* %y
     82   %tmp1 = xor i32 %x, -1
     83   %tmp2 = and i32 %y1, %tmp1
     84   ret i32 %tmp2
     85 ; CHECK-LABEL: andn32_load:
     86 ; CHECK: andnl ({{.*}})
     87 }
     88 
     89 define i64 @andn64(i64 %x, i64 %y) nounwind readnone {
     90   %tmp1 = xor i64 %x, -1
     91   %tmp2 = and i64 %tmp1, %y
     92   ret i64 %tmp2
     93 ; CHECK-LABEL: andn64:
     94 ; CHECK: andnq
     95 }
     96 
     97 define i32 @bextr32(i32 %x, i32 %y) nounwind readnone {
     98   %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)
     99   ret i32 %tmp
    100 ; CHECK-LABEL: bextr32:
    101 ; CHECK: bextrl
    102 }
    103 
    104 define i32 @bextr32_load(i32* %x, i32 %y) nounwind readnone {
    105   %x1 = load i32, i32* %x
    106   %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x1, i32 %y)
    107   ret i32 %tmp
    108 ; CHECK-LABEL: bextr32_load:
    109 ; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}}
    110 }
    111 
    112 declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone
    113 
    114 define i32 @bextr32b(i32 %x) nounwind uwtable readnone ssp {
    115   %1 = lshr i32 %x, 4
    116   %2 = and i32 %1, 4095
    117   ret i32 %2
    118 ; CHECK-LABEL: bextr32b:
    119 ; CHECK: bextrl
    120 }
    121 
    122 define i32 @bextr32b_load(i32* %x) nounwind uwtable readnone ssp {
    123   %1 = load i32, i32* %x
    124   %2 = lshr i32 %1, 4
    125   %3 = and i32 %2, 4095
    126   ret i32 %3
    127 ; CHECK-LABEL: bextr32b_load:
    128 ; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}}
    129 }
    130 
    131 define i64 @bextr64(i64 %x, i64 %y) nounwind readnone {
    132   %tmp = tail call i64 @llvm.x86.bmi.bextr.64(i64 %x, i64 %y)
    133   ret i64 %tmp
    134 ; CHECK-LABEL: bextr64:
    135 ; CHECK: bextrq
    136 }
    137 
    138 declare i64 @llvm.x86.bmi.bextr.64(i64, i64) nounwind readnone
    139 
    140 define i64 @bextr64b(i64 %x) nounwind uwtable readnone ssp {
    141   %1 = lshr i64 %x, 4
    142   %2 = and i64 %1, 4095
    143   ret i64 %2
    144 ; CHECK-LABEL: bextr64b:
    145 ; CHECK: bextrq
    146 }
    147 
    148 define i64 @bextr64b_load(i64* %x) {
    149   %1 = load i64, i64* %x, align 8
    150   %2 = lshr i64 %1, 4
    151   %3 = and i64 %2, 4095
    152   ret i64 %3
    153 ; CHECK-LABEL: bextr64b_load:
    154 ; CHECK: bextrq {{.*}}, ({{.*}}), {{.*}}
    155 }
    156 
    157 define i32 @non_bextr32(i32 %x) {
    158 entry:
    159   %shr = lshr i32 %x, 2
    160   %and = and i32 %shr, 111
    161   ret i32 %and
    162 ; CHECK-LABEL: non_bextr32:
    163 ; CHECK: shrl $2
    164 ; CHECK: andl $111
    165 }
    166 
    167 define i64 @non_bextr64(i64 %x) {
    168 entry:
    169   %shr = lshr i64 %x, 2
    170   %and = and i64 %shr, 8589934590
    171   ret i64 %and
    172 ; CHECK-LABEL: non_bextr64:
    173 ; CHECK: shrq $2
    174 ; CHECK: movabsq $8589934590
    175 ; CHECK: andq 
    176 }
    177 
    178 define i32 @bzhi32(i32 %x, i32 %y) nounwind readnone {
    179   %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x, i32 %y)
    180   ret i32 %tmp
    181 ; CHECK-LABEL: bzhi32:
    182 ; CHECK: bzhil
    183 }
    184 
    185 define i32 @bzhi32_load(i32* %x, i32 %y) nounwind readnone {
    186   %x1 = load i32, i32* %x
    187   %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x1, i32 %y)
    188   ret i32 %tmp
    189 ; CHECK-LABEL: bzhi32_load:
    190 ; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}}
    191 }
    192 
    193 declare i32 @llvm.x86.bmi.bzhi.32(i32, i32) nounwind readnone
    194 
    195 define i64 @bzhi64(i64 %x, i64 %y) nounwind readnone {
    196   %tmp = tail call i64 @llvm.x86.bmi.bzhi.64(i64 %x, i64 %y)
    197   ret i64 %tmp
    198 ; CHECK-LABEL: bzhi64:
    199 ; CHECK: bzhiq
    200 }
    201 
    202 declare i64 @llvm.x86.bmi.bzhi.64(i64, i64) nounwind readnone
    203 
    204 define i32 @bzhi32b(i32 %x, i8 zeroext %index) #0 {
    205 entry:
    206   %conv = zext i8 %index to i32
    207   %shl = shl i32 1, %conv
    208   %sub = add nsw i32 %shl, -1
    209   %and = and i32 %sub, %x
    210   ret i32 %and
    211 ; CHECK-LABEL: bzhi32b:
    212 ; CHECK: bzhil
    213 }
    214 
    215 define i32 @bzhi32b_load(i32* %w, i8 zeroext %index) #0 {
    216 entry:
    217   %x = load i32, i32* %w
    218   %conv = zext i8 %index to i32
    219   %shl = shl i32 1, %conv
    220   %sub = add nsw i32 %shl, -1
    221   %and = and i32 %sub, %x
    222   ret i32 %and
    223 ; CHECK-LABEL: bzhi32b_load:
    224 ; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}}
    225 }
    226 
    227 define i32 @bzhi32c(i32 %x, i8 zeroext %index) #0 {
    228 entry:
    229   %conv = zext i8 %index to i32
    230   %shl = shl i32 1, %conv
    231   %sub = add nsw i32 %shl, -1
    232   %and = and i32 %x, %sub
    233   ret i32 %and
    234 ; CHECK-LABEL: bzhi32c:
    235 ; CHECK: bzhil
    236 }
    237 
    238 define i64 @bzhi64b(i64 %x, i8 zeroext %index) #0 {
    239 entry:
    240   %conv = zext i8 %index to i64
    241   %shl = shl i64 1, %conv
    242   %sub = add nsw i64 %shl, -1
    243   %and = and i64 %x, %sub
    244   ret i64 %and
    245 ; CHECK-LABEL: bzhi64b:
    246 ; CHECK: bzhiq
    247 }
    248 
    249 define i64 @bzhi64_constant_mask(i64 %x) #0 {
    250 entry:
    251   %and = and i64 %x, 4611686018427387903
    252   ret i64 %and
    253 ; CHECK-LABEL: bzhi64_constant_mask:
    254 ; CHECK: movb    $62, %al
    255 ; CHECK: bzhiq   %rax, %r[[ARG1:di|cx]], %rax
    256 }
    257 
    258 define i64 @bzhi64_small_constant_mask(i64 %x) #0 {
    259 entry:
    260   %and = and i64 %x, 2147483647
    261   ret i64 %and
    262 ; CHECK-LABEL: bzhi64_small_constant_mask:
    263 ; CHECK: andl  $2147483647, %e[[ARG1]]
    264 }
    265 
    266 define i32 @blsi32(i32 %x) nounwind readnone {
    267   %tmp = sub i32 0, %x
    268   %tmp2 = and i32 %x, %tmp
    269   ret i32 %tmp2
    270 ; CHECK-LABEL: blsi32:
    271 ; CHECK: blsil
    272 }
    273 
    274 define i32 @blsi32_load(i32* %x) nounwind readnone {
    275   %x1 = load i32, i32* %x
    276   %tmp = sub i32 0, %x1
    277   %tmp2 = and i32 %x1, %tmp
    278   ret i32 %tmp2
    279 ; CHECK-LABEL: blsi32_load:
    280 ; CHECK: blsil ({{.*}})
    281 }
    282 
    283 define i64 @blsi64(i64 %x) nounwind readnone {
    284   %tmp = sub i64 0, %x
    285   %tmp2 = and i64 %tmp, %x
    286   ret i64 %tmp2
    287 ; CHECK-LABEL: blsi64:
    288 ; CHECK: blsiq
    289 }
    290 
    291 define i32 @blsmsk32(i32 %x) nounwind readnone {
    292   %tmp = sub i32 %x, 1
    293   %tmp2 = xor i32 %x, %tmp
    294   ret i32 %tmp2
    295 ; CHECK-LABEL: blsmsk32:
    296 ; CHECK: blsmskl
    297 }
    298 
    299 define i32 @blsmsk32_load(i32* %x) nounwind readnone {
    300   %x1 = load i32, i32* %x
    301   %tmp = sub i32 %x1, 1
    302   %tmp2 = xor i32 %x1, %tmp
    303   ret i32 %tmp2
    304 ; CHECK-LABEL: blsmsk32_load:
    305 ; CHECK: blsmskl ({{.*}})
    306 }
    307 
    308 define i64 @blsmsk64(i64 %x) nounwind readnone {
    309   %tmp = sub i64 %x, 1
    310   %tmp2 = xor i64 %tmp, %x
    311   ret i64 %tmp2
    312 ; CHECK-LABEL: blsmsk64:
    313 ; CHECK: blsmskq
    314 }
    315 
    316 define i32 @blsr32(i32 %x) nounwind readnone {
    317   %tmp = sub i32 %x, 1
    318   %tmp2 = and i32 %x, %tmp
    319   ret i32 %tmp2
    320 ; CHECK-LABEL: blsr32:
    321 ; CHECK: blsrl
    322 }
    323 
    324 define i32 @blsr32_load(i32* %x) nounwind readnone {
    325   %x1 = load i32, i32* %x
    326   %tmp = sub i32 %x1, 1
    327   %tmp2 = and i32 %x1, %tmp
    328   ret i32 %tmp2
    329 ; CHECK-LABEL: blsr32_load:
    330 ; CHECK: blsrl ({{.*}})
    331 }
    332 
    333 define i64 @blsr64(i64 %x) nounwind readnone {
    334   %tmp = sub i64 %x, 1
    335   %tmp2 = and i64 %tmp, %x
    336   ret i64 %tmp2
    337 ; CHECK-LABEL: blsr64:
    338 ; CHECK: blsrq
    339 }
    340 
    341 define i32 @pdep32(i32 %x, i32 %y) nounwind readnone {
    342   %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y)
    343   ret i32 %tmp
    344 ; CHECK-LABEL: pdep32:
    345 ; CHECK: pdepl
    346 }
    347 
    348 define i32 @pdep32_load(i32 %x, i32* %y) nounwind readnone {
    349   %y1 = load i32, i32* %y
    350   %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y1)
    351   ret i32 %tmp
    352 ; CHECK-LABEL: pdep32_load:
    353 ; CHECK: pdepl ({{.*}})
    354 }
    355 
    356 declare i32 @llvm.x86.bmi.pdep.32(i32, i32) nounwind readnone
    357 
    358 define i64 @pdep64(i64 %x, i64 %y) nounwind readnone {
    359   %tmp = tail call i64 @llvm.x86.bmi.pdep.64(i64 %x, i64 %y)
    360   ret i64 %tmp
    361 ; CHECK-LABEL: pdep64:
    362 ; CHECK: pdepq
    363 }
    364 
    365 declare i64 @llvm.x86.bmi.pdep.64(i64, i64) nounwind readnone
    366 
    367 define i32 @pext32(i32 %x, i32 %y) nounwind readnone {
    368   %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y)
    369   ret i32 %tmp
    370 ; CHECK-LABEL: pext32:
    371 ; CHECK: pextl
    372 }
    373 
    374 define i32 @pext32_load(i32 %x, i32* %y) nounwind readnone {
    375   %y1 = load i32, i32* %y
    376   %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y1)
    377   ret i32 %tmp
    378 ; CHECK-LABEL: pext32_load:
    379 ; CHECK: pextl ({{.*}})
    380 }
    381 
    382 declare i32 @llvm.x86.bmi.pext.32(i32, i32) nounwind readnone
    383 
    384 define i64 @pext64(i64 %x, i64 %y) nounwind readnone {
    385   %tmp = tail call i64 @llvm.x86.bmi.pext.64(i64 %x, i64 %y)
    386   ret i64 %tmp
    387 ; CHECK-LABEL: pext64:
    388 ; CHECK: pextq
    389 }
    390 
    391 declare i64 @llvm.x86.bmi.pext.64(i64, i64) nounwind readnone
    392 
    393