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 21define 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; 27entry: 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 33bb: 34 call void @foo() 35 ret void 36 37UnifiedReturnBlock: 38 ret void 39} 40 41define 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; 47entry: 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 53bb: 54 call void @foo() 55 ret void 56 57UnifiedReturnBlock: 58 ret void 59} 60 61define 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; 67entry: 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 73bb: 74 call void @foo() 75 ret void 76 77UnifiedReturnBlock: 78 ret void 79} 80 81define 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; 87entry: 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 93bb: 94 call void @foo() 95 ret void 96 97UnifiedReturnBlock: 98 ret void 99} 100 101define 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; 107entry: 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 113bb: 114 call void @foo() 115 ret void 116 117UnifiedReturnBlock: 118 ret void 119} 120 121define 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; 127entry: 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 133bb: 134 call void @foo() 135 ret void 136 137UnifiedReturnBlock: 138 ret void 139} 140 141define 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; 147entry: 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 153bb: 154 call void @foo() 155 ret void 156 157UnifiedReturnBlock: 158 ret void 159} 160 161define 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; 167entry: 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 173bb: 174 call void @foo() 175 ret void 176 177UnifiedReturnBlock: 178 ret void 179} 180 181define 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; 187entry: 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 193bb: 194 call void @foo() 195 ret void 196 197UnifiedReturnBlock: 198 ret void 199} 200 201define 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; 207entry: 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 213bb: 214 call void @foo() 215 ret void 216 217UnifiedReturnBlock: 218 ret void 219} 220 221define 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; 227entry: 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 233bb: 234 call void @foo() 235 ret void 236 237UnifiedReturnBlock: 238 ret void 239} 240 241define 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; 247entry: 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 253bb: 254 call void @foo() 255 ret void 256 257UnifiedReturnBlock: 258 ret void 259} 260 261define 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; 267entry: 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 273bb: 274 call void @foo() 275 ret void 276 277UnifiedReturnBlock: 278 ret void 279} 280 281define 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; 287entry: 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 293bb: 294 call void @foo() 295 ret void 296 297UnifiedReturnBlock: 298 ret void 299} 300 301define 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; 307entry: 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 313bb: 314 call void @foo() 315 ret void 316 317UnifiedReturnBlock: 318 ret void 319} 320 321define 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; 327entry: 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 333bb: 334 call void @foo() 335 ret void 336 337UnifiedReturnBlock: 338 ret void 339} 340 341define 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; 347entry: 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 353bb: 354 call void @foo() 355 ret void 356 357UnifiedReturnBlock: 358 ret void 359} 360 361define 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; 367entry: 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 373bb: 374 call void @foo() 375 ret void 376 377UnifiedReturnBlock: 378 ret void 379} 380 381define 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; 387entry: 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 393bb: 394 call void @foo() 395 ret void 396 397UnifiedReturnBlock: 398 ret void 399} 400 401define 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; 407entry: 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 413bb: 414 call void @foo() 415 ret void 416 417UnifiedReturnBlock: 418 ret void 419} 420 421define 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; 427entry: 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 433bb: 434 call void @foo() 435 ret void 436 437UnifiedReturnBlock: 438 ret void 439} 440 441define 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; 447entry: 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 453bb: 454 call void @foo() 455 ret void 456 457UnifiedReturnBlock: 458 ret void 459} 460 461define 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; 467entry: 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 473bb: 474 call void @foo() 475 ret void 476 477UnifiedReturnBlock: 478 ret void 479} 480 481define 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; 487entry: 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 493bb: 494 call void @foo() 495 ret void 496 497UnifiedReturnBlock: 498 ret void 499} 500 501define 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; 507entry: 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 513bb: 514 call void @foo() 515 ret void 516 517UnifiedReturnBlock: 518 ret void 519} 520 521define 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; 527entry: 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 533bb: 534 call void @foo() 535 ret void 536 537UnifiedReturnBlock: 538 ret void 539} 540 541define 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; 547entry: 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 553bb: 554 call void @foo() 555 ret void 556 557UnifiedReturnBlock: 558 ret void 559} 560 561define 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; 567entry: 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 573bb: 574 call void @foo() 575 ret void 576 577UnifiedReturnBlock: 578 ret void 579} 580 581declare void @foo() 582 583define 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