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