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