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