Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+lzcnt | FileCheck %s
      2 
      3 ; LZCNT and TZCNT will always produce the operand size when the input operand
      4 ; is zero. This test is to verify that we efficiently select LZCNT/TZCNT
      5 ; based on the fact that the 'icmp+select' sequence is always redundant
      6 ; in every function defined below.
      7 
      8 
      9 define i16 @test1_ctlz(i16 %v) {
     10   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
     11   %tobool = icmp eq i16 %v, 0
     12   %cond = select i1 %tobool, i16 16, i16 %cnt
     13   ret i16 %cond
     14 }
     15 ; CHECK-LABEL: test1_ctlz
     16 ; CHECK: lzcnt
     17 ; CHECK-NEXT: ret
     18 
     19 
     20 define i32 @test2_ctlz(i32 %v) {
     21   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
     22   %tobool = icmp eq i32 %v, 0
     23   %cond = select i1 %tobool, i32 32, i32 %cnt
     24   ret i32 %cond
     25 }
     26 ; CHECK-LABEL: test2_ctlz
     27 ; CHECK: lzcnt
     28 ; CHECK-NEXT: ret
     29 
     30 
     31 define i64 @test3_ctlz(i64 %v) {
     32   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
     33   %tobool = icmp eq i64 %v, 0
     34   %cond = select i1 %tobool, i64 64, i64 %cnt
     35   ret i64 %cond
     36 }
     37 ; CHECK-LABEL: test3_ctlz
     38 ; CHECK: lzcnt
     39 ; CHECK-NEXT: ret
     40 
     41 
     42 define i16 @test4_ctlz(i16 %v) {
     43   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
     44   %tobool = icmp eq i16 0, %v
     45   %cond = select i1 %tobool, i16 16, i16 %cnt
     46   ret i16 %cond
     47 }
     48 ; CHECK-LABEL: test4_ctlz
     49 ; CHECK: lzcnt
     50 ; CHECK-NEXT: ret
     51 
     52 
     53 define i32 @test5_ctlz(i32 %v) {
     54   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
     55   %tobool = icmp eq i32 0, %v
     56   %cond = select i1 %tobool, i32 32, i32 %cnt
     57   ret i32 %cond
     58 }
     59 ; CHECK-LABEL: test5_ctlz
     60 ; CHECK: lzcnt
     61 ; CHECK-NEXT: ret
     62 
     63 
     64 define i64 @test6_ctlz(i64 %v) {
     65   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
     66   %tobool = icmp eq i64 0, %v
     67   %cond = select i1 %tobool, i64 64, i64 %cnt
     68   ret i64 %cond
     69 }
     70 ; CHECK-LABEL: test6_ctlz
     71 ; CHECK: lzcnt
     72 ; CHECK-NEXT: ret
     73 
     74 
     75 define i16 @test7_ctlz(i16 %v) {
     76   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
     77   %tobool = icmp eq i16 0, %v
     78   %cond = select i1 %tobool, i16 %cnt, i16 16
     79   ret i16 %cond
     80 }
     81 ; CHECK-LABEL: test7_ctlz
     82 ; CHECK: lzcnt
     83 ; CHECK-NEXT: ret
     84 
     85 
     86 define i32 @test8_ctlz(i32 %v) {
     87   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
     88   %tobool = icmp eq i32 0, %v
     89   %cond = select i1 %tobool, i32 %cnt, i32 32
     90   ret i32 %cond
     91 }
     92 ; CHECK-LABEL: test8_ctlz
     93 ; CHECK: lzcnt
     94 ; CHECK-NEXT: ret
     95 
     96 
     97 define i64 @test9_ctlz(i64 %v) {
     98   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
     99   %tobool = icmp eq i64 0, %v
    100   %cond = select i1 %tobool, i64 %cnt, i64 64
    101   ret i64 %cond
    102 }
    103 ; CHECK-LABEL: test9_ctlz
    104 ; CHECK: lzcnt
    105 ; CHECK-NEXT: ret
    106 
    107 
    108 define i16 @test10_ctlz(i16* %ptr) {
    109   %v = load i16* %ptr
    110   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
    111   %tobool = icmp eq i16 %v, 0
    112   %cond = select i1 %tobool, i16 16, i16 %cnt
    113   ret i16 %cond
    114 }
    115 ; CHECK-LABEL: test10_ctlz
    116 ; CHECK-NOT: movw
    117 ; CHECK: lzcnt
    118 ; CHECK-NEXT: ret
    119 
    120 
    121 define i32 @test11_ctlz(i32* %ptr) {
    122   %v = load i32* %ptr
    123   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
    124   %tobool = icmp eq i32 %v, 0
    125   %cond = select i1 %tobool, i32 32, i32 %cnt
    126   ret i32 %cond
    127 }
    128 ; CHECK-LABEL: test11_ctlz
    129 ; CHECK-NOT: movd
    130 ; CHECK: lzcnt
    131 ; CHECK-NEXT: ret
    132 
    133 
    134 define i64 @test12_ctlz(i64* %ptr) {
    135   %v = load i64* %ptr
    136   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    137   %tobool = icmp eq i64 %v, 0
    138   %cond = select i1 %tobool, i64 64, i64 %cnt
    139   ret i64 %cond
    140 }
    141 ; CHECK-LABEL: test12_ctlz
    142 ; CHECK-NOT: movq
    143 ; CHECK: lzcnt
    144 ; CHECK-NEXT: ret
    145 
    146 
    147 define i16 @test13_ctlz(i16* %ptr) {
    148   %v = load i16* %ptr
    149   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
    150   %tobool = icmp eq i16 0, %v
    151   %cond = select i1 %tobool, i16 16, i16 %cnt
    152   ret i16 %cond
    153 }
    154 ; CHECK-LABEL: test13_ctlz
    155 ; CHECK-NOT: movw
    156 ; CHECK: lzcnt
    157 ; CHECK-NEXT: ret
    158 
    159 
    160 define i32 @test14_ctlz(i32* %ptr) {
    161   %v = load i32* %ptr
    162   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
    163   %tobool = icmp eq i32 0, %v
    164   %cond = select i1 %tobool, i32 32, i32 %cnt
    165   ret i32 %cond
    166 }
    167 ; CHECK-LABEL: test14_ctlz
    168 ; CHECK-NOT: movd
    169 ; CHECK: lzcnt
    170 ; CHECK-NEXT: ret
    171 
    172 
    173 define i64 @test15_ctlz(i64* %ptr) {
    174   %v = load i64* %ptr
    175   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    176   %tobool = icmp eq i64 0, %v
    177   %cond = select i1 %tobool, i64 64, i64 %cnt
    178   ret i64 %cond
    179 }
    180 ; CHECK-LABEL: test15_ctlz
    181 ; CHECK-NOT: movq
    182 ; CHECK: lzcnt
    183 ; CHECK-NEXT: ret
    184 
    185 
    186 define i16 @test16_ctlz(i16* %ptr) {
    187   %v = load i16* %ptr
    188   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
    189   %tobool = icmp eq i16 0, %v
    190   %cond = select i1 %tobool, i16 %cnt, i16 16
    191   ret i16 %cond
    192 }
    193 ; CHECK-LABEL: test16_ctlz
    194 ; CHECK-NOT: movw
    195 ; CHECK: lzcnt
    196 ; CHECK-NEXT: ret
    197 
    198 
    199 define i32 @test17_ctlz(i32* %ptr) {
    200   %v = load i32* %ptr
    201   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
    202   %tobool = icmp eq i32 0, %v
    203   %cond = select i1 %tobool, i32 %cnt, i32 32
    204   ret i32 %cond
    205 }
    206 ; CHECK-LABEL: test17_ctlz
    207 ; CHECK-NOT: movd
    208 ; CHECK: lzcnt
    209 ; CHECK-NEXT: ret
    210 
    211 
    212 define i64 @test18_ctlz(i64* %ptr) {
    213   %v = load i64* %ptr
    214   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    215   %tobool = icmp eq i64 0, %v
    216   %cond = select i1 %tobool, i64 %cnt, i64 64
    217   ret i64 %cond
    218 }
    219 ; CHECK-LABEL: test18_ctlz
    220 ; CHECK-NOT: movq
    221 ; CHECK: lzcnt
    222 ; CHECK-NEXT: ret
    223 
    224 
    225 define i16 @test1_cttz(i16 %v) {
    226   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    227   %tobool = icmp eq i16 %v, 0
    228   %cond = select i1 %tobool, i16 16, i16 %cnt
    229   ret i16 %cond
    230 }
    231 ; CHECK-LABEL: test1_cttz
    232 ; CHECK: tzcnt
    233 ; CHECK-NEXT: ret
    234 
    235 
    236 define i32 @test2_cttz(i32 %v) {
    237   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    238   %tobool = icmp eq i32 %v, 0
    239   %cond = select i1 %tobool, i32 32, i32 %cnt
    240   ret i32 %cond
    241 }
    242 ; CHECK-LABEL: test2_cttz
    243 ; CHECK: tzcnt
    244 ; CHECK-NEXT: ret
    245 
    246 
    247 define i64 @test3_cttz(i64 %v) {
    248   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    249   %tobool = icmp eq i64 %v, 0
    250   %cond = select i1 %tobool, i64 64, i64 %cnt
    251   ret i64 %cond
    252 }
    253 ; CHECK-LABEL: test3_cttz
    254 ; CHECK: tzcnt
    255 ; CHECK-NEXT: ret
    256 
    257 
    258 define i16 @test4_cttz(i16 %v) {
    259   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    260   %tobool = icmp eq i16 0, %v
    261   %cond = select i1 %tobool, i16 16, i16 %cnt
    262   ret i16 %cond
    263 }
    264 ; CHECK-LABEL: test4_cttz
    265 ; CHECK: tzcnt
    266 ; CHECK-NEXT: ret
    267 
    268 
    269 define i32 @test5_cttz(i32 %v) {
    270   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    271   %tobool = icmp eq i32 0, %v
    272   %cond = select i1 %tobool, i32 32, i32 %cnt
    273   ret i32 %cond
    274 }
    275 ; CHECK-LABEL: test5_cttz
    276 ; CHECK: tzcnt
    277 ; CHECK-NEXT: ret
    278 
    279 
    280 define i64 @test6_cttz(i64 %v) {
    281   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    282   %tobool = icmp eq i64 0, %v
    283   %cond = select i1 %tobool, i64 64, i64 %cnt
    284   ret i64 %cond
    285 }
    286 ; CHECK-LABEL: test6_cttz
    287 ; CHECK: tzcnt
    288 ; CHECK-NEXT: ret
    289 
    290 
    291 define i16 @test7_cttz(i16 %v) {
    292   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    293   %tobool = icmp eq i16 0, %v
    294   %cond = select i1 %tobool, i16 %cnt, i16 16
    295   ret i16 %cond
    296 }
    297 ; CHECK-LABEL: test7_cttz
    298 ; CHECK: tzcnt
    299 ; CHECK-NEXT: ret
    300 
    301 
    302 define i32 @test8_cttz(i32 %v) {
    303   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    304   %tobool = icmp eq i32 0, %v
    305   %cond = select i1 %tobool, i32 %cnt, i32 32
    306   ret i32 %cond
    307 }
    308 ; CHECK-LABEL: test8_cttz
    309 ; CHECK: tzcnt
    310 ; CHECK-NEXT: ret
    311 
    312 
    313 define i64 @test9_cttz(i64 %v) {
    314   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    315   %tobool = icmp eq i64 0, %v
    316   %cond = select i1 %tobool, i64 %cnt, i64 64
    317   ret i64 %cond
    318 }
    319 ; CHECK-LABEL: test9_cttz
    320 ; CHECK: tzcnt
    321 ; CHECK-NEXT: ret
    322 
    323 
    324 define i16 @test10_cttz(i16* %ptr) {
    325   %v = load i16* %ptr
    326   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    327   %tobool = icmp eq i16 %v, 0
    328   %cond = select i1 %tobool, i16 16, i16 %cnt
    329   ret i16 %cond
    330 }
    331 ; CHECK-LABEL: test10_cttz
    332 ; CHECK-NOT: movw
    333 ; CHECK: tzcnt
    334 ; CHECK-NEXT: ret
    335 
    336 
    337 define i32 @test11_cttz(i32* %ptr) {
    338   %v = load i32* %ptr
    339   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    340   %tobool = icmp eq i32 %v, 0
    341   %cond = select i1 %tobool, i32 32, i32 %cnt
    342   ret i32 %cond
    343 }
    344 ; CHECK-LABEL: test11_cttz
    345 ; CHECK-NOT: movd
    346 ; CHECK: tzcnt
    347 ; CHECK-NEXT: ret
    348 
    349 
    350 define i64 @test12_cttz(i64* %ptr) {
    351   %v = load i64* %ptr
    352   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    353   %tobool = icmp eq i64 %v, 0
    354   %cond = select i1 %tobool, i64 64, i64 %cnt
    355   ret i64 %cond
    356 }
    357 ; CHECK-LABEL: test12_cttz
    358 ; CHECK-NOT: movq
    359 ; CHECK: tzcnt
    360 ; CHECK-NEXT: ret
    361 
    362 
    363 define i16 @test13_cttz(i16* %ptr) {
    364   %v = load i16* %ptr
    365   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    366   %tobool = icmp eq i16 0, %v
    367   %cond = select i1 %tobool, i16 16, i16 %cnt
    368   ret i16 %cond
    369 }
    370 ; CHECK-LABEL: test13_cttz
    371 ; CHECK-NOT: movw
    372 ; CHECK: tzcnt
    373 ; CHECK-NEXT: ret
    374 
    375 
    376 define i32 @test14_cttz(i32* %ptr) {
    377   %v = load i32* %ptr
    378   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    379   %tobool = icmp eq i32 0, %v
    380   %cond = select i1 %tobool, i32 32, i32 %cnt
    381   ret i32 %cond
    382 }
    383 ; CHECK-LABEL: test14_cttz
    384 ; CHECK-NOT: movd
    385 ; CHECK: tzcnt
    386 ; CHECK-NEXT: ret
    387 
    388 
    389 define i64 @test15_cttz(i64* %ptr) {
    390   %v = load i64* %ptr
    391   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    392   %tobool = icmp eq i64 0, %v
    393   %cond = select i1 %tobool, i64 64, i64 %cnt
    394   ret i64 %cond
    395 }
    396 ; CHECK-LABEL: test15_cttz
    397 ; CHECK-NOT: movq
    398 ; CHECK: tzcnt
    399 ; CHECK-NEXT: ret
    400 
    401 
    402 define i16 @test16_cttz(i16* %ptr) {
    403   %v = load i16* %ptr
    404   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    405   %tobool = icmp eq i16 0, %v
    406   %cond = select i1 %tobool, i16 %cnt, i16 16
    407   ret i16 %cond
    408 }
    409 ; CHECK-LABEL: test16_cttz
    410 ; CHECK-NOT: movw
    411 ; CHECK: tzcnt
    412 ; CHECK-NEXT: ret
    413 
    414 
    415 define i32 @test17_cttz(i32* %ptr) {
    416   %v = load i32* %ptr
    417   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    418   %tobool = icmp eq i32 0, %v
    419   %cond = select i1 %tobool, i32 %cnt, i32 32
    420   ret i32 %cond
    421 }
    422 ; CHECK-LABEL: test17_cttz
    423 ; CHECK-NOT: movd
    424 ; CHECK: tzcnt
    425 ; CHECK-NEXT: ret
    426 
    427 
    428 define i64 @test18_cttz(i64* %ptr) {
    429   %v = load i64* %ptr
    430   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    431   %tobool = icmp eq i64 0, %v
    432   %cond = select i1 %tobool, i64 %cnt, i64 64
    433   ret i64 %cond
    434 }
    435 ; CHECK-LABEL: test18_cttz
    436 ; CHECK-NOT: movq
    437 ; CHECK: tzcnt
    438 ; CHECK-NEXT: ret
    439 
    440 
    441 declare i64 @llvm.cttz.i64(i64, i1)
    442 declare i32 @llvm.cttz.i32(i32, i1)
    443 declare i16 @llvm.cttz.i16(i16, i1)
    444 declare i64 @llvm.ctlz.i64(i64, i1)
    445 declare i32 @llvm.ctlz.i32(i32, i1)
    446 declare i16 @llvm.ctlz.i16(i16, i1)
    447 
    448