1173 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X644; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=X645 6; PR32537 8; The register+memory form of the BT instruction should be usable on9; pentium4, however it is currently disabled due to the register+memory10; 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 neither21; 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: # %entry27; X86-NEXT: movl {{[0-9]+}}(%esp), %eax28; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx29; X86-NEXT: btl %ecx, %eax30; X86-NEXT: jb .LBB0_231; X86-NEXT: # %bb.1: # %bb32; X86-NEXT: calll foo@PLT33; X86-NEXT: .LBB0_2: # %UnifiedReturnBlock34; X86-NEXT: retl35;36; X64-LABEL: test2:37; X64: # %bb.0: # %entry38; X64-NEXT: btl %esi, %edi39; X64-NEXT: jb .LBB0_240; X64-NEXT: # %bb.1: # %bb41; X64-NEXT: pushq %rax42; X64-NEXT: callq foo@PLT43; X64-NEXT: popq %rax44; X64-NEXT: .LBB0_2: # %UnifiedReturnBlock45; X64-NEXT: retq46entry:47 %tmp29 = lshr i32 %x, %n48 %tmp3 = and i32 %tmp29, 149 %tmp4 = icmp eq i32 %tmp3, 050 br i1 %tmp4, label %bb, label %UnifiedReturnBlock51 52bb:53 call void @foo()54 ret void55 56UnifiedReturnBlock:57 ret void58}59 60define void @test2b(i32 %x, i32 %n) nounwind {61; X86-LABEL: test2b:62; X86: # %bb.0: # %entry63; X86-NEXT: movl {{[0-9]+}}(%esp), %eax64; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx65; X86-NEXT: btl %ecx, %eax66; X86-NEXT: jae .LBB1_167; X86-NEXT: # %bb.2: # %UnifiedReturnBlock68; X86-NEXT: retl69; X86-NEXT: .LBB1_1: # %bb70; X86-NEXT: calll foo@PLT71; X86-NEXT: retl72;73; X64-LABEL: test2b:74; X64: # %bb.0: # %entry75; X64-NEXT: btl %esi, %edi76; X64-NEXT: jae .LBB1_177; X64-NEXT: # %bb.2: # %UnifiedReturnBlock78; X64-NEXT: retq79; X64-NEXT: .LBB1_1: # %bb80; X64-NEXT: pushq %rax81; X64-NEXT: callq foo@PLT82; X64-NEXT: popq %rax83; X64-NEXT: retq84entry:85 %tmp29 = lshr i32 %x, %n86 %tmp3 = and i32 1, %tmp2987 %tmp4 = icmp eq i32 %tmp3, 088 br i1 %tmp4, label %bb, label %UnifiedReturnBlock89 90bb:91 call void @foo()92 ret void93 94UnifiedReturnBlock:95 ret void96}97 98define void @atest2(i32 %x, i32 %n) nounwind {99; X86-LABEL: atest2:100; X86: # %bb.0: # %entry101; X86-NEXT: movl {{[0-9]+}}(%esp), %eax102; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx103; X86-NEXT: btl %ecx, %eax104; X86-NEXT: jb .LBB2_2105; X86-NEXT: # %bb.1: # %bb106; X86-NEXT: calll foo@PLT107; X86-NEXT: .LBB2_2: # %UnifiedReturnBlock108; X86-NEXT: retl109;110; X64-LABEL: atest2:111; X64: # %bb.0: # %entry112; X64-NEXT: btl %esi, %edi113; X64-NEXT: jb .LBB2_2114; X64-NEXT: # %bb.1: # %bb115; X64-NEXT: pushq %rax116; X64-NEXT: callq foo@PLT117; X64-NEXT: popq %rax118; X64-NEXT: .LBB2_2: # %UnifiedReturnBlock119; X64-NEXT: retq120entry:121 %tmp29 = ashr i32 %x, %n122 %tmp3 = and i32 %tmp29, 1123 %tmp4 = icmp eq i32 %tmp3, 0124 br i1 %tmp4, label %bb, label %UnifiedReturnBlock125 126bb:127 call void @foo()128 ret void129 130UnifiedReturnBlock:131 ret void132}133 134define void @atest2b(i32 %x, i32 %n) nounwind {135; X86-LABEL: atest2b:136; X86: # %bb.0: # %entry137; X86-NEXT: movl {{[0-9]+}}(%esp), %eax138; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx139; X86-NEXT: btl %ecx, %eax140; X86-NEXT: jae .LBB3_1141; X86-NEXT: # %bb.2: # %UnifiedReturnBlock142; X86-NEXT: retl143; X86-NEXT: .LBB3_1: # %bb144; X86-NEXT: calll foo@PLT145; X86-NEXT: retl146;147; X64-LABEL: atest2b:148; X64: # %bb.0: # %entry149; X64-NEXT: btl %esi, %edi150; X64-NEXT: jae .LBB3_1151; X64-NEXT: # %bb.2: # %UnifiedReturnBlock152; X64-NEXT: retq153; X64-NEXT: .LBB3_1: # %bb154; X64-NEXT: pushq %rax155; X64-NEXT: callq foo@PLT156; X64-NEXT: popq %rax157; X64-NEXT: retq158entry:159 %tmp29 = ashr i32 %x, %n160 %tmp3 = and i32 1, %tmp29161 %tmp4 = icmp eq i32 %tmp3, 0162 br i1 %tmp4, label %bb, label %UnifiedReturnBlock163 164bb:165 call void @foo()166 ret void167 168UnifiedReturnBlock:169 ret void170}171 172define void @test3(i32 %x, i32 %n) nounwind {173; X86-LABEL: test3:174; X86: # %bb.0: # %entry175; X86-NEXT: movl {{[0-9]+}}(%esp), %eax176; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx177; X86-NEXT: btl %ecx, %eax178; X86-NEXT: jae .LBB4_1179; X86-NEXT: # %bb.2: # %UnifiedReturnBlock180; X86-NEXT: retl181; X86-NEXT: .LBB4_1: # %bb182; X86-NEXT: calll foo@PLT183; X86-NEXT: retl184;185; X64-LABEL: test3:186; X64: # %bb.0: # %entry187; X64-NEXT: btl %esi, %edi188; X64-NEXT: jae .LBB4_1189; X64-NEXT: # %bb.2: # %UnifiedReturnBlock190; X64-NEXT: retq191; X64-NEXT: .LBB4_1: # %bb192; X64-NEXT: pushq %rax193; X64-NEXT: callq foo@PLT194; X64-NEXT: popq %rax195; X64-NEXT: retq196entry:197 %tmp29 = shl i32 1, %n198 %tmp3 = and i32 %tmp29, %x199 %tmp4 = icmp eq i32 %tmp3, 0200 br i1 %tmp4, label %bb, label %UnifiedReturnBlock201 202bb:203 call void @foo()204 ret void205 206UnifiedReturnBlock:207 ret void208}209 210define void @test3b(i32 %x, i32 %n) nounwind {211; X86-LABEL: test3b:212; X86: # %bb.0: # %entry213; X86-NEXT: movl {{[0-9]+}}(%esp), %eax214; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx215; X86-NEXT: btl %ecx, %eax216; X86-NEXT: jae .LBB5_1217; X86-NEXT: # %bb.2: # %UnifiedReturnBlock218; X86-NEXT: retl219; X86-NEXT: .LBB5_1: # %bb220; X86-NEXT: calll foo@PLT221; X86-NEXT: retl222;223; X64-LABEL: test3b:224; X64: # %bb.0: # %entry225; X64-NEXT: btl %esi, %edi226; X64-NEXT: jae .LBB5_1227; X64-NEXT: # %bb.2: # %UnifiedReturnBlock228; X64-NEXT: retq229; X64-NEXT: .LBB5_1: # %bb230; X64-NEXT: pushq %rax231; X64-NEXT: callq foo@PLT232; X64-NEXT: popq %rax233; X64-NEXT: retq234entry:235 %tmp29 = shl i32 1, %n236 %tmp3 = and i32 %x, %tmp29237 %tmp4 = icmp eq i32 %tmp3, 0238 br i1 %tmp4, label %bb, label %UnifiedReturnBlock239 240bb:241 call void @foo()242 ret void243 244UnifiedReturnBlock:245 ret void246}247 248define void @testne2(i32 %x, i32 %n) nounwind {249; X86-LABEL: testne2:250; X86: # %bb.0: # %entry251; X86-NEXT: movl {{[0-9]+}}(%esp), %eax252; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx253; X86-NEXT: btl %ecx, %eax254; X86-NEXT: jae .LBB6_2255; X86-NEXT: # %bb.1: # %bb256; X86-NEXT: calll foo@PLT257; X86-NEXT: .LBB6_2: # %UnifiedReturnBlock258; X86-NEXT: retl259;260; X64-LABEL: testne2:261; X64: # %bb.0: # %entry262; X64-NEXT: btl %esi, %edi263; X64-NEXT: jae .LBB6_2264; X64-NEXT: # %bb.1: # %bb265; X64-NEXT: pushq %rax266; X64-NEXT: callq foo@PLT267; X64-NEXT: popq %rax268; X64-NEXT: .LBB6_2: # %UnifiedReturnBlock269; X64-NEXT: retq270entry:271 %tmp29 = lshr i32 %x, %n272 %tmp3 = and i32 %tmp29, 1273 %tmp4 = icmp ne i32 %tmp3, 0274 br i1 %tmp4, label %bb, label %UnifiedReturnBlock275 276bb:277 call void @foo()278 ret void279 280UnifiedReturnBlock:281 ret void282}283 284define void @testne2b(i32 %x, i32 %n) nounwind {285; X86-LABEL: testne2b:286; X86: # %bb.0: # %entry287; X86-NEXT: movl {{[0-9]+}}(%esp), %eax288; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx289; X86-NEXT: btl %ecx, %eax290; X86-NEXT: jae .LBB7_2291; X86-NEXT: # %bb.1: # %bb292; X86-NEXT: calll foo@PLT293; X86-NEXT: .LBB7_2: # %UnifiedReturnBlock294; X86-NEXT: retl295;296; X64-LABEL: testne2b:297; X64: # %bb.0: # %entry298; X64-NEXT: btl %esi, %edi299; X64-NEXT: jae .LBB7_2300; X64-NEXT: # %bb.1: # %bb301; X64-NEXT: pushq %rax302; X64-NEXT: callq foo@PLT303; X64-NEXT: popq %rax304; X64-NEXT: .LBB7_2: # %UnifiedReturnBlock305; X64-NEXT: retq306entry:307 %tmp29 = lshr i32 %x, %n308 %tmp3 = and i32 1, %tmp29309 %tmp4 = icmp ne i32 %tmp3, 0310 br i1 %tmp4, label %bb, label %UnifiedReturnBlock311 312bb:313 call void @foo()314 ret void315 316UnifiedReturnBlock:317 ret void318}319 320define void @atestne2(i32 %x, i32 %n) nounwind {321; X86-LABEL: atestne2:322; X86: # %bb.0: # %entry323; X86-NEXT: movl {{[0-9]+}}(%esp), %eax324; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx325; X86-NEXT: btl %ecx, %eax326; X86-NEXT: jae .LBB8_2327; X86-NEXT: # %bb.1: # %bb328; X86-NEXT: calll foo@PLT329; X86-NEXT: .LBB8_2: # %UnifiedReturnBlock330; X86-NEXT: retl331;332; X64-LABEL: atestne2:333; X64: # %bb.0: # %entry334; X64-NEXT: btl %esi, %edi335; X64-NEXT: jae .LBB8_2336; X64-NEXT: # %bb.1: # %bb337; X64-NEXT: pushq %rax338; X64-NEXT: callq foo@PLT339; X64-NEXT: popq %rax340; X64-NEXT: .LBB8_2: # %UnifiedReturnBlock341; X64-NEXT: retq342entry:343 %tmp29 = ashr i32 %x, %n344 %tmp3 = and i32 %tmp29, 1345 %tmp4 = icmp ne i32 %tmp3, 0346 br i1 %tmp4, label %bb, label %UnifiedReturnBlock347 348bb:349 call void @foo()350 ret void351 352UnifiedReturnBlock:353 ret void354}355 356define void @atestne2b(i32 %x, i32 %n) nounwind {357; X86-LABEL: atestne2b:358; X86: # %bb.0: # %entry359; X86-NEXT: movl {{[0-9]+}}(%esp), %eax360; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx361; X86-NEXT: btl %ecx, %eax362; X86-NEXT: jae .LBB9_2363; X86-NEXT: # %bb.1: # %bb364; X86-NEXT: calll foo@PLT365; X86-NEXT: .LBB9_2: # %UnifiedReturnBlock366; X86-NEXT: retl367;368; X64-LABEL: atestne2b:369; X64: # %bb.0: # %entry370; X64-NEXT: btl %esi, %edi371; X64-NEXT: jae .LBB9_2372; X64-NEXT: # %bb.1: # %bb373; X64-NEXT: pushq %rax374; X64-NEXT: callq foo@PLT375; X64-NEXT: popq %rax376; X64-NEXT: .LBB9_2: # %UnifiedReturnBlock377; X64-NEXT: retq378entry:379 %tmp29 = ashr i32 %x, %n380 %tmp3 = and i32 1, %tmp29381 %tmp4 = icmp ne i32 %tmp3, 0382 br i1 %tmp4, label %bb, label %UnifiedReturnBlock383 384bb:385 call void @foo()386 ret void387 388UnifiedReturnBlock:389 ret void390}391 392define void @testne3(i32 %x, i32 %n) nounwind {393; X86-LABEL: testne3:394; X86: # %bb.0: # %entry395; X86-NEXT: movl {{[0-9]+}}(%esp), %eax396; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx397; X86-NEXT: btl %ecx, %eax398; X86-NEXT: jae .LBB10_2399; X86-NEXT: # %bb.1: # %bb400; X86-NEXT: calll foo@PLT401; X86-NEXT: .LBB10_2: # %UnifiedReturnBlock402; X86-NEXT: retl403;404; X64-LABEL: testne3:405; X64: # %bb.0: # %entry406; X64-NEXT: btl %esi, %edi407; X64-NEXT: jae .LBB10_2408; X64-NEXT: # %bb.1: # %bb409; X64-NEXT: pushq %rax410; X64-NEXT: callq foo@PLT411; X64-NEXT: popq %rax412; X64-NEXT: .LBB10_2: # %UnifiedReturnBlock413; X64-NEXT: retq414entry:415 %tmp29 = shl i32 1, %n416 %tmp3 = and i32 %tmp29, %x417 %tmp4 = icmp ne i32 %tmp3, 0418 br i1 %tmp4, label %bb, label %UnifiedReturnBlock419 420bb:421 call void @foo()422 ret void423 424UnifiedReturnBlock:425 ret void426}427 428define void @testne3b(i32 %x, i32 %n) nounwind {429; X86-LABEL: testne3b:430; X86: # %bb.0: # %entry431; X86-NEXT: movl {{[0-9]+}}(%esp), %eax432; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx433; X86-NEXT: btl %ecx, %eax434; X86-NEXT: jae .LBB11_2435; X86-NEXT: # %bb.1: # %bb436; X86-NEXT: calll foo@PLT437; X86-NEXT: .LBB11_2: # %UnifiedReturnBlock438; X86-NEXT: retl439;440; X64-LABEL: testne3b:441; X64: # %bb.0: # %entry442; X64-NEXT: btl %esi, %edi443; X64-NEXT: jae .LBB11_2444; X64-NEXT: # %bb.1: # %bb445; X64-NEXT: pushq %rax446; X64-NEXT: callq foo@PLT447; X64-NEXT: popq %rax448; X64-NEXT: .LBB11_2: # %UnifiedReturnBlock449; X64-NEXT: retq450entry:451 %tmp29 = shl i32 1, %n452 %tmp3 = and i32 %x, %tmp29453 %tmp4 = icmp ne i32 %tmp3, 0454 br i1 %tmp4, label %bb, label %UnifiedReturnBlock455 456bb:457 call void @foo()458 ret void459 460UnifiedReturnBlock:461 ret void462}463 464define void @query2(i32 %x, i32 %n) nounwind {465; X86-LABEL: query2:466; X86: # %bb.0: # %entry467; X86-NEXT: movl {{[0-9]+}}(%esp), %eax468; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx469; X86-NEXT: btl %ecx, %eax470; X86-NEXT: jae .LBB12_2471; X86-NEXT: # %bb.1: # %bb472; X86-NEXT: calll foo@PLT473; X86-NEXT: .LBB12_2: # %UnifiedReturnBlock474; X86-NEXT: retl475;476; X64-LABEL: query2:477; X64: # %bb.0: # %entry478; X64-NEXT: btl %esi, %edi479; X64-NEXT: jae .LBB12_2480; X64-NEXT: # %bb.1: # %bb481; X64-NEXT: pushq %rax482; X64-NEXT: callq foo@PLT483; X64-NEXT: popq %rax484; X64-NEXT: .LBB12_2: # %UnifiedReturnBlock485; X64-NEXT: retq486entry:487 %tmp29 = lshr i32 %x, %n488 %tmp3 = and i32 %tmp29, 1489 %tmp4 = icmp eq i32 %tmp3, 1490 br i1 %tmp4, label %bb, label %UnifiedReturnBlock491 492bb:493 call void @foo()494 ret void495 496UnifiedReturnBlock:497 ret void498}499 500define void @query2b(i32 %x, i32 %n) nounwind {501; X86-LABEL: query2b:502; X86: # %bb.0: # %entry503; X86-NEXT: movl {{[0-9]+}}(%esp), %eax504; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx505; X86-NEXT: btl %ecx, %eax506; X86-NEXT: jae .LBB13_2507; X86-NEXT: # %bb.1: # %bb508; X86-NEXT: calll foo@PLT509; X86-NEXT: .LBB13_2: # %UnifiedReturnBlock510; X86-NEXT: retl511;512; X64-LABEL: query2b:513; X64: # %bb.0: # %entry514; X64-NEXT: btl %esi, %edi515; X64-NEXT: jae .LBB13_2516; X64-NEXT: # %bb.1: # %bb517; X64-NEXT: pushq %rax518; X64-NEXT: callq foo@PLT519; X64-NEXT: popq %rax520; X64-NEXT: .LBB13_2: # %UnifiedReturnBlock521; X64-NEXT: retq522entry:523 %tmp29 = lshr i32 %x, %n524 %tmp3 = and i32 1, %tmp29525 %tmp4 = icmp eq i32 %tmp3, 1526 br i1 %tmp4, label %bb, label %UnifiedReturnBlock527 528bb:529 call void @foo()530 ret void531 532UnifiedReturnBlock:533 ret void534}535 536define void @aquery2(i32 %x, i32 %n) nounwind {537; X86-LABEL: aquery2:538; X86: # %bb.0: # %entry539; X86-NEXT: movl {{[0-9]+}}(%esp), %eax540; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx541; X86-NEXT: btl %ecx, %eax542; X86-NEXT: jae .LBB14_2543; X86-NEXT: # %bb.1: # %bb544; X86-NEXT: calll foo@PLT545; X86-NEXT: .LBB14_2: # %UnifiedReturnBlock546; X86-NEXT: retl547;548; X64-LABEL: aquery2:549; X64: # %bb.0: # %entry550; X64-NEXT: btl %esi, %edi551; X64-NEXT: jae .LBB14_2552; X64-NEXT: # %bb.1: # %bb553; X64-NEXT: pushq %rax554; X64-NEXT: callq foo@PLT555; X64-NEXT: popq %rax556; X64-NEXT: .LBB14_2: # %UnifiedReturnBlock557; X64-NEXT: retq558entry:559 %tmp29 = ashr i32 %x, %n560 %tmp3 = and i32 %tmp29, 1561 %tmp4 = icmp eq i32 %tmp3, 1562 br i1 %tmp4, label %bb, label %UnifiedReturnBlock563 564bb:565 call void @foo()566 ret void567 568UnifiedReturnBlock:569 ret void570}571 572define void @aquery2b(i32 %x, i32 %n) nounwind {573; X86-LABEL: aquery2b:574; X86: # %bb.0: # %entry575; X86-NEXT: movl {{[0-9]+}}(%esp), %eax576; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx577; X86-NEXT: btl %ecx, %eax578; X86-NEXT: jae .LBB15_2579; X86-NEXT: # %bb.1: # %bb580; X86-NEXT: calll foo@PLT581; X86-NEXT: .LBB15_2: # %UnifiedReturnBlock582; X86-NEXT: retl583;584; X64-LABEL: aquery2b:585; X64: # %bb.0: # %entry586; X64-NEXT: btl %esi, %edi587; X64-NEXT: jae .LBB15_2588; X64-NEXT: # %bb.1: # %bb589; X64-NEXT: pushq %rax590; X64-NEXT: callq foo@PLT591; X64-NEXT: popq %rax592; X64-NEXT: .LBB15_2: # %UnifiedReturnBlock593; X64-NEXT: retq594entry:595 %tmp29 = ashr i32 %x, %n596 %tmp3 = and i32 1, %tmp29597 %tmp4 = icmp eq i32 %tmp3, 1598 br i1 %tmp4, label %bb, label %UnifiedReturnBlock599 600bb:601 call void @foo()602 ret void603 604UnifiedReturnBlock:605 ret void606}607 608define void @query3(i32 %x, i32 %n) nounwind {609; X86-LABEL: query3:610; X86: # %bb.0: # %entry611; X86-NEXT: movl {{[0-9]+}}(%esp), %eax612; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx613; X86-NEXT: btl %ecx, %eax614; X86-NEXT: jae .LBB16_2615; X86-NEXT: # %bb.1: # %bb616; X86-NEXT: calll foo@PLT617; X86-NEXT: .LBB16_2: # %UnifiedReturnBlock618; X86-NEXT: retl619;620; X64-LABEL: query3:621; X64: # %bb.0: # %entry622; X64-NEXT: btl %esi, %edi623; X64-NEXT: jae .LBB16_2624; X64-NEXT: # %bb.1: # %bb625; X64-NEXT: pushq %rax626; X64-NEXT: callq foo@PLT627; X64-NEXT: popq %rax628; X64-NEXT: .LBB16_2: # %UnifiedReturnBlock629; X64-NEXT: retq630entry:631 %tmp29 = shl i32 1, %n632 %tmp3 = and i32 %tmp29, %x633 %tmp4 = icmp eq i32 %tmp3, %tmp29634 br i1 %tmp4, label %bb, label %UnifiedReturnBlock635 636bb:637 call void @foo()638 ret void639 640UnifiedReturnBlock:641 ret void642}643 644define void @query3b(i32 %x, i32 %n) nounwind {645; X86-LABEL: query3b:646; X86: # %bb.0: # %entry647; X86-NEXT: movl {{[0-9]+}}(%esp), %eax648; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx649; X86-NEXT: btl %ecx, %eax650; X86-NEXT: jae .LBB17_2651; X86-NEXT: # %bb.1: # %bb652; X86-NEXT: calll foo@PLT653; X86-NEXT: .LBB17_2: # %UnifiedReturnBlock654; X86-NEXT: retl655;656; X64-LABEL: query3b:657; X64: # %bb.0: # %entry658; X64-NEXT: btl %esi, %edi659; X64-NEXT: jae .LBB17_2660; X64-NEXT: # %bb.1: # %bb661; X64-NEXT: pushq %rax662; X64-NEXT: callq foo@PLT663; X64-NEXT: popq %rax664; X64-NEXT: .LBB17_2: # %UnifiedReturnBlock665; X64-NEXT: retq666entry:667 %tmp29 = shl i32 1, %n668 %tmp3 = and i32 %x, %tmp29669 %tmp4 = icmp eq i32 %tmp3, %tmp29670 br i1 %tmp4, label %bb, label %UnifiedReturnBlock671 672bb:673 call void @foo()674 ret void675 676UnifiedReturnBlock:677 ret void678}679 680define void @query3x(i32 %x, i32 %n) nounwind {681; X86-LABEL: query3x:682; X86: # %bb.0: # %entry683; X86-NEXT: movl {{[0-9]+}}(%esp), %eax684; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx685; X86-NEXT: btl %ecx, %eax686; X86-NEXT: jae .LBB18_2687; X86-NEXT: # %bb.1: # %bb688; X86-NEXT: calll foo@PLT689; X86-NEXT: .LBB18_2: # %UnifiedReturnBlock690; X86-NEXT: retl691;692; X64-LABEL: query3x:693; X64: # %bb.0: # %entry694; X64-NEXT: btl %esi, %edi695; X64-NEXT: jae .LBB18_2696; X64-NEXT: # %bb.1: # %bb697; X64-NEXT: pushq %rax698; X64-NEXT: callq foo@PLT699; X64-NEXT: popq %rax700; X64-NEXT: .LBB18_2: # %UnifiedReturnBlock701; X64-NEXT: retq702entry:703 %tmp29 = shl i32 1, %n704 %tmp3 = and i32 %tmp29, %x705 %tmp4 = icmp eq i32 %tmp29, %tmp3706 br i1 %tmp4, label %bb, label %UnifiedReturnBlock707 708bb:709 call void @foo()710 ret void711 712UnifiedReturnBlock:713 ret void714}715 716define void @query3bx(i32 %x, i32 %n) nounwind {717; X86-LABEL: query3bx:718; X86: # %bb.0: # %entry719; X86-NEXT: movl {{[0-9]+}}(%esp), %eax720; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx721; X86-NEXT: btl %ecx, %eax722; X86-NEXT: jae .LBB19_2723; X86-NEXT: # %bb.1: # %bb724; X86-NEXT: calll foo@PLT725; X86-NEXT: .LBB19_2: # %UnifiedReturnBlock726; X86-NEXT: retl727;728; X64-LABEL: query3bx:729; X64: # %bb.0: # %entry730; X64-NEXT: btl %esi, %edi731; X64-NEXT: jae .LBB19_2732; X64-NEXT: # %bb.1: # %bb733; X64-NEXT: pushq %rax734; X64-NEXT: callq foo@PLT735; X64-NEXT: popq %rax736; X64-NEXT: .LBB19_2: # %UnifiedReturnBlock737; X64-NEXT: retq738entry:739 %tmp29 = shl i32 1, %n740 %tmp3 = and i32 %x, %tmp29741 %tmp4 = icmp eq i32 %tmp29, %tmp3742 br i1 %tmp4, label %bb, label %UnifiedReturnBlock743 744bb:745 call void @foo()746 ret void747 748UnifiedReturnBlock:749 ret void750}751 752define void @queryne2(i32 %x, i32 %n) nounwind {753; X86-LABEL: queryne2:754; X86: # %bb.0: # %entry755; X86-NEXT: movl {{[0-9]+}}(%esp), %eax756; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx757; X86-NEXT: btl %ecx, %eax758; X86-NEXT: jb .LBB20_2759; X86-NEXT: # %bb.1: # %bb760; X86-NEXT: calll foo@PLT761; X86-NEXT: .LBB20_2: # %UnifiedReturnBlock762; X86-NEXT: retl763;764; X64-LABEL: queryne2:765; X64: # %bb.0: # %entry766; X64-NEXT: btl %esi, %edi767; X64-NEXT: jb .LBB20_2768; X64-NEXT: # %bb.1: # %bb769; X64-NEXT: pushq %rax770; X64-NEXT: callq foo@PLT771; X64-NEXT: popq %rax772; X64-NEXT: .LBB20_2: # %UnifiedReturnBlock773; X64-NEXT: retq774entry:775 %tmp29 = lshr i32 %x, %n776 %tmp3 = and i32 %tmp29, 1777 %tmp4 = icmp ne i32 %tmp3, 1778 br i1 %tmp4, label %bb, label %UnifiedReturnBlock779 780bb:781 call void @foo()782 ret void783 784UnifiedReturnBlock:785 ret void786}787 788define void @queryne2b(i32 %x, i32 %n) nounwind {789; X86-LABEL: queryne2b:790; X86: # %bb.0: # %entry791; X86-NEXT: movl {{[0-9]+}}(%esp), %eax792; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx793; X86-NEXT: btl %ecx, %eax794; X86-NEXT: jb .LBB21_2795; X86-NEXT: # %bb.1: # %bb796; X86-NEXT: calll foo@PLT797; X86-NEXT: .LBB21_2: # %UnifiedReturnBlock798; X86-NEXT: retl799;800; X64-LABEL: queryne2b:801; X64: # %bb.0: # %entry802; X64-NEXT: btl %esi, %edi803; X64-NEXT: jb .LBB21_2804; X64-NEXT: # %bb.1: # %bb805; X64-NEXT: pushq %rax806; X64-NEXT: callq foo@PLT807; X64-NEXT: popq %rax808; X64-NEXT: .LBB21_2: # %UnifiedReturnBlock809; X64-NEXT: retq810entry:811 %tmp29 = lshr i32 %x, %n812 %tmp3 = and i32 1, %tmp29813 %tmp4 = icmp ne i32 %tmp3, 1814 br i1 %tmp4, label %bb, label %UnifiedReturnBlock815 816bb:817 call void @foo()818 ret void819 820UnifiedReturnBlock:821 ret void822}823 824define void @aqueryne2(i32 %x, i32 %n) nounwind {825; X86-LABEL: aqueryne2:826; X86: # %bb.0: # %entry827; X86-NEXT: movl {{[0-9]+}}(%esp), %eax828; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx829; X86-NEXT: btl %ecx, %eax830; X86-NEXT: jb .LBB22_2831; X86-NEXT: # %bb.1: # %bb832; X86-NEXT: calll foo@PLT833; X86-NEXT: .LBB22_2: # %UnifiedReturnBlock834; X86-NEXT: retl835;836; X64-LABEL: aqueryne2:837; X64: # %bb.0: # %entry838; X64-NEXT: btl %esi, %edi839; X64-NEXT: jb .LBB22_2840; X64-NEXT: # %bb.1: # %bb841; X64-NEXT: pushq %rax842; X64-NEXT: callq foo@PLT843; X64-NEXT: popq %rax844; X64-NEXT: .LBB22_2: # %UnifiedReturnBlock845; X64-NEXT: retq846entry:847 %tmp29 = ashr i32 %x, %n848 %tmp3 = and i32 %tmp29, 1849 %tmp4 = icmp ne i32 %tmp3, 1850 br i1 %tmp4, label %bb, label %UnifiedReturnBlock851 852bb:853 call void @foo()854 ret void855 856UnifiedReturnBlock:857 ret void858}859 860define void @aqueryne2b(i32 %x, i32 %n) nounwind {861; X86-LABEL: aqueryne2b:862; X86: # %bb.0: # %entry863; X86-NEXT: movl {{[0-9]+}}(%esp), %eax864; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx865; X86-NEXT: btl %ecx, %eax866; X86-NEXT: jb .LBB23_2867; X86-NEXT: # %bb.1: # %bb868; X86-NEXT: calll foo@PLT869; X86-NEXT: .LBB23_2: # %UnifiedReturnBlock870; X86-NEXT: retl871;872; X64-LABEL: aqueryne2b:873; X64: # %bb.0: # %entry874; X64-NEXT: btl %esi, %edi875; X64-NEXT: jb .LBB23_2876; X64-NEXT: # %bb.1: # %bb877; X64-NEXT: pushq %rax878; X64-NEXT: callq foo@PLT879; X64-NEXT: popq %rax880; X64-NEXT: .LBB23_2: # %UnifiedReturnBlock881; X64-NEXT: retq882entry:883 %tmp29 = ashr i32 %x, %n884 %tmp3 = and i32 1, %tmp29885 %tmp4 = icmp ne i32 %tmp3, 1886 br i1 %tmp4, label %bb, label %UnifiedReturnBlock887 888bb:889 call void @foo()890 ret void891 892UnifiedReturnBlock:893 ret void894}895 896define void @queryne3(i32 %x, i32 %n) nounwind {897; X86-LABEL: queryne3:898; X86: # %bb.0: # %entry899; X86-NEXT: movl {{[0-9]+}}(%esp), %eax900; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx901; X86-NEXT: btl %ecx, %eax902; X86-NEXT: jb .LBB24_2903; X86-NEXT: # %bb.1: # %bb904; X86-NEXT: calll foo@PLT905; X86-NEXT: .LBB24_2: # %UnifiedReturnBlock906; X86-NEXT: retl907;908; X64-LABEL: queryne3:909; X64: # %bb.0: # %entry910; X64-NEXT: btl %esi, %edi911; X64-NEXT: jb .LBB24_2912; X64-NEXT: # %bb.1: # %bb913; X64-NEXT: pushq %rax914; X64-NEXT: callq foo@PLT915; X64-NEXT: popq %rax916; X64-NEXT: .LBB24_2: # %UnifiedReturnBlock917; X64-NEXT: retq918entry:919 %tmp29 = shl i32 1, %n920 %tmp3 = and i32 %tmp29, %x921 %tmp4 = icmp ne i32 %tmp3, %tmp29922 br i1 %tmp4, label %bb, label %UnifiedReturnBlock923 924bb:925 call void @foo()926 ret void927 928UnifiedReturnBlock:929 ret void930}931 932define void @queryne3b(i32 %x, i32 %n) nounwind {933; X86-LABEL: queryne3b:934; X86: # %bb.0: # %entry935; X86-NEXT: movl {{[0-9]+}}(%esp), %eax936; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx937; X86-NEXT: btl %ecx, %eax938; X86-NEXT: jb .LBB25_2939; X86-NEXT: # %bb.1: # %bb940; X86-NEXT: calll foo@PLT941; X86-NEXT: .LBB25_2: # %UnifiedReturnBlock942; X86-NEXT: retl943;944; X64-LABEL: queryne3b:945; X64: # %bb.0: # %entry946; X64-NEXT: btl %esi, %edi947; X64-NEXT: jb .LBB25_2948; X64-NEXT: # %bb.1: # %bb949; X64-NEXT: pushq %rax950; X64-NEXT: callq foo@PLT951; X64-NEXT: popq %rax952; X64-NEXT: .LBB25_2: # %UnifiedReturnBlock953; X64-NEXT: retq954entry:955 %tmp29 = shl i32 1, %n956 %tmp3 = and i32 %x, %tmp29957 %tmp4 = icmp ne i32 %tmp3, %tmp29958 br i1 %tmp4, label %bb, label %UnifiedReturnBlock959 960bb:961 call void @foo()962 ret void963 964UnifiedReturnBlock:965 ret void966}967 968define void @queryne3x(i32 %x, i32 %n) nounwind {969; X86-LABEL: queryne3x:970; X86: # %bb.0: # %entry971; X86-NEXT: movl {{[0-9]+}}(%esp), %eax972; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx973; X86-NEXT: btl %ecx, %eax974; X86-NEXT: jb .LBB26_2975; X86-NEXT: # %bb.1: # %bb976; X86-NEXT: calll foo@PLT977; X86-NEXT: .LBB26_2: # %UnifiedReturnBlock978; X86-NEXT: retl979;980; X64-LABEL: queryne3x:981; X64: # %bb.0: # %entry982; X64-NEXT: btl %esi, %edi983; X64-NEXT: jb .LBB26_2984; X64-NEXT: # %bb.1: # %bb985; X64-NEXT: pushq %rax986; X64-NEXT: callq foo@PLT987; X64-NEXT: popq %rax988; X64-NEXT: .LBB26_2: # %UnifiedReturnBlock989; X64-NEXT: retq990entry:991 %tmp29 = shl i32 1, %n992 %tmp3 = and i32 %tmp29, %x993 %tmp4 = icmp ne i32 %tmp29, %tmp3994 br i1 %tmp4, label %bb, label %UnifiedReturnBlock995 996bb:997 call void @foo()998 ret void999 1000UnifiedReturnBlock:1001 ret void1002}1003 1004define void @queryne3bx(i32 %x, i32 %n) nounwind {1005; X86-LABEL: queryne3bx:1006; X86: # %bb.0: # %entry1007; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1008; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1009; X86-NEXT: btl %ecx, %eax1010; X86-NEXT: jb .LBB27_21011; X86-NEXT: # %bb.1: # %bb1012; X86-NEXT: calll foo@PLT1013; X86-NEXT: .LBB27_2: # %UnifiedReturnBlock1014; X86-NEXT: retl1015;1016; X64-LABEL: queryne3bx:1017; X64: # %bb.0: # %entry1018; X64-NEXT: btl %esi, %edi1019; X64-NEXT: jb .LBB27_21020; X64-NEXT: # %bb.1: # %bb1021; X64-NEXT: pushq %rax1022; X64-NEXT: callq foo@PLT1023; X64-NEXT: popq %rax1024; X64-NEXT: .LBB27_2: # %UnifiedReturnBlock1025; X64-NEXT: retq1026entry:1027 %tmp29 = shl i32 1, %n1028 %tmp3 = and i32 %x, %tmp291029 %tmp4 = icmp ne i32 %tmp29, %tmp31030 br i1 %tmp4, label %bb, label %UnifiedReturnBlock1031 1032bb:1033 call void @foo()1034 ret void1035 1036UnifiedReturnBlock:1037 ret void1038}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), %eax1046; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1047; X86-NEXT: btl %ecx, %eax1048; X86-NEXT: setae %al1049; X86-NEXT: retl1050;1051; X64-LABEL: invert:1052; X64: # %bb.0:1053; X64-NEXT: btl %esi, %edi1054; X64-NEXT: setae %al1055; X64-NEXT: retq1056 %neg = xor i32 %flags, -11057 %shl = shl i32 1, %flag1058 %and = and i32 %shl, %neg1059 %tobool = icmp ne i32 %and, 01060 ret i1 %tobool1061}1062 1063define zeroext i1 @extend(i32 %bit, i64 %bits) {1064; X86-LABEL: extend:1065; X86: # %bb.0: # %entry1066; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1067; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1068; X86-NEXT: btl %ecx, %eax1069; X86-NEXT: setb %al1070; X86-NEXT: retl1071;1072; X64-LABEL: extend:1073; X64: # %bb.0: # %entry1074; X64-NEXT: btl %edi, %esi1075; X64-NEXT: setb %al1076; X64-NEXT: retq1077entry:1078 %and = and i32 %bit, 311079 %sh_prom = zext i32 %and to i641080 %shl = shl i64 1, %sh_prom1081 %and1 = and i64 %shl, %bits1082 %tobool = icmp ne i64 %and1, 01083 ret i1 %tobool1084}1085 1086; TODO: BT fails to look through to demanded bits as c%32 has more than one use.1087; void demanded_i32(int *a, int *b, unsigned c) {1088; if ((a[c/32] >> (c % 32)) & 1)1089; b[c/32] |= 1 << (c % 32);1090; }1091define void @demanded_i32(ptr nocapture readonly, ptr nocapture, i32) nounwind {1092; X86-LABEL: demanded_i32:1093; X86: # %bb.0:1094; X86-NEXT: pushl %esi1095; X86-NEXT: movl {{[0-9]+}}(%esp), %edx1096; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1097; X86-NEXT: movl %ecx, %eax1098; X86-NEXT: shrl $5, %eax1099; X86-NEXT: movl (%edx,%eax,4), %esi1100; X86-NEXT: movl $1, %edx1101; X86-NEXT: shll %cl, %edx1102; X86-NEXT: btl %ecx, %esi1103; X86-NEXT: jae .LBB30_21104; X86-NEXT: # %bb.1:1105; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1106; X86-NEXT: orl %edx, (%ecx,%eax,4)1107; X86-NEXT: .LBB30_2:1108; X86-NEXT: popl %esi1109; X86-NEXT: retl1110;1111; X64-LABEL: demanded_i32:1112; X64: # %bb.0:1113; X64-NEXT: movl %edx, %ecx1114; X64-NEXT: movl %edx, %eax1115; X64-NEXT: shrl $5, %eax1116; X64-NEXT: movl (%rdi,%rax,4), %edi1117; X64-NEXT: movl $1, %edx1118; X64-NEXT: shll %cl, %edx1119; X64-NEXT: btl %ecx, %edi1120; X64-NEXT: jae .LBB30_21121; X64-NEXT: # %bb.1:1122; X64-NEXT: orl %edx, (%rsi,%rax,4)1123; X64-NEXT: .LBB30_2:1124; X64-NEXT: retq1125 %4 = lshr i32 %2, 51126 %5 = zext i32 %4 to i641127 %6 = getelementptr inbounds i32, ptr %0, i64 %51128 %7 = load i32, ptr %6, align 41129 %8 = and i32 %2, 311130 %9 = shl i32 1, %81131 %10 = and i32 %7, %91132 %11 = icmp eq i32 %10, 01133 br i1 %11, label %16, label %121134 1135; <label>:12:1136 %13 = getelementptr inbounds i32, ptr %1, i64 %51137 %14 = load i32, ptr %13, align 41138 %15 = or i32 %14, %91139 store i32 %15, ptr %13, align 41140 br label %161141 1142; <label>:16:1143 ret void1144}1145 1146; Make sure we can simplify bt when the shift amount has known zeros in it1147; which cause the and mask to have bits removed.1148define zeroext i1 @demanded_with_known_zeroes(i32 %bit, i32 %bits) {1149; X86-LABEL: demanded_with_known_zeroes:1150; X86: # %bb.0: # %entry1151; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax1152; X86-NEXT: shlb $2, %al1153; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1154; X86-NEXT: movzbl %al, %eax1155; X86-NEXT: btl %eax, %ecx1156; X86-NEXT: setb %al1157; X86-NEXT: retl1158;1159; X64-LABEL: demanded_with_known_zeroes:1160; X64: # %bb.0: # %entry1161; X64-NEXT: shll $2, %edi1162; X64-NEXT: btl %edi, %esi1163; X64-NEXT: setb %al1164; X64-NEXT: retq1165entry:1166 %bit2 = shl i32 %bit, 21167 %and = and i32 %bit2, 311168 %shl = shl i32 1, %and1169 %and1 = and i32 %shl, %bits1170 %tobool = icmp ne i32 %and1, 01171 ret i1 %tobool1172}1173