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