Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
      3 ; PR3253
      4 
      5 ; The register+memory form of the BT instruction should be usable on
      6 ; pentium4, however it is currently disabled due to the register+memory
      7 ; form having different semantics than the register+register form.
      8 
      9 ; Test these patterns:
     10 ;    (X & (1 << N))  != 0  -->  BT(X, N).
     11 ;    ((X >>u N) & 1) != 0  -->  BT(X, N).
     12 ; as well as several variations:
     13 ;    - The second form can use an arithmetic shift.
     14 ;    - Either form can use == instead of !=.
     15 ;    - Either form can compare with an operand of the &
     16 ;      instead of with 0.
     17 ;    - The comparison can be commuted (only cases where neither
     18 ;      operand is constant are included).
     19 ;    - The and can be commuted.
     20 
     21 define void @test2(i32 %x, i32 %n) nounwind {
     22 ; CHECK-LABEL: test2:
     23 ; CHECK:       # BB#0: # %entry
     24 ; CHECK-NEXT:    btl %esi, %edi
     25 ; CHECK-NEXT:    jb .LBB0_2
     26 ;
     27 entry:
     28   %tmp29 = lshr i32 %x, %n
     29   %tmp3 = and i32 %tmp29, 1
     30   %tmp4 = icmp eq i32 %tmp3, 0
     31   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
     32 
     33 bb:
     34   call void @foo()
     35   ret void
     36 
     37 UnifiedReturnBlock:
     38   ret void
     39 }
     40 
     41 define void @test2b(i32 %x, i32 %n) nounwind {
     42 ; CHECK-LABEL: test2b:
     43 ; CHECK:       # BB#0: # %entry
     44 ; CHECK-NEXT:    btl %esi, %edi
     45 ; CHECK-NEXT:    jb .LBB1_2
     46 ;
     47 entry:
     48   %tmp29 = lshr i32 %x, %n
     49   %tmp3 = and i32 1, %tmp29
     50   %tmp4 = icmp eq i32 %tmp3, 0
     51   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
     52 
     53 bb:
     54   call void @foo()
     55   ret void
     56 
     57 UnifiedReturnBlock:
     58   ret void
     59 }
     60 
     61 define void @atest2(i32 %x, i32 %n) nounwind {
     62 ; CHECK-LABEL: atest2:
     63 ; CHECK:       # BB#0: # %entry
     64 ; CHECK-NEXT:    btl %esi, %edi
     65 ; CHECK-NEXT:    jb .LBB2_2
     66 ;
     67 entry:
     68   %tmp29 = ashr i32 %x, %n
     69   %tmp3 = and i32 %tmp29, 1
     70   %tmp4 = icmp eq i32 %tmp3, 0
     71   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
     72 
     73 bb:
     74   call void @foo()
     75   ret void
     76 
     77 UnifiedReturnBlock:
     78   ret void
     79 }
     80 
     81 define void @atest2b(i32 %x, i32 %n) nounwind {
     82 ; CHECK-LABEL: atest2b:
     83 ; CHECK:       # BB#0: # %entry
     84 ; CHECK-NEXT:    btl %esi, %edi
     85 ; CHECK-NEXT:    jb .LBB3_2
     86 ;
     87 entry:
     88   %tmp29 = ashr i32 %x, %n
     89   %tmp3 = and i32 1, %tmp29
     90   %tmp4 = icmp eq i32 %tmp3, 0
     91   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
     92 
     93 bb:
     94   call void @foo()
     95   ret void
     96 
     97 UnifiedReturnBlock:
     98   ret void
     99 }
    100 
    101 define void @test3(i32 %x, i32 %n) nounwind {
    102 ; CHECK-LABEL: test3:
    103 ; CHECK:       # BB#0: # %entry
    104 ; CHECK-NEXT:    btl %esi, %edi
    105 ; CHECK-NEXT:    jb .LBB4_2
    106 ;
    107 entry:
    108   %tmp29 = shl i32 1, %n
    109   %tmp3 = and i32 %tmp29, %x
    110   %tmp4 = icmp eq i32 %tmp3, 0
    111   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    112 
    113 bb:
    114   call void @foo()
    115   ret void
    116 
    117 UnifiedReturnBlock:
    118   ret void
    119 }
    120 
    121 define void @test3b(i32 %x, i32 %n) nounwind {
    122 ; CHECK-LABEL: test3b:
    123 ; CHECK:       # BB#0: # %entry
    124 ; CHECK-NEXT:    btl %esi, %edi
    125 ; CHECK-NEXT:    jb .LBB5_2
    126 ;
    127 entry:
    128   %tmp29 = shl i32 1, %n
    129   %tmp3 = and i32 %x, %tmp29
    130   %tmp4 = icmp eq i32 %tmp3, 0
    131   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    132 
    133 bb:
    134   call void @foo()
    135   ret void
    136 
    137 UnifiedReturnBlock:
    138   ret void
    139 }
    140 
    141 define void @testne2(i32 %x, i32 %n) nounwind {
    142 ; CHECK-LABEL: testne2:
    143 ; CHECK:       # BB#0: # %entry
    144 ; CHECK-NEXT:    btl %esi, %edi
    145 ; CHECK-NEXT:    jae .LBB6_2
    146 ;
    147 entry:
    148   %tmp29 = lshr i32 %x, %n
    149   %tmp3 = and i32 %tmp29, 1
    150   %tmp4 = icmp ne i32 %tmp3, 0
    151   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    152 
    153 bb:
    154   call void @foo()
    155   ret void
    156 
    157 UnifiedReturnBlock:
    158   ret void
    159 }
    160 
    161 define void @testne2b(i32 %x, i32 %n) nounwind {
    162 ; CHECK-LABEL: testne2b:
    163 ; CHECK:       # BB#0: # %entry
    164 ; CHECK-NEXT:    btl %esi, %edi
    165 ; CHECK-NEXT:    jae .LBB7_2
    166 ;
    167 entry:
    168   %tmp29 = lshr i32 %x, %n
    169   %tmp3 = and i32 1, %tmp29
    170   %tmp4 = icmp ne i32 %tmp3, 0
    171   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    172 
    173 bb:
    174   call void @foo()
    175   ret void
    176 
    177 UnifiedReturnBlock:
    178   ret void
    179 }
    180 
    181 define void @atestne2(i32 %x, i32 %n) nounwind {
    182 ; CHECK-LABEL: atestne2:
    183 ; CHECK:       # BB#0: # %entry
    184 ; CHECK-NEXT:    btl %esi, %edi
    185 ; CHECK-NEXT:    jae .LBB8_2
    186 ;
    187 entry:
    188   %tmp29 = ashr i32 %x, %n
    189   %tmp3 = and i32 %tmp29, 1
    190   %tmp4 = icmp ne i32 %tmp3, 0
    191   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    192 
    193 bb:
    194   call void @foo()
    195   ret void
    196 
    197 UnifiedReturnBlock:
    198   ret void
    199 }
    200 
    201 define void @atestne2b(i32 %x, i32 %n) nounwind {
    202 ; CHECK-LABEL: atestne2b:
    203 ; CHECK:       # BB#0: # %entry
    204 ; CHECK-NEXT:    btl %esi, %edi
    205 ; CHECK-NEXT:    jae .LBB9_2
    206 ;
    207 entry:
    208   %tmp29 = ashr i32 %x, %n
    209   %tmp3 = and i32 1, %tmp29
    210   %tmp4 = icmp ne i32 %tmp3, 0
    211   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    212 
    213 bb:
    214   call void @foo()
    215   ret void
    216 
    217 UnifiedReturnBlock:
    218   ret void
    219 }
    220 
    221 define void @testne3(i32 %x, i32 %n) nounwind {
    222 ; CHECK-LABEL: testne3:
    223 ; CHECK:       # BB#0: # %entry
    224 ; CHECK-NEXT:    btl %esi, %edi
    225 ; CHECK-NEXT:    jae .LBB10_2
    226 ;
    227 entry:
    228   %tmp29 = shl i32 1, %n
    229   %tmp3 = and i32 %tmp29, %x
    230   %tmp4 = icmp ne i32 %tmp3, 0
    231   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    232 
    233 bb:
    234   call void @foo()
    235   ret void
    236 
    237 UnifiedReturnBlock:
    238   ret void
    239 }
    240 
    241 define void @testne3b(i32 %x, i32 %n) nounwind {
    242 ; CHECK-LABEL: testne3b:
    243 ; CHECK:       # BB#0: # %entry
    244 ; CHECK-NEXT:    btl %esi, %edi
    245 ; CHECK-NEXT:    jae .LBB11_2
    246 ;
    247 entry:
    248   %tmp29 = shl i32 1, %n
    249   %tmp3 = and i32 %x, %tmp29
    250   %tmp4 = icmp ne i32 %tmp3, 0
    251   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    252 
    253 bb:
    254   call void @foo()
    255   ret void
    256 
    257 UnifiedReturnBlock:
    258   ret void
    259 }
    260 
    261 define void @query2(i32 %x, i32 %n) nounwind {
    262 ; CHECK-LABEL: query2:
    263 ; CHECK:       # BB#0: # %entry
    264 ; CHECK-NEXT:    btl %esi, %edi
    265 ; CHECK-NEXT:    jae .LBB12_2
    266 ;
    267 entry:
    268   %tmp29 = lshr i32 %x, %n
    269   %tmp3 = and i32 %tmp29, 1
    270   %tmp4 = icmp eq i32 %tmp3, 1
    271   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    272 
    273 bb:
    274   call void @foo()
    275   ret void
    276 
    277 UnifiedReturnBlock:
    278   ret void
    279 }
    280 
    281 define void @query2b(i32 %x, i32 %n) nounwind {
    282 ; CHECK-LABEL: query2b:
    283 ; CHECK:       # BB#0: # %entry
    284 ; CHECK-NEXT:    btl %esi, %edi
    285 ; CHECK-NEXT:    jae .LBB13_2
    286 ;
    287 entry:
    288   %tmp29 = lshr i32 %x, %n
    289   %tmp3 = and i32 1, %tmp29
    290   %tmp4 = icmp eq i32 %tmp3, 1
    291   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    292 
    293 bb:
    294   call void @foo()
    295   ret void
    296 
    297 UnifiedReturnBlock:
    298   ret void
    299 }
    300 
    301 define void @aquery2(i32 %x, i32 %n) nounwind {
    302 ; CHECK-LABEL: aquery2:
    303 ; CHECK:       # BB#0: # %entry
    304 ; CHECK-NEXT:    btl %esi, %edi
    305 ; CHECK-NEXT:    jae .LBB14_2
    306 ;
    307 entry:
    308   %tmp29 = ashr i32 %x, %n
    309   %tmp3 = and i32 %tmp29, 1
    310   %tmp4 = icmp eq i32 %tmp3, 1
    311   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    312 
    313 bb:
    314   call void @foo()
    315   ret void
    316 
    317 UnifiedReturnBlock:
    318   ret void
    319 }
    320 
    321 define void @aquery2b(i32 %x, i32 %n) nounwind {
    322 ; CHECK-LABEL: aquery2b:
    323 ; CHECK:       # BB#0: # %entry
    324 ; CHECK-NEXT:    btl %esi, %edi
    325 ; CHECK-NEXT:    jae .LBB15_2
    326 ;
    327 entry:
    328   %tmp29 = ashr i32 %x, %n
    329   %tmp3 = and i32 1, %tmp29
    330   %tmp4 = icmp eq i32 %tmp3, 1
    331   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    332 
    333 bb:
    334   call void @foo()
    335   ret void
    336 
    337 UnifiedReturnBlock:
    338   ret void
    339 }
    340 
    341 define void @query3(i32 %x, i32 %n) nounwind {
    342 ; CHECK-LABEL: query3:
    343 ; CHECK:       # BB#0: # %entry
    344 ; CHECK-NEXT:    btl %esi, %edi
    345 ; CHECK-NEXT:    jae .LBB16_2
    346 ;
    347 entry:
    348   %tmp29 = shl i32 1, %n
    349   %tmp3 = and i32 %tmp29, %x
    350   %tmp4 = icmp eq i32 %tmp3, %tmp29
    351   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    352 
    353 bb:
    354   call void @foo()
    355   ret void
    356 
    357 UnifiedReturnBlock:
    358   ret void
    359 }
    360 
    361 define void @query3b(i32 %x, i32 %n) nounwind {
    362 ; CHECK-LABEL: query3b:
    363 ; CHECK:       # BB#0: # %entry
    364 ; CHECK-NEXT:    btl %esi, %edi
    365 ; CHECK-NEXT:    jae .LBB17_2
    366 ;
    367 entry:
    368   %tmp29 = shl i32 1, %n
    369   %tmp3 = and i32 %x, %tmp29
    370   %tmp4 = icmp eq i32 %tmp3, %tmp29
    371   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    372 
    373 bb:
    374   call void @foo()
    375   ret void
    376 
    377 UnifiedReturnBlock:
    378   ret void
    379 }
    380 
    381 define void @query3x(i32 %x, i32 %n) nounwind {
    382 ; CHECK-LABEL: query3x:
    383 ; CHECK:       # BB#0: # %entry
    384 ; CHECK-NEXT:    btl %esi, %edi
    385 ; CHECK-NEXT:    jae .LBB18_2
    386 ;
    387 entry:
    388   %tmp29 = shl i32 1, %n
    389   %tmp3 = and i32 %tmp29, %x
    390   %tmp4 = icmp eq i32 %tmp29, %tmp3
    391   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    392 
    393 bb:
    394   call void @foo()
    395   ret void
    396 
    397 UnifiedReturnBlock:
    398   ret void
    399 }
    400 
    401 define void @query3bx(i32 %x, i32 %n) nounwind {
    402 ; CHECK-LABEL: query3bx:
    403 ; CHECK:       # BB#0: # %entry
    404 ; CHECK-NEXT:    btl %esi, %edi
    405 ; CHECK-NEXT:    jae .LBB19_2
    406 ;
    407 entry:
    408   %tmp29 = shl i32 1, %n
    409   %tmp3 = and i32 %x, %tmp29
    410   %tmp4 = icmp eq i32 %tmp29, %tmp3
    411   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    412 
    413 bb:
    414   call void @foo()
    415   ret void
    416 
    417 UnifiedReturnBlock:
    418   ret void
    419 }
    420 
    421 define void @queryne2(i32 %x, i32 %n) nounwind {
    422 ; CHECK-LABEL: queryne2:
    423 ; CHECK:       # BB#0: # %entry
    424 ; CHECK-NEXT:    btl %esi, %edi
    425 ; CHECK-NEXT:    jb .LBB20_2
    426 ;
    427 entry:
    428   %tmp29 = lshr i32 %x, %n
    429   %tmp3 = and i32 %tmp29, 1
    430   %tmp4 = icmp ne i32 %tmp3, 1
    431   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    432 
    433 bb:
    434   call void @foo()
    435   ret void
    436 
    437 UnifiedReturnBlock:
    438   ret void
    439 }
    440 
    441 define void @queryne2b(i32 %x, i32 %n) nounwind {
    442 ; CHECK-LABEL: queryne2b:
    443 ; CHECK:       # BB#0: # %entry
    444 ; CHECK-NEXT:    btl %esi, %edi
    445 ; CHECK-NEXT:    jb .LBB21_2
    446 ;
    447 entry:
    448   %tmp29 = lshr i32 %x, %n
    449   %tmp3 = and i32 1, %tmp29
    450   %tmp4 = icmp ne i32 %tmp3, 1
    451   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    452 
    453 bb:
    454   call void @foo()
    455   ret void
    456 
    457 UnifiedReturnBlock:
    458   ret void
    459 }
    460 
    461 define void @aqueryne2(i32 %x, i32 %n) nounwind {
    462 ; CHECK-LABEL: aqueryne2:
    463 ; CHECK:       # BB#0: # %entry
    464 ; CHECK-NEXT:    btl %esi, %edi
    465 ; CHECK-NEXT:    jb .LBB22_2
    466 ;
    467 entry:
    468   %tmp29 = ashr i32 %x, %n
    469   %tmp3 = and i32 %tmp29, 1
    470   %tmp4 = icmp ne i32 %tmp3, 1
    471   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    472 
    473 bb:
    474   call void @foo()
    475   ret void
    476 
    477 UnifiedReturnBlock:
    478   ret void
    479 }
    480 
    481 define void @aqueryne2b(i32 %x, i32 %n) nounwind {
    482 ; CHECK-LABEL: aqueryne2b:
    483 ; CHECK:       # BB#0: # %entry
    484 ; CHECK-NEXT:    btl %esi, %edi
    485 ; CHECK-NEXT:    jb .LBB23_2
    486 ;
    487 entry:
    488   %tmp29 = ashr i32 %x, %n
    489   %tmp3 = and i32 1, %tmp29
    490   %tmp4 = icmp ne i32 %tmp3, 1
    491   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    492 
    493 bb:
    494   call void @foo()
    495   ret void
    496 
    497 UnifiedReturnBlock:
    498   ret void
    499 }
    500 
    501 define void @queryne3(i32 %x, i32 %n) nounwind {
    502 ; CHECK-LABEL: queryne3:
    503 ; CHECK:       # BB#0: # %entry
    504 ; CHECK-NEXT:    btl %esi, %edi
    505 ; CHECK-NEXT:    jb .LBB24_2
    506 ;
    507 entry:
    508   %tmp29 = shl i32 1, %n
    509   %tmp3 = and i32 %tmp29, %x
    510   %tmp4 = icmp ne i32 %tmp3, %tmp29
    511   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    512 
    513 bb:
    514   call void @foo()
    515   ret void
    516 
    517 UnifiedReturnBlock:
    518   ret void
    519 }
    520 
    521 define void @queryne3b(i32 %x, i32 %n) nounwind {
    522 ; CHECK-LABEL: queryne3b:
    523 ; CHECK:       # BB#0: # %entry
    524 ; CHECK-NEXT:    btl %esi, %edi
    525 ; CHECK-NEXT:    jb .LBB25_2
    526 ;
    527 entry:
    528   %tmp29 = shl i32 1, %n
    529   %tmp3 = and i32 %x, %tmp29
    530   %tmp4 = icmp ne i32 %tmp3, %tmp29
    531   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    532 
    533 bb:
    534   call void @foo()
    535   ret void
    536 
    537 UnifiedReturnBlock:
    538   ret void
    539 }
    540 
    541 define void @queryne3x(i32 %x, i32 %n) nounwind {
    542 ; CHECK-LABEL: queryne3x:
    543 ; CHECK:       # BB#0: # %entry
    544 ; CHECK-NEXT:    btl %esi, %edi
    545 ; CHECK-NEXT:    jb .LBB26_2
    546 ;
    547 entry:
    548   %tmp29 = shl i32 1, %n
    549   %tmp3 = and i32 %tmp29, %x
    550   %tmp4 = icmp ne i32 %tmp29, %tmp3
    551   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    552 
    553 bb:
    554   call void @foo()
    555   ret void
    556 
    557 UnifiedReturnBlock:
    558   ret void
    559 }
    560 
    561 define void @queryne3bx(i32 %x, i32 %n) nounwind {
    562 ; CHECK-LABEL: queryne3bx:
    563 ; CHECK:       # BB#0: # %entry
    564 ; CHECK-NEXT:    btl %esi, %edi
    565 ; CHECK-NEXT:    jb .LBB27_2
    566 ;
    567 entry:
    568   %tmp29 = shl i32 1, %n
    569   %tmp3 = and i32 %x, %tmp29
    570   %tmp4 = icmp ne i32 %tmp29, %tmp3
    571   br i1 %tmp4, label %bb, label %UnifiedReturnBlock
    572 
    573 bb:
    574   call void @foo()
    575   ret void
    576 
    577 UnifiedReturnBlock:
    578   ret void
    579 }
    580 
    581 declare void @foo()
    582 
    583 define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind {
    584 ; CHECK-LABEL: invert:
    585 ; CHECK:       # BB#0:
    586 ; CHECK-NEXT:    notl %edi
    587 ; CHECK-NEXT:    btl %esi, %edi
    588 ; CHECK-NEXT:    setb %al
    589 ; CHECK-NEXT:    retq
    590 ;
    591   %neg = xor i32 %flags, -1
    592   %shl = shl i32 1, %flag
    593   %and = and i32 %shl, %neg
    594   %tobool = icmp ne i32 %and, 0
    595   ret i1 %tobool
    596 }
    597 
    598