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 @test10_ctlz(i16* %ptr) {
     76   %v = load i16, i16* %ptr
     77   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
     78   %tobool = icmp eq i16 %v, 0
     79   %cond = select i1 %tobool, i16 16, i16 %cnt
     80   ret i16 %cond
     81 }
     82 ; CHECK-LABEL: test10_ctlz
     83 ; CHECK-NOT: movw
     84 ; CHECK: lzcnt
     85 ; CHECK-NEXT: ret
     86 
     87 
     88 define i32 @test11_ctlz(i32* %ptr) {
     89   %v = load i32, i32* %ptr
     90   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
     91   %tobool = icmp eq i32 %v, 0
     92   %cond = select i1 %tobool, i32 32, i32 %cnt
     93   ret i32 %cond
     94 }
     95 ; CHECK-LABEL: test11_ctlz
     96 ; CHECK-NOT: movd
     97 ; CHECK: lzcnt
     98 ; CHECK-NEXT: ret
     99 
    100 
    101 define i64 @test12_ctlz(i64* %ptr) {
    102   %v = load i64, i64* %ptr
    103   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    104   %tobool = icmp eq i64 %v, 0
    105   %cond = select i1 %tobool, i64 64, i64 %cnt
    106   ret i64 %cond
    107 }
    108 ; CHECK-LABEL: test12_ctlz
    109 ; CHECK-NOT: movq
    110 ; CHECK: lzcnt
    111 ; CHECK-NEXT: ret
    112 
    113 
    114 define i16 @test13_ctlz(i16* %ptr) {
    115   %v = load i16, i16* %ptr
    116   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
    117   %tobool = icmp eq i16 0, %v
    118   %cond = select i1 %tobool, i16 16, i16 %cnt
    119   ret i16 %cond
    120 }
    121 ; CHECK-LABEL: test13_ctlz
    122 ; CHECK-NOT: movw
    123 ; CHECK: lzcnt
    124 ; CHECK-NEXT: ret
    125 
    126 
    127 define i32 @test14_ctlz(i32* %ptr) {
    128   %v = load i32, i32* %ptr
    129   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
    130   %tobool = icmp eq i32 0, %v
    131   %cond = select i1 %tobool, i32 32, i32 %cnt
    132   ret i32 %cond
    133 }
    134 ; CHECK-LABEL: test14_ctlz
    135 ; CHECK-NOT: movd
    136 ; CHECK: lzcnt
    137 ; CHECK-NEXT: ret
    138 
    139 
    140 define i64 @test15_ctlz(i64* %ptr) {
    141   %v = load i64, i64* %ptr
    142   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    143   %tobool = icmp eq i64 0, %v
    144   %cond = select i1 %tobool, i64 64, i64 %cnt
    145   ret i64 %cond
    146 }
    147 ; CHECK-LABEL: test15_ctlz
    148 ; CHECK-NOT: movq
    149 ; CHECK: lzcnt
    150 ; CHECK-NEXT: ret
    151 
    152 
    153 define i16 @test1_cttz(i16 %v) {
    154   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    155   %tobool = icmp eq i16 %v, 0
    156   %cond = select i1 %tobool, i16 16, i16 %cnt
    157   ret i16 %cond
    158 }
    159 ; CHECK-LABEL: test1_cttz
    160 ; CHECK: tzcnt
    161 ; CHECK-NEXT: ret
    162 
    163 
    164 define i32 @test2_cttz(i32 %v) {
    165   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    166   %tobool = icmp eq i32 %v, 0
    167   %cond = select i1 %tobool, i32 32, i32 %cnt
    168   ret i32 %cond
    169 }
    170 ; CHECK-LABEL: test2_cttz
    171 ; CHECK: tzcnt
    172 ; CHECK-NEXT: ret
    173 
    174 
    175 define i64 @test3_cttz(i64 %v) {
    176   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    177   %tobool = icmp eq i64 %v, 0
    178   %cond = select i1 %tobool, i64 64, i64 %cnt
    179   ret i64 %cond
    180 }
    181 ; CHECK-LABEL: test3_cttz
    182 ; CHECK: tzcnt
    183 ; CHECK-NEXT: ret
    184 
    185 
    186 define i16 @test4_cttz(i16 %v) {
    187   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    188   %tobool = icmp eq i16 0, %v
    189   %cond = select i1 %tobool, i16 16, i16 %cnt
    190   ret i16 %cond
    191 }
    192 ; CHECK-LABEL: test4_cttz
    193 ; CHECK: tzcnt
    194 ; CHECK-NEXT: ret
    195 
    196 
    197 define i32 @test5_cttz(i32 %v) {
    198   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    199   %tobool = icmp eq i32 0, %v
    200   %cond = select i1 %tobool, i32 32, i32 %cnt
    201   ret i32 %cond
    202 }
    203 ; CHECK-LABEL: test5_cttz
    204 ; CHECK: tzcnt
    205 ; CHECK-NEXT: ret
    206 
    207 
    208 define i64 @test6_cttz(i64 %v) {
    209   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    210   %tobool = icmp eq i64 0, %v
    211   %cond = select i1 %tobool, i64 64, i64 %cnt
    212   ret i64 %cond
    213 }
    214 ; CHECK-LABEL: test6_cttz
    215 ; CHECK: tzcnt
    216 ; CHECK-NEXT: ret
    217 
    218 
    219 define i16 @test10_cttz(i16* %ptr) {
    220   %v = load i16, i16* %ptr
    221   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    222   %tobool = icmp eq i16 %v, 0
    223   %cond = select i1 %tobool, i16 16, i16 %cnt
    224   ret i16 %cond
    225 }
    226 ; CHECK-LABEL: test10_cttz
    227 ; CHECK-NOT: movw
    228 ; CHECK: tzcnt
    229 ; CHECK-NEXT: ret
    230 
    231 
    232 define i32 @test11_cttz(i32* %ptr) {
    233   %v = load i32, i32* %ptr
    234   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    235   %tobool = icmp eq i32 %v, 0
    236   %cond = select i1 %tobool, i32 32, i32 %cnt
    237   ret i32 %cond
    238 }
    239 ; CHECK-LABEL: test11_cttz
    240 ; CHECK-NOT: movd
    241 ; CHECK: tzcnt
    242 ; CHECK-NEXT: ret
    243 
    244 
    245 define i64 @test12_cttz(i64* %ptr) {
    246   %v = load i64, i64* %ptr
    247   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    248   %tobool = icmp eq i64 %v, 0
    249   %cond = select i1 %tobool, i64 64, i64 %cnt
    250   ret i64 %cond
    251 }
    252 ; CHECK-LABEL: test12_cttz
    253 ; CHECK-NOT: movq
    254 ; CHECK: tzcnt
    255 ; CHECK-NEXT: ret
    256 
    257 
    258 define i16 @test13_cttz(i16* %ptr) {
    259   %v = load i16, i16* %ptr
    260   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    261   %tobool = icmp eq i16 0, %v
    262   %cond = select i1 %tobool, i16 16, i16 %cnt
    263   ret i16 %cond
    264 }
    265 ; CHECK-LABEL: test13_cttz
    266 ; CHECK-NOT: movw
    267 ; CHECK: tzcnt
    268 ; CHECK-NEXT: ret
    269 
    270 
    271 define i32 @test14_cttz(i32* %ptr) {
    272   %v = load i32, i32* %ptr
    273   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    274   %tobool = icmp eq i32 0, %v
    275   %cond = select i1 %tobool, i32 32, i32 %cnt
    276   ret i32 %cond
    277 }
    278 ; CHECK-LABEL: test14_cttz
    279 ; CHECK-NOT: movd
    280 ; CHECK: tzcnt
    281 ; CHECK-NEXT: ret
    282 
    283 
    284 define i64 @test15_cttz(i64* %ptr) {
    285   %v = load i64, i64* %ptr
    286   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    287   %tobool = icmp eq i64 0, %v
    288   %cond = select i1 %tobool, i64 64, i64 %cnt
    289   ret i64 %cond
    290 }
    291 ; CHECK-LABEL: test15_cttz
    292 ; CHECK-NOT: movq
    293 ; CHECK: tzcnt
    294 ; CHECK-NEXT: ret
    295 
    296 
    297 define i16 @test4b_ctlz(i16 %v) {
    298   %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)
    299   %tobool = icmp ne i16 %v, 0
    300   %cond = select i1 %tobool, i16 %cnt, i16 16
    301   ret i16 %cond
    302 }
    303 ; CHECK-LABEL: test4b_ctlz
    304 ; CHECK: lzcnt
    305 ; CHECK-NEXT: ret
    306 
    307 
    308 define i32 @test5b_ctlz(i32 %v) {
    309   %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
    310   %tobool = icmp ne i32 %v, 0
    311   %cond = select i1 %tobool, i32 %cnt, i32 32
    312   ret i32 %cond
    313 }
    314 ; CHECK-LABEL: test5b_ctlz
    315 ; CHECK: lzcnt
    316 ; CHECK-NEXT: ret
    317 
    318 
    319 define i64 @test6b_ctlz(i64 %v) {
    320   %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
    321   %tobool = icmp ne i64 %v, 0
    322   %cond = select i1 %tobool, i64 %cnt, i64 64
    323   ret i64 %cond
    324 }
    325 ; CHECK-LABEL: test6b_ctlz
    326 ; CHECK: lzcnt
    327 ; CHECK-NEXT: ret
    328 
    329 
    330 define i16 @test4b_cttz(i16 %v) {
    331   %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)
    332   %tobool = icmp ne i16 %v, 0
    333   %cond = select i1 %tobool, i16 %cnt, i16 16
    334   ret i16 %cond
    335 }
    336 ; CHECK-LABEL: test4b_cttz
    337 ; CHECK: tzcnt
    338 ; CHECK-NEXT: ret
    339 
    340 
    341 define i32 @test5b_cttz(i32 %v) {
    342   %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
    343   %tobool = icmp ne i32 %v, 0
    344   %cond = select i1 %tobool, i32 %cnt, i32 32
    345   ret i32 %cond
    346 }
    347 ; CHECK-LABEL: test5b_cttz
    348 ; CHECK: tzcnt
    349 ; CHECK-NEXT: ret
    350 
    351 
    352 define i64 @test6b_cttz(i64 %v) {
    353   %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
    354   %tobool = icmp ne i64 %v, 0
    355   %cond = select i1 %tobool, i64 %cnt, i64 64
    356   ret i64 %cond
    357 }
    358 ; CHECK-LABEL: test6b_cttz
    359 ; CHECK: tzcnt
    360 ; CHECK-NEXT: ret
    361 
    362 
    363 declare i64 @llvm.cttz.i64(i64, i1)
    364 declare i32 @llvm.cttz.i32(i32, i1)
    365 declare i16 @llvm.cttz.i16(i16, i1)
    366 declare i64 @llvm.ctlz.i64(i64, i1)
    367 declare i32 @llvm.ctlz.i32(i32, i1)
    368 declare i16 @llvm.ctlz.i16(i16, i1)
    369 
    370