1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=X64 5 6; PR3253 7 8; The register+memory form of the BT instruction should be usable on 9; pentium4, however it is currently disabled due to the register+memory 10; form having different semantics than the register+register form. 11 12; Test these patterns: 13; (X & (1 << N)) != 0 --> BT(X, N). 14; ((X >>u N) & 1) != 0 --> BT(X, N). 15; as well as several variations: 16; - The second form can use an arithmetic shift. 17; - Either form can use == instead of !=. 18; - Either form can compare with an operand of the & 19; instead of with 0. 20; - The comparison can be commuted (only cases where neither 21; operand is constant are included). 22; - The and can be commuted. 23 24define void @test2(i32 %x, i32 %n) nounwind { 25; X86-LABEL: test2: 26; X86: # %bb.0: # %entry 27; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 28; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 29; X86-NEXT: btl %ecx, %eax 30; X86-NEXT: jb .LBB0_2 31; X86-NEXT: # %bb.1: # %bb 32; X86-NEXT: calll foo 33; X86-NEXT: .LBB0_2: # %UnifiedReturnBlock 34; X86-NEXT: retl 35; 36; X64-LABEL: test2: 37; X64: # %bb.0: # %entry 38; X64-NEXT: btl %esi, %edi 39; X64-NEXT: jb .LBB0_2 40; X64-NEXT: # %bb.1: # %bb 41; X64-NEXT: pushq %rax 42; X64-NEXT: callq foo 43; X64-NEXT: popq %rax 44; X64-NEXT: .LBB0_2: # %UnifiedReturnBlock 45; X64-NEXT: retq 46entry: 47 %tmp29 = lshr i32 %x, %n 48 %tmp3 = and i32 %tmp29, 1 49 %tmp4 = icmp eq i32 %tmp3, 0 50 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 51 52bb: 53 call void @foo() 54 ret void 55 56UnifiedReturnBlock: 57 ret void 58} 59 60define void @test2b(i32 %x, i32 %n) nounwind { 61; X86-LABEL: test2b: 62; X86: # %bb.0: # %entry 63; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 64; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 65; X86-NEXT: btl %ecx, %eax 66; X86-NEXT: jae .LBB1_1 67; X86-NEXT: # %bb.2: # %UnifiedReturnBlock 68; X86-NEXT: retl 69; X86-NEXT: .LBB1_1: # %bb 70; X86-NEXT: calll foo 71; X86-NEXT: retl 72; 73; X64-LABEL: test2b: 74; X64: # %bb.0: # %entry 75; X64-NEXT: btl %esi, %edi 76; X64-NEXT: jae .LBB1_1 77; X64-NEXT: # %bb.2: # %UnifiedReturnBlock 78; X64-NEXT: retq 79; X64-NEXT: .LBB1_1: # %bb 80; X64-NEXT: pushq %rax 81; X64-NEXT: callq foo 82; X64-NEXT: popq %rax 83; X64-NEXT: retq 84entry: 85 %tmp29 = lshr i32 %x, %n 86 %tmp3 = and i32 1, %tmp29 87 %tmp4 = icmp eq i32 %tmp3, 0 88 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 89 90bb: 91 call void @foo() 92 ret void 93 94UnifiedReturnBlock: 95 ret void 96} 97 98define void @atest2(i32 %x, i32 %n) nounwind { 99; X86-LABEL: atest2: 100; X86: # %bb.0: # %entry 101; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 102; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 103; X86-NEXT: btl %ecx, %eax 104; X86-NEXT: jb .LBB2_2 105; X86-NEXT: # %bb.1: # %bb 106; X86-NEXT: calll foo 107; X86-NEXT: .LBB2_2: # %UnifiedReturnBlock 108; X86-NEXT: retl 109; 110; X64-LABEL: atest2: 111; X64: # %bb.0: # %entry 112; X64-NEXT: btl %esi, %edi 113; X64-NEXT: jb .LBB2_2 114; X64-NEXT: # %bb.1: # %bb 115; X64-NEXT: pushq %rax 116; X64-NEXT: callq foo 117; X64-NEXT: popq %rax 118; X64-NEXT: .LBB2_2: # %UnifiedReturnBlock 119; X64-NEXT: retq 120entry: 121 %tmp29 = ashr i32 %x, %n 122 %tmp3 = and i32 %tmp29, 1 123 %tmp4 = icmp eq i32 %tmp3, 0 124 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 125 126bb: 127 call void @foo() 128 ret void 129 130UnifiedReturnBlock: 131 ret void 132} 133 134define void @atest2b(i32 %x, i32 %n) nounwind { 135; X86-LABEL: atest2b: 136; X86: # %bb.0: # %entry 137; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 138; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 139; X86-NEXT: btl %ecx, %eax 140; X86-NEXT: jae .LBB3_1 141; X86-NEXT: # %bb.2: # %UnifiedReturnBlock 142; X86-NEXT: retl 143; X86-NEXT: .LBB3_1: # %bb 144; X86-NEXT: calll foo 145; X86-NEXT: retl 146; 147; X64-LABEL: atest2b: 148; X64: # %bb.0: # %entry 149; X64-NEXT: btl %esi, %edi 150; X64-NEXT: jae .LBB3_1 151; X64-NEXT: # %bb.2: # %UnifiedReturnBlock 152; X64-NEXT: retq 153; X64-NEXT: .LBB3_1: # %bb 154; X64-NEXT: pushq %rax 155; X64-NEXT: callq foo 156; X64-NEXT: popq %rax 157; X64-NEXT: retq 158entry: 159 %tmp29 = ashr i32 %x, %n 160 %tmp3 = and i32 1, %tmp29 161 %tmp4 = icmp eq i32 %tmp3, 0 162 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 163 164bb: 165 call void @foo() 166 ret void 167 168UnifiedReturnBlock: 169 ret void 170} 171 172define void @test3(i32 %x, i32 %n) nounwind { 173; X86-LABEL: test3: 174; X86: # %bb.0: # %entry 175; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 176; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 177; X86-NEXT: btl %ecx, %eax 178; X86-NEXT: jae .LBB4_1 179; X86-NEXT: # %bb.2: # %UnifiedReturnBlock 180; X86-NEXT: retl 181; X86-NEXT: .LBB4_1: # %bb 182; X86-NEXT: calll foo 183; X86-NEXT: retl 184; 185; X64-LABEL: test3: 186; X64: # %bb.0: # %entry 187; X64-NEXT: btl %esi, %edi 188; X64-NEXT: jae .LBB4_1 189; X64-NEXT: # %bb.2: # %UnifiedReturnBlock 190; X64-NEXT: retq 191; X64-NEXT: .LBB4_1: # %bb 192; X64-NEXT: pushq %rax 193; X64-NEXT: callq foo 194; X64-NEXT: popq %rax 195; X64-NEXT: retq 196entry: 197 %tmp29 = shl i32 1, %n 198 %tmp3 = and i32 %tmp29, %x 199 %tmp4 = icmp eq i32 %tmp3, 0 200 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 201 202bb: 203 call void @foo() 204 ret void 205 206UnifiedReturnBlock: 207 ret void 208} 209 210define void @test3b(i32 %x, i32 %n) nounwind { 211; X86-LABEL: test3b: 212; X86: # %bb.0: # %entry 213; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 214; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 215; X86-NEXT: btl %ecx, %eax 216; X86-NEXT: jae .LBB5_1 217; X86-NEXT: # %bb.2: # %UnifiedReturnBlock 218; X86-NEXT: retl 219; X86-NEXT: .LBB5_1: # %bb 220; X86-NEXT: calll foo 221; X86-NEXT: retl 222; 223; X64-LABEL: test3b: 224; X64: # %bb.0: # %entry 225; X64-NEXT: btl %esi, %edi 226; X64-NEXT: jae .LBB5_1 227; X64-NEXT: # %bb.2: # %UnifiedReturnBlock 228; X64-NEXT: retq 229; X64-NEXT: .LBB5_1: # %bb 230; X64-NEXT: pushq %rax 231; X64-NEXT: callq foo 232; X64-NEXT: popq %rax 233; X64-NEXT: retq 234entry: 235 %tmp29 = shl i32 1, %n 236 %tmp3 = and i32 %x, %tmp29 237 %tmp4 = icmp eq i32 %tmp3, 0 238 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 239 240bb: 241 call void @foo() 242 ret void 243 244UnifiedReturnBlock: 245 ret void 246} 247 248define void @testne2(i32 %x, i32 %n) nounwind { 249; X86-LABEL: testne2: 250; X86: # %bb.0: # %entry 251; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 252; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 253; X86-NEXT: btl %ecx, %eax 254; X86-NEXT: jae .LBB6_2 255; X86-NEXT: # %bb.1: # %bb 256; X86-NEXT: calll foo 257; X86-NEXT: .LBB6_2: # %UnifiedReturnBlock 258; X86-NEXT: retl 259; 260; X64-LABEL: testne2: 261; X64: # %bb.0: # %entry 262; X64-NEXT: btl %esi, %edi 263; X64-NEXT: jae .LBB6_2 264; X64-NEXT: # %bb.1: # %bb 265; X64-NEXT: pushq %rax 266; X64-NEXT: callq foo 267; X64-NEXT: popq %rax 268; X64-NEXT: .LBB6_2: # %UnifiedReturnBlock 269; X64-NEXT: retq 270entry: 271 %tmp29 = lshr i32 %x, %n 272 %tmp3 = and i32 %tmp29, 1 273 %tmp4 = icmp ne i32 %tmp3, 0 274 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 275 276bb: 277 call void @foo() 278 ret void 279 280UnifiedReturnBlock: 281 ret void 282} 283 284define void @testne2b(i32 %x, i32 %n) nounwind { 285; X86-LABEL: testne2b: 286; X86: # %bb.0: # %entry 287; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 288; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 289; X86-NEXT: btl %ecx, %eax 290; X86-NEXT: jae .LBB7_2 291; X86-NEXT: # %bb.1: # %bb 292; X86-NEXT: calll foo 293; X86-NEXT: .LBB7_2: # %UnifiedReturnBlock 294; X86-NEXT: retl 295; 296; X64-LABEL: testne2b: 297; X64: # %bb.0: # %entry 298; X64-NEXT: btl %esi, %edi 299; X64-NEXT: jae .LBB7_2 300; X64-NEXT: # %bb.1: # %bb 301; X64-NEXT: pushq %rax 302; X64-NEXT: callq foo 303; X64-NEXT: popq %rax 304; X64-NEXT: .LBB7_2: # %UnifiedReturnBlock 305; X64-NEXT: retq 306entry: 307 %tmp29 = lshr i32 %x, %n 308 %tmp3 = and i32 1, %tmp29 309 %tmp4 = icmp ne i32 %tmp3, 0 310 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 311 312bb: 313 call void @foo() 314 ret void 315 316UnifiedReturnBlock: 317 ret void 318} 319 320define void @atestne2(i32 %x, i32 %n) nounwind { 321; X86-LABEL: atestne2: 322; X86: # %bb.0: # %entry 323; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 324; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 325; X86-NEXT: btl %ecx, %eax 326; X86-NEXT: jae .LBB8_2 327; X86-NEXT: # %bb.1: # %bb 328; X86-NEXT: calll foo 329; X86-NEXT: .LBB8_2: # %UnifiedReturnBlock 330; X86-NEXT: retl 331; 332; X64-LABEL: atestne2: 333; X64: # %bb.0: # %entry 334; X64-NEXT: btl %esi, %edi 335; X64-NEXT: jae .LBB8_2 336; X64-NEXT: # %bb.1: # %bb 337; X64-NEXT: pushq %rax 338; X64-NEXT: callq foo 339; X64-NEXT: popq %rax 340; X64-NEXT: .LBB8_2: # %UnifiedReturnBlock 341; X64-NEXT: retq 342entry: 343 %tmp29 = ashr i32 %x, %n 344 %tmp3 = and i32 %tmp29, 1 345 %tmp4 = icmp ne i32 %tmp3, 0 346 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 347 348bb: 349 call void @foo() 350 ret void 351 352UnifiedReturnBlock: 353 ret void 354} 355 356define void @atestne2b(i32 %x, i32 %n) nounwind { 357; X86-LABEL: atestne2b: 358; X86: # %bb.0: # %entry 359; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 360; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 361; X86-NEXT: btl %ecx, %eax 362; X86-NEXT: jae .LBB9_2 363; X86-NEXT: # %bb.1: # %bb 364; X86-NEXT: calll foo 365; X86-NEXT: .LBB9_2: # %UnifiedReturnBlock 366; X86-NEXT: retl 367; 368; X64-LABEL: atestne2b: 369; X64: # %bb.0: # %entry 370; X64-NEXT: btl %esi, %edi 371; X64-NEXT: jae .LBB9_2 372; X64-NEXT: # %bb.1: # %bb 373; X64-NEXT: pushq %rax 374; X64-NEXT: callq foo 375; X64-NEXT: popq %rax 376; X64-NEXT: .LBB9_2: # %UnifiedReturnBlock 377; X64-NEXT: retq 378entry: 379 %tmp29 = ashr i32 %x, %n 380 %tmp3 = and i32 1, %tmp29 381 %tmp4 = icmp ne i32 %tmp3, 0 382 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 383 384bb: 385 call void @foo() 386 ret void 387 388UnifiedReturnBlock: 389 ret void 390} 391 392define void @testne3(i32 %x, i32 %n) nounwind { 393; X86-LABEL: testne3: 394; X86: # %bb.0: # %entry 395; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 396; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 397; X86-NEXT: btl %ecx, %eax 398; X86-NEXT: jae .LBB10_2 399; X86-NEXT: # %bb.1: # %bb 400; X86-NEXT: calll foo 401; X86-NEXT: .LBB10_2: # %UnifiedReturnBlock 402; X86-NEXT: retl 403; 404; X64-LABEL: testne3: 405; X64: # %bb.0: # %entry 406; X64-NEXT: btl %esi, %edi 407; X64-NEXT: jae .LBB10_2 408; X64-NEXT: # %bb.1: # %bb 409; X64-NEXT: pushq %rax 410; X64-NEXT: callq foo 411; X64-NEXT: popq %rax 412; X64-NEXT: .LBB10_2: # %UnifiedReturnBlock 413; X64-NEXT: retq 414entry: 415 %tmp29 = shl i32 1, %n 416 %tmp3 = and i32 %tmp29, %x 417 %tmp4 = icmp ne i32 %tmp3, 0 418 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 419 420bb: 421 call void @foo() 422 ret void 423 424UnifiedReturnBlock: 425 ret void 426} 427 428define void @testne3b(i32 %x, i32 %n) nounwind { 429; X86-LABEL: testne3b: 430; X86: # %bb.0: # %entry 431; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 432; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 433; X86-NEXT: btl %ecx, %eax 434; X86-NEXT: jae .LBB11_2 435; X86-NEXT: # %bb.1: # %bb 436; X86-NEXT: calll foo 437; X86-NEXT: .LBB11_2: # %UnifiedReturnBlock 438; X86-NEXT: retl 439; 440; X64-LABEL: testne3b: 441; X64: # %bb.0: # %entry 442; X64-NEXT: btl %esi, %edi 443; X64-NEXT: jae .LBB11_2 444; X64-NEXT: # %bb.1: # %bb 445; X64-NEXT: pushq %rax 446; X64-NEXT: callq foo 447; X64-NEXT: popq %rax 448; X64-NEXT: .LBB11_2: # %UnifiedReturnBlock 449; X64-NEXT: retq 450entry: 451 %tmp29 = shl i32 1, %n 452 %tmp3 = and i32 %x, %tmp29 453 %tmp4 = icmp ne i32 %tmp3, 0 454 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 455 456bb: 457 call void @foo() 458 ret void 459 460UnifiedReturnBlock: 461 ret void 462} 463 464define void @query2(i32 %x, i32 %n) nounwind { 465; X86-LABEL: query2: 466; X86: # %bb.0: # %entry 467; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 468; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 469; X86-NEXT: btl %ecx, %eax 470; X86-NEXT: jae .LBB12_2 471; X86-NEXT: # %bb.1: # %bb 472; X86-NEXT: calll foo 473; X86-NEXT: .LBB12_2: # %UnifiedReturnBlock 474; X86-NEXT: retl 475; 476; X64-LABEL: query2: 477; X64: # %bb.0: # %entry 478; X64-NEXT: btl %esi, %edi 479; X64-NEXT: jae .LBB12_2 480; X64-NEXT: # %bb.1: # %bb 481; X64-NEXT: pushq %rax 482; X64-NEXT: callq foo 483; X64-NEXT: popq %rax 484; X64-NEXT: .LBB12_2: # %UnifiedReturnBlock 485; X64-NEXT: retq 486entry: 487 %tmp29 = lshr i32 %x, %n 488 %tmp3 = and i32 %tmp29, 1 489 %tmp4 = icmp eq i32 %tmp3, 1 490 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 491 492bb: 493 call void @foo() 494 ret void 495 496UnifiedReturnBlock: 497 ret void 498} 499 500define void @query2b(i32 %x, i32 %n) nounwind { 501; X86-LABEL: query2b: 502; X86: # %bb.0: # %entry 503; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 504; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 505; X86-NEXT: btl %ecx, %eax 506; X86-NEXT: jae .LBB13_2 507; X86-NEXT: # %bb.1: # %bb 508; X86-NEXT: calll foo 509; X86-NEXT: .LBB13_2: # %UnifiedReturnBlock 510; X86-NEXT: retl 511; 512; X64-LABEL: query2b: 513; X64: # %bb.0: # %entry 514; X64-NEXT: btl %esi, %edi 515; X64-NEXT: jae .LBB13_2 516; X64-NEXT: # %bb.1: # %bb 517; X64-NEXT: pushq %rax 518; X64-NEXT: callq foo 519; X64-NEXT: popq %rax 520; X64-NEXT: .LBB13_2: # %UnifiedReturnBlock 521; X64-NEXT: retq 522entry: 523 %tmp29 = lshr i32 %x, %n 524 %tmp3 = and i32 1, %tmp29 525 %tmp4 = icmp eq i32 %tmp3, 1 526 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 527 528bb: 529 call void @foo() 530 ret void 531 532UnifiedReturnBlock: 533 ret void 534} 535 536define void @aquery2(i32 %x, i32 %n) nounwind { 537; X86-LABEL: aquery2: 538; X86: # %bb.0: # %entry 539; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 540; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 541; X86-NEXT: btl %ecx, %eax 542; X86-NEXT: jae .LBB14_2 543; X86-NEXT: # %bb.1: # %bb 544; X86-NEXT: calll foo 545; X86-NEXT: .LBB14_2: # %UnifiedReturnBlock 546; X86-NEXT: retl 547; 548; X64-LABEL: aquery2: 549; X64: # %bb.0: # %entry 550; X64-NEXT: btl %esi, %edi 551; X64-NEXT: jae .LBB14_2 552; X64-NEXT: # %bb.1: # %bb 553; X64-NEXT: pushq %rax 554; X64-NEXT: callq foo 555; X64-NEXT: popq %rax 556; X64-NEXT: .LBB14_2: # %UnifiedReturnBlock 557; X64-NEXT: retq 558entry: 559 %tmp29 = ashr i32 %x, %n 560 %tmp3 = and i32 %tmp29, 1 561 %tmp4 = icmp eq i32 %tmp3, 1 562 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 563 564bb: 565 call void @foo() 566 ret void 567 568UnifiedReturnBlock: 569 ret void 570} 571 572define void @aquery2b(i32 %x, i32 %n) nounwind { 573; X86-LABEL: aquery2b: 574; X86: # %bb.0: # %entry 575; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 576; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 577; X86-NEXT: btl %ecx, %eax 578; X86-NEXT: jae .LBB15_2 579; X86-NEXT: # %bb.1: # %bb 580; X86-NEXT: calll foo 581; X86-NEXT: .LBB15_2: # %UnifiedReturnBlock 582; X86-NEXT: retl 583; 584; X64-LABEL: aquery2b: 585; X64: # %bb.0: # %entry 586; X64-NEXT: btl %esi, %edi 587; X64-NEXT: jae .LBB15_2 588; X64-NEXT: # %bb.1: # %bb 589; X64-NEXT: pushq %rax 590; X64-NEXT: callq foo 591; X64-NEXT: popq %rax 592; X64-NEXT: .LBB15_2: # %UnifiedReturnBlock 593; X64-NEXT: retq 594entry: 595 %tmp29 = ashr i32 %x, %n 596 %tmp3 = and i32 1, %tmp29 597 %tmp4 = icmp eq i32 %tmp3, 1 598 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 599 600bb: 601 call void @foo() 602 ret void 603 604UnifiedReturnBlock: 605 ret void 606} 607 608define void @query3(i32 %x, i32 %n) nounwind { 609; X86-LABEL: query3: 610; X86: # %bb.0: # %entry 611; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 612; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 613; X86-NEXT: btl %ecx, %eax 614; X86-NEXT: jae .LBB16_2 615; X86-NEXT: # %bb.1: # %bb 616; X86-NEXT: calll foo 617; X86-NEXT: .LBB16_2: # %UnifiedReturnBlock 618; X86-NEXT: retl 619; 620; X64-LABEL: query3: 621; X64: # %bb.0: # %entry 622; X64-NEXT: btl %esi, %edi 623; X64-NEXT: jae .LBB16_2 624; X64-NEXT: # %bb.1: # %bb 625; X64-NEXT: pushq %rax 626; X64-NEXT: callq foo 627; X64-NEXT: popq %rax 628; X64-NEXT: .LBB16_2: # %UnifiedReturnBlock 629; X64-NEXT: retq 630entry: 631 %tmp29 = shl i32 1, %n 632 %tmp3 = and i32 %tmp29, %x 633 %tmp4 = icmp eq i32 %tmp3, %tmp29 634 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 635 636bb: 637 call void @foo() 638 ret void 639 640UnifiedReturnBlock: 641 ret void 642} 643 644define void @query3b(i32 %x, i32 %n) nounwind { 645; X86-LABEL: query3b: 646; X86: # %bb.0: # %entry 647; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 648; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 649; X86-NEXT: btl %ecx, %eax 650; X86-NEXT: jae .LBB17_2 651; X86-NEXT: # %bb.1: # %bb 652; X86-NEXT: calll foo 653; X86-NEXT: .LBB17_2: # %UnifiedReturnBlock 654; X86-NEXT: retl 655; 656; X64-LABEL: query3b: 657; X64: # %bb.0: # %entry 658; X64-NEXT: btl %esi, %edi 659; X64-NEXT: jae .LBB17_2 660; X64-NEXT: # %bb.1: # %bb 661; X64-NEXT: pushq %rax 662; X64-NEXT: callq foo 663; X64-NEXT: popq %rax 664; X64-NEXT: .LBB17_2: # %UnifiedReturnBlock 665; X64-NEXT: retq 666entry: 667 %tmp29 = shl i32 1, %n 668 %tmp3 = and i32 %x, %tmp29 669 %tmp4 = icmp eq i32 %tmp3, %tmp29 670 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 671 672bb: 673 call void @foo() 674 ret void 675 676UnifiedReturnBlock: 677 ret void 678} 679 680define void @query3x(i32 %x, i32 %n) nounwind { 681; X86-LABEL: query3x: 682; X86: # %bb.0: # %entry 683; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 684; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 685; X86-NEXT: btl %ecx, %eax 686; X86-NEXT: jae .LBB18_2 687; X86-NEXT: # %bb.1: # %bb 688; X86-NEXT: calll foo 689; X86-NEXT: .LBB18_2: # %UnifiedReturnBlock 690; X86-NEXT: retl 691; 692; X64-LABEL: query3x: 693; X64: # %bb.0: # %entry 694; X64-NEXT: btl %esi, %edi 695; X64-NEXT: jae .LBB18_2 696; X64-NEXT: # %bb.1: # %bb 697; X64-NEXT: pushq %rax 698; X64-NEXT: callq foo 699; X64-NEXT: popq %rax 700; X64-NEXT: .LBB18_2: # %UnifiedReturnBlock 701; X64-NEXT: retq 702entry: 703 %tmp29 = shl i32 1, %n 704 %tmp3 = and i32 %tmp29, %x 705 %tmp4 = icmp eq i32 %tmp29, %tmp3 706 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 707 708bb: 709 call void @foo() 710 ret void 711 712UnifiedReturnBlock: 713 ret void 714} 715 716define void @query3bx(i32 %x, i32 %n) nounwind { 717; X86-LABEL: query3bx: 718; X86: # %bb.0: # %entry 719; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 720; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 721; X86-NEXT: btl %ecx, %eax 722; X86-NEXT: jae .LBB19_2 723; X86-NEXT: # %bb.1: # %bb 724; X86-NEXT: calll foo 725; X86-NEXT: .LBB19_2: # %UnifiedReturnBlock 726; X86-NEXT: retl 727; 728; X64-LABEL: query3bx: 729; X64: # %bb.0: # %entry 730; X64-NEXT: btl %esi, %edi 731; X64-NEXT: jae .LBB19_2 732; X64-NEXT: # %bb.1: # %bb 733; X64-NEXT: pushq %rax 734; X64-NEXT: callq foo 735; X64-NEXT: popq %rax 736; X64-NEXT: .LBB19_2: # %UnifiedReturnBlock 737; X64-NEXT: retq 738entry: 739 %tmp29 = shl i32 1, %n 740 %tmp3 = and i32 %x, %tmp29 741 %tmp4 = icmp eq i32 %tmp29, %tmp3 742 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 743 744bb: 745 call void @foo() 746 ret void 747 748UnifiedReturnBlock: 749 ret void 750} 751 752define void @queryne2(i32 %x, i32 %n) nounwind { 753; X86-LABEL: queryne2: 754; X86: # %bb.0: # %entry 755; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 756; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 757; X86-NEXT: btl %ecx, %eax 758; X86-NEXT: jb .LBB20_2 759; X86-NEXT: # %bb.1: # %bb 760; X86-NEXT: calll foo 761; X86-NEXT: .LBB20_2: # %UnifiedReturnBlock 762; X86-NEXT: retl 763; 764; X64-LABEL: queryne2: 765; X64: # %bb.0: # %entry 766; X64-NEXT: btl %esi, %edi 767; X64-NEXT: jb .LBB20_2 768; X64-NEXT: # %bb.1: # %bb 769; X64-NEXT: pushq %rax 770; X64-NEXT: callq foo 771; X64-NEXT: popq %rax 772; X64-NEXT: .LBB20_2: # %UnifiedReturnBlock 773; X64-NEXT: retq 774entry: 775 %tmp29 = lshr i32 %x, %n 776 %tmp3 = and i32 %tmp29, 1 777 %tmp4 = icmp ne i32 %tmp3, 1 778 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 779 780bb: 781 call void @foo() 782 ret void 783 784UnifiedReturnBlock: 785 ret void 786} 787 788define void @queryne2b(i32 %x, i32 %n) nounwind { 789; X86-LABEL: queryne2b: 790; X86: # %bb.0: # %entry 791; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 792; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 793; X86-NEXT: btl %ecx, %eax 794; X86-NEXT: jb .LBB21_2 795; X86-NEXT: # %bb.1: # %bb 796; X86-NEXT: calll foo 797; X86-NEXT: .LBB21_2: # %UnifiedReturnBlock 798; X86-NEXT: retl 799; 800; X64-LABEL: queryne2b: 801; X64: # %bb.0: # %entry 802; X64-NEXT: btl %esi, %edi 803; X64-NEXT: jb .LBB21_2 804; X64-NEXT: # %bb.1: # %bb 805; X64-NEXT: pushq %rax 806; X64-NEXT: callq foo 807; X64-NEXT: popq %rax 808; X64-NEXT: .LBB21_2: # %UnifiedReturnBlock 809; X64-NEXT: retq 810entry: 811 %tmp29 = lshr i32 %x, %n 812 %tmp3 = and i32 1, %tmp29 813 %tmp4 = icmp ne i32 %tmp3, 1 814 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 815 816bb: 817 call void @foo() 818 ret void 819 820UnifiedReturnBlock: 821 ret void 822} 823 824define void @aqueryne2(i32 %x, i32 %n) nounwind { 825; X86-LABEL: aqueryne2: 826; X86: # %bb.0: # %entry 827; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 828; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 829; X86-NEXT: btl %ecx, %eax 830; X86-NEXT: jb .LBB22_2 831; X86-NEXT: # %bb.1: # %bb 832; X86-NEXT: calll foo 833; X86-NEXT: .LBB22_2: # %UnifiedReturnBlock 834; X86-NEXT: retl 835; 836; X64-LABEL: aqueryne2: 837; X64: # %bb.0: # %entry 838; X64-NEXT: btl %esi, %edi 839; X64-NEXT: jb .LBB22_2 840; X64-NEXT: # %bb.1: # %bb 841; X64-NEXT: pushq %rax 842; X64-NEXT: callq foo 843; X64-NEXT: popq %rax 844; X64-NEXT: .LBB22_2: # %UnifiedReturnBlock 845; X64-NEXT: retq 846entry: 847 %tmp29 = ashr i32 %x, %n 848 %tmp3 = and i32 %tmp29, 1 849 %tmp4 = icmp ne i32 %tmp3, 1 850 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 851 852bb: 853 call void @foo() 854 ret void 855 856UnifiedReturnBlock: 857 ret void 858} 859 860define void @aqueryne2b(i32 %x, i32 %n) nounwind { 861; X86-LABEL: aqueryne2b: 862; X86: # %bb.0: # %entry 863; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 864; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 865; X86-NEXT: btl %ecx, %eax 866; X86-NEXT: jb .LBB23_2 867; X86-NEXT: # %bb.1: # %bb 868; X86-NEXT: calll foo 869; X86-NEXT: .LBB23_2: # %UnifiedReturnBlock 870; X86-NEXT: retl 871; 872; X64-LABEL: aqueryne2b: 873; X64: # %bb.0: # %entry 874; X64-NEXT: btl %esi, %edi 875; X64-NEXT: jb .LBB23_2 876; X64-NEXT: # %bb.1: # %bb 877; X64-NEXT: pushq %rax 878; X64-NEXT: callq foo 879; X64-NEXT: popq %rax 880; X64-NEXT: .LBB23_2: # %UnifiedReturnBlock 881; X64-NEXT: retq 882entry: 883 %tmp29 = ashr i32 %x, %n 884 %tmp3 = and i32 1, %tmp29 885 %tmp4 = icmp ne i32 %tmp3, 1 886 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 887 888bb: 889 call void @foo() 890 ret void 891 892UnifiedReturnBlock: 893 ret void 894} 895 896define void @queryne3(i32 %x, i32 %n) nounwind { 897; X86-LABEL: queryne3: 898; X86: # %bb.0: # %entry 899; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 900; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 901; X86-NEXT: btl %ecx, %eax 902; X86-NEXT: jb .LBB24_2 903; X86-NEXT: # %bb.1: # %bb 904; X86-NEXT: calll foo 905; X86-NEXT: .LBB24_2: # %UnifiedReturnBlock 906; X86-NEXT: retl 907; 908; X64-LABEL: queryne3: 909; X64: # %bb.0: # %entry 910; X64-NEXT: btl %esi, %edi 911; X64-NEXT: jb .LBB24_2 912; X64-NEXT: # %bb.1: # %bb 913; X64-NEXT: pushq %rax 914; X64-NEXT: callq foo 915; X64-NEXT: popq %rax 916; X64-NEXT: .LBB24_2: # %UnifiedReturnBlock 917; X64-NEXT: retq 918entry: 919 %tmp29 = shl i32 1, %n 920 %tmp3 = and i32 %tmp29, %x 921 %tmp4 = icmp ne i32 %tmp3, %tmp29 922 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 923 924bb: 925 call void @foo() 926 ret void 927 928UnifiedReturnBlock: 929 ret void 930} 931 932define void @queryne3b(i32 %x, i32 %n) nounwind { 933; X86-LABEL: queryne3b: 934; X86: # %bb.0: # %entry 935; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 936; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 937; X86-NEXT: btl %ecx, %eax 938; X86-NEXT: jb .LBB25_2 939; X86-NEXT: # %bb.1: # %bb 940; X86-NEXT: calll foo 941; X86-NEXT: .LBB25_2: # %UnifiedReturnBlock 942; X86-NEXT: retl 943; 944; X64-LABEL: queryne3b: 945; X64: # %bb.0: # %entry 946; X64-NEXT: btl %esi, %edi 947; X64-NEXT: jb .LBB25_2 948; X64-NEXT: # %bb.1: # %bb 949; X64-NEXT: pushq %rax 950; X64-NEXT: callq foo 951; X64-NEXT: popq %rax 952; X64-NEXT: .LBB25_2: # %UnifiedReturnBlock 953; X64-NEXT: retq 954entry: 955 %tmp29 = shl i32 1, %n 956 %tmp3 = and i32 %x, %tmp29 957 %tmp4 = icmp ne i32 %tmp3, %tmp29 958 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 959 960bb: 961 call void @foo() 962 ret void 963 964UnifiedReturnBlock: 965 ret void 966} 967 968define void @queryne3x(i32 %x, i32 %n) nounwind { 969; X86-LABEL: queryne3x: 970; X86: # %bb.0: # %entry 971; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 972; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 973; X86-NEXT: btl %ecx, %eax 974; X86-NEXT: jb .LBB26_2 975; X86-NEXT: # %bb.1: # %bb 976; X86-NEXT: calll foo 977; X86-NEXT: .LBB26_2: # %UnifiedReturnBlock 978; X86-NEXT: retl 979; 980; X64-LABEL: queryne3x: 981; X64: # %bb.0: # %entry 982; X64-NEXT: btl %esi, %edi 983; X64-NEXT: jb .LBB26_2 984; X64-NEXT: # %bb.1: # %bb 985; X64-NEXT: pushq %rax 986; X64-NEXT: callq foo 987; X64-NEXT: popq %rax 988; X64-NEXT: .LBB26_2: # %UnifiedReturnBlock 989; X64-NEXT: retq 990entry: 991 %tmp29 = shl i32 1, %n 992 %tmp3 = and i32 %tmp29, %x 993 %tmp4 = icmp ne i32 %tmp29, %tmp3 994 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 995 996bb: 997 call void @foo() 998 ret void 999 1000UnifiedReturnBlock: 1001 ret void 1002} 1003 1004define void @queryne3bx(i32 %x, i32 %n) nounwind { 1005; X86-LABEL: queryne3bx: 1006; X86: # %bb.0: # %entry 1007; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1008; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1009; X86-NEXT: btl %ecx, %eax 1010; X86-NEXT: jb .LBB27_2 1011; X86-NEXT: # %bb.1: # %bb 1012; X86-NEXT: calll foo 1013; X86-NEXT: .LBB27_2: # %UnifiedReturnBlock 1014; X86-NEXT: retl 1015; 1016; X64-LABEL: queryne3bx: 1017; X64: # %bb.0: # %entry 1018; X64-NEXT: btl %esi, %edi 1019; X64-NEXT: jb .LBB27_2 1020; X64-NEXT: # %bb.1: # %bb 1021; X64-NEXT: pushq %rax 1022; X64-NEXT: callq foo 1023; X64-NEXT: popq %rax 1024; X64-NEXT: .LBB27_2: # %UnifiedReturnBlock 1025; X64-NEXT: retq 1026entry: 1027 %tmp29 = shl i32 1, %n 1028 %tmp3 = and i32 %x, %tmp29 1029 %tmp4 = icmp ne i32 %tmp29, %tmp3 1030 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 1031 1032bb: 1033 call void @foo() 1034 ret void 1035 1036UnifiedReturnBlock: 1037 ret void 1038} 1039 1040declare void @foo() 1041 1042define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind { 1043; X86-LABEL: invert: 1044; X86: # %bb.0: 1045; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1046; X86-NEXT: notl %eax 1047; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1048; X86-NEXT: btl %ecx, %eax 1049; X86-NEXT: setb %al 1050; X86-NEXT: retl 1051; 1052; X64-LABEL: invert: 1053; X64: # %bb.0: 1054; X64-NEXT: notl %edi 1055; X64-NEXT: btl %esi, %edi 1056; X64-NEXT: setb %al 1057; X64-NEXT: retq 1058 %neg = xor i32 %flags, -1 1059 %shl = shl i32 1, %flag 1060 %and = and i32 %shl, %neg 1061 %tobool = icmp ne i32 %and, 0 1062 ret i1 %tobool 1063} 1064 1065define zeroext i1 @extend(i32 %bit, i64 %bits) { 1066; X86-LABEL: extend: 1067; X86: # %bb.0: # %entry 1068; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1069; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1070; X86-NEXT: btl %ecx, %eax 1071; X86-NEXT: setb %al 1072; X86-NEXT: retl 1073; 1074; X64-LABEL: extend: 1075; X64: # %bb.0: # %entry 1076; X64-NEXT: btl %edi, %esi 1077; X64-NEXT: setb %al 1078; X64-NEXT: retq 1079entry: 1080 %and = and i32 %bit, 31 1081 %sh_prom = zext i32 %and to i64 1082 %shl = shl i64 1, %sh_prom 1083 %and1 = and i64 %shl, %bits 1084 %tobool = icmp ne i64 %and1, 0 1085 ret i1 %tobool 1086} 1087 1088; TODO: BT fails to look through to demanded bits as c%32 has more than one use. 1089; void demanded_i32(int *a, int *b, unsigned c) { 1090; if ((a[c/32] >> (c % 32)) & 1) 1091; b[c/32] |= 1 << (c % 32); 1092; } 1093define void @demanded_i32(i32* nocapture readonly, i32* nocapture, i32) nounwind { 1094; X86-LABEL: demanded_i32: 1095; X86: # %bb.0: 1096; X86-NEXT: pushl %esi 1097; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1098; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1099; X86-NEXT: movl %ecx, %eax 1100; X86-NEXT: shrl $5, %eax 1101; X86-NEXT: movl (%edx,%eax,4), %esi 1102; X86-NEXT: movl $1, %edx 1103; X86-NEXT: shll %cl, %edx 1104; X86-NEXT: btl %ecx, %esi 1105; X86-NEXT: jae .LBB30_2 1106; X86-NEXT: # %bb.1: 1107; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1108; X86-NEXT: orl %edx, (%ecx,%eax,4) 1109; X86-NEXT: .LBB30_2: 1110; X86-NEXT: popl %esi 1111; X86-NEXT: retl 1112; 1113; X64-LABEL: demanded_i32: 1114; X64: # %bb.0: 1115; X64-NEXT: movl %edx, %ecx 1116; X64-NEXT: movl %edx, %eax 1117; X64-NEXT: shrl $5, %eax 1118; X64-NEXT: movl (%rdi,%rax,4), %edi 1119; X64-NEXT: movl $1, %edx 1120; X64-NEXT: shll %cl, %edx 1121; X64-NEXT: btl %ecx, %edi 1122; X64-NEXT: jae .LBB30_2 1123; X64-NEXT: # %bb.1: 1124; X64-NEXT: orl %edx, (%rsi,%rax,4) 1125; X64-NEXT: .LBB30_2: 1126; X64-NEXT: retq 1127 %4 = lshr i32 %2, 5 1128 %5 = zext i32 %4 to i64 1129 %6 = getelementptr inbounds i32, i32* %0, i64 %5 1130 %7 = load i32, i32* %6, align 4 1131 %8 = and i32 %2, 31 1132 %9 = shl i32 1, %8 1133 %10 = and i32 %7, %9 1134 %11 = icmp eq i32 %10, 0 1135 br i1 %11, label %16, label %12 1136 1137; <label>:12: 1138 %13 = getelementptr inbounds i32, i32* %1, i64 %5 1139 %14 = load i32, i32* %13, align 4 1140 %15 = or i32 %14, %9 1141 store i32 %15, i32* %13, align 4 1142 br label %16 1143 1144; <label>:16: 1145 ret void 1146} 1147 1148; Make sure we can simplify bt when the shift amount has known zeros in it 1149; which cause the and mask to have bits removed. 1150define zeroext i1 @demanded_with_known_zeroes(i32 %bit, i32 %bits) { 1151; X86-LABEL: demanded_with_known_zeroes: 1152; X86: # %bb.0: # %entry 1153; X86-NEXT: movb {{[0-9]+}}(%esp), %al 1154; X86-NEXT: shlb $2, %al 1155; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1156; X86-NEXT: movzbl %al, %eax 1157; X86-NEXT: btl %eax, %ecx 1158; X86-NEXT: setb %al 1159; X86-NEXT: retl 1160; 1161; X64-LABEL: demanded_with_known_zeroes: 1162; X64: # %bb.0: # %entry 1163; X64-NEXT: shll $2, %edi 1164; X64-NEXT: btl %edi, %esi 1165; X64-NEXT: setb %al 1166; X64-NEXT: retq 1167entry: 1168 %bit2 = shl i32 %bit, 2 1169 %and = and i32 %bit2, 31 1170 %shl = shl i32 1, %and 1171 %and1 = and i32 %shl, %bits 1172 %tobool = icmp ne i32 %and1, 0 1173 ret i1 %tobool 1174} 1175