brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.4 KiB · c95b7bd Raw
776 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-prefixes=X86,X86-NOCMOV3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=X86,X86-CMOV4; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X645; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86-CLZ6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X64-CLZ7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X64-FASTLZCNT8; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X86-FASTLZCNT9 10declare i8 @llvm.cttz.i8(i8, i1)11declare i16 @llvm.cttz.i16(i16, i1)12declare i32 @llvm.cttz.i32(i32, i1)13declare i64 @llvm.cttz.i64(i64, i1)14 15define i8 @cttz_i8(i8 %x)  {16; X86-LABEL: cttz_i8:17; X86:       # %bb.0:18; X86-NEXT:    rep bsfl {{[0-9]+}}(%esp), %eax19; X86-NEXT:    # kill: def $al killed $al killed $eax20; X86-NEXT:    retl21;22; X64-LABEL: cttz_i8:23; X64:       # %bb.0:24; X64-NEXT:    rep bsfl %edi, %eax25; X64-NEXT:    # kill: def $al killed $al killed $eax26; X64-NEXT:    retq27;28; X86-CLZ-LABEL: cttz_i8:29; X86-CLZ:       # %bb.0:30; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax31; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax32; X86-CLZ-NEXT:    retl33;34; X64-CLZ-LABEL: cttz_i8:35; X64-CLZ:       # %bb.0:36; X64-CLZ-NEXT:    tzcntl %edi, %eax37; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax38; X64-CLZ-NEXT:    retq39;40; X64-FASTLZCNT-LABEL: cttz_i8:41; X64-FASTLZCNT:       # %bb.0:42; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax43; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax44; X64-FASTLZCNT-NEXT:    retq45;46; X86-FASTLZCNT-LABEL: cttz_i8:47; X86-FASTLZCNT:       # %bb.0:48; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax49; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax50; X86-FASTLZCNT-NEXT:    retl51  %tmp = call i8 @llvm.cttz.i8( i8 %x, i1 true )52  ret i8 %tmp53}54 55define i16 @cttz_i16(i16 %x)  {56; X86-LABEL: cttz_i16:57; X86:       # %bb.0:58; X86-NEXT:    rep bsfl {{[0-9]+}}(%esp), %eax59; X86-NEXT:    # kill: def $ax killed $ax killed $eax60; X86-NEXT:    retl61;62; X64-LABEL: cttz_i16:63; X64:       # %bb.0:64; X64-NEXT:    rep bsfl %edi, %eax65; X64-NEXT:    # kill: def $ax killed $ax killed $eax66; X64-NEXT:    retq67;68; X86-CLZ-LABEL: cttz_i16:69; X86-CLZ:       # %bb.0:70; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax71; X86-CLZ-NEXT:    # kill: def $ax killed $ax killed $eax72; X86-CLZ-NEXT:    retl73;74; X64-CLZ-LABEL: cttz_i16:75; X64-CLZ:       # %bb.0:76; X64-CLZ-NEXT:    tzcntl %edi, %eax77; X64-CLZ-NEXT:    # kill: def $ax killed $ax killed $eax78; X64-CLZ-NEXT:    retq79;80; X64-FASTLZCNT-LABEL: cttz_i16:81; X64-FASTLZCNT:       # %bb.0:82; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax83; X64-FASTLZCNT-NEXT:    # kill: def $ax killed $ax killed $eax84; X64-FASTLZCNT-NEXT:    retq85;86; X86-FASTLZCNT-LABEL: cttz_i16:87; X86-FASTLZCNT:       # %bb.0:88; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax89; X86-FASTLZCNT-NEXT:    # kill: def $ax killed $ax killed $eax90; X86-FASTLZCNT-NEXT:    retl91  %tmp = call i16 @llvm.cttz.i16( i16 %x, i1 true )92  ret i16 %tmp93}94 95define i32 @cttz_i32(i32 %x)  {96; X86-LABEL: cttz_i32:97; X86:       # %bb.0:98; X86-NEXT:    rep bsfl {{[0-9]+}}(%esp), %eax99; X86-NEXT:    retl100;101; X64-LABEL: cttz_i32:102; X64:       # %bb.0:103; X64-NEXT:    rep bsfl %edi, %eax104; X64-NEXT:    retq105;106; X86-CLZ-LABEL: cttz_i32:107; X86-CLZ:       # %bb.0:108; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax109; X86-CLZ-NEXT:    retl110;111; X64-CLZ-LABEL: cttz_i32:112; X64-CLZ:       # %bb.0:113; X64-CLZ-NEXT:    tzcntl %edi, %eax114; X64-CLZ-NEXT:    retq115;116; X64-FASTLZCNT-LABEL: cttz_i32:117; X64-FASTLZCNT:       # %bb.0:118; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax119; X64-FASTLZCNT-NEXT:    retq120;121; X86-FASTLZCNT-LABEL: cttz_i32:122; X86-FASTLZCNT:       # %bb.0:123; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax124; X86-FASTLZCNT-NEXT:    retl125  %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 true )126  ret i32 %tmp127}128 129define i64 @cttz_i64(i64 %x)  {130; X86-NOCMOV-LABEL: cttz_i64:131; X86-NOCMOV:       # %bb.0:132; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax133; X86-NOCMOV-NEXT:    testl %eax, %eax134; X86-NOCMOV-NEXT:    jne .LBB3_1135; X86-NOCMOV-NEXT:  # %bb.2:136; X86-NOCMOV-NEXT:    rep bsfl {{[0-9]+}}(%esp), %eax137; X86-NOCMOV-NEXT:    addl $32, %eax138; X86-NOCMOV-NEXT:    xorl %edx, %edx139; X86-NOCMOV-NEXT:    retl140; X86-NOCMOV-NEXT:  .LBB3_1:141; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax142; X86-NOCMOV-NEXT:    xorl %edx, %edx143; X86-NOCMOV-NEXT:    retl144;145; X86-CMOV-LABEL: cttz_i64:146; X86-CMOV:       # %bb.0:147; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx148; X86-CMOV-NEXT:    rep bsfl %ecx, %edx149; X86-CMOV-NEXT:    rep bsfl {{[0-9]+}}(%esp), %eax150; X86-CMOV-NEXT:    addl $32, %eax151; X86-CMOV-NEXT:    testl %ecx, %ecx152; X86-CMOV-NEXT:    cmovnel %edx, %eax153; X86-CMOV-NEXT:    xorl %edx, %edx154; X86-CMOV-NEXT:    retl155;156; X64-LABEL: cttz_i64:157; X64:       # %bb.0:158; X64-NEXT:    rep bsfq %rdi, %rax159; X64-NEXT:    retq160;161; X86-CLZ-LABEL: cttz_i64:162; X86-CLZ:       # %bb.0:163; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax164; X86-CLZ-NEXT:    testl %eax, %eax165; X86-CLZ-NEXT:    jne .LBB3_1166; X86-CLZ-NEXT:  # %bb.2:167; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax168; X86-CLZ-NEXT:    addl $32, %eax169; X86-CLZ-NEXT:    xorl %edx, %edx170; X86-CLZ-NEXT:    retl171; X86-CLZ-NEXT:  .LBB3_1:172; X86-CLZ-NEXT:    tzcntl %eax, %eax173; X86-CLZ-NEXT:    xorl %edx, %edx174; X86-CLZ-NEXT:    retl175;176; X64-CLZ-LABEL: cttz_i64:177; X64-CLZ:       # %bb.0:178; X64-CLZ-NEXT:    tzcntq %rdi, %rax179; X64-CLZ-NEXT:    retq180;181; X64-FASTLZCNT-LABEL: cttz_i64:182; X64-FASTLZCNT:       # %bb.0:183; X64-FASTLZCNT-NEXT:    tzcntq %rdi, %rax184; X64-FASTLZCNT-NEXT:    retq185;186; X86-FASTLZCNT-LABEL: cttz_i64:187; X86-FASTLZCNT:       # %bb.0:188; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax189; X86-FASTLZCNT-NEXT:    testl %eax, %eax190; X86-FASTLZCNT-NEXT:    jne .LBB3_1191; X86-FASTLZCNT-NEXT:  # %bb.2:192; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax193; X86-FASTLZCNT-NEXT:    addl $32, %eax194; X86-FASTLZCNT-NEXT:    xorl %edx, %edx195; X86-FASTLZCNT-NEXT:    retl196; X86-FASTLZCNT-NEXT:  .LBB3_1:197; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax198; X86-FASTLZCNT-NEXT:    xorl %edx, %edx199; X86-FASTLZCNT-NEXT:    retl200  %tmp = call i64 @llvm.cttz.i64( i64 %x, i1 true )201  ret i64 %tmp202}203 204; Promote i8 cttz to i32 and mask bit8 to prevent (slow) zero-src bsf case.205define i8 @cttz_i8_zero_test(i8 %n) {206; X86-LABEL: cttz_i8_zero_test:207; X86:       # %bb.0:208; X86-NEXT:    movl $256, %eax # imm = 0x100209; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax210; X86-NEXT:    rep bsfl %eax, %eax211; X86-NEXT:    # kill: def $al killed $al killed $eax212; X86-NEXT:    retl213;214; X64-LABEL: cttz_i8_zero_test:215; X64:       # %bb.0:216; X64-NEXT:    orl $256, %edi # imm = 0x100217; X64-NEXT:    rep bsfl %edi, %eax218; X64-NEXT:    # kill: def $al killed $al killed $eax219; X64-NEXT:    retq220;221; X86-CLZ-LABEL: cttz_i8_zero_test:222; X86-CLZ:       # %bb.0:223; X86-CLZ-NEXT:    movl $256, %eax # imm = 0x100224; X86-CLZ-NEXT:    orl {{[0-9]+}}(%esp), %eax225; X86-CLZ-NEXT:    tzcntl %eax, %eax226; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax227; X86-CLZ-NEXT:    retl228;229; X64-CLZ-LABEL: cttz_i8_zero_test:230; X64-CLZ:       # %bb.0:231; X64-CLZ-NEXT:    orl $256, %edi # imm = 0x100232; X64-CLZ-NEXT:    tzcntl %edi, %eax233; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax234; X64-CLZ-NEXT:    retq235;236; X64-FASTLZCNT-LABEL: cttz_i8_zero_test:237; X64-FASTLZCNT:       # %bb.0:238; X64-FASTLZCNT-NEXT:    orl $256, %edi # imm = 0x100239; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax240; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax241; X64-FASTLZCNT-NEXT:    retq242;243; X86-FASTLZCNT-LABEL: cttz_i8_zero_test:244; X86-FASTLZCNT:       # %bb.0:245; X86-FASTLZCNT-NEXT:    movl $256, %eax # imm = 0x100246; X86-FASTLZCNT-NEXT:    orl {{[0-9]+}}(%esp), %eax247; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax248; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax249; X86-FASTLZCNT-NEXT:    retl250  %tmp1 = call i8 @llvm.cttz.i8(i8 %n, i1 false)251  ret i8 %tmp1252}253 254; Promote i16 cttz to i32 and mask bit16 to prevent (slow) zero-src bsf case.255define i16 @cttz_i16_zero_test(i16 %n) {256; X86-LABEL: cttz_i16_zero_test:257; X86:       # %bb.0:258; X86-NEXT:    movl $65536, %eax # imm = 0x10000259; X86-NEXT:    orl {{[0-9]+}}(%esp), %eax260; X86-NEXT:    rep bsfl %eax, %eax261; X86-NEXT:    # kill: def $ax killed $ax killed $eax262; X86-NEXT:    retl263;264; X64-LABEL: cttz_i16_zero_test:265; X64:       # %bb.0:266; X64-NEXT:    orl $65536, %edi # imm = 0x10000267; X64-NEXT:    rep bsfl %edi, %eax268; X64-NEXT:    # kill: def $ax killed $ax killed $eax269; X64-NEXT:    retq270;271; X86-CLZ-LABEL: cttz_i16_zero_test:272; X86-CLZ:       # %bb.0:273; X86-CLZ-NEXT:    movl $65536, %eax # imm = 0x10000274; X86-CLZ-NEXT:    orl {{[0-9]+}}(%esp), %eax275; X86-CLZ-NEXT:    tzcntl %eax, %eax276; X86-CLZ-NEXT:    # kill: def $ax killed $ax killed $eax277; X86-CLZ-NEXT:    retl278;279; X64-CLZ-LABEL: cttz_i16_zero_test:280; X64-CLZ:       # %bb.0:281; X64-CLZ-NEXT:    orl $65536, %edi # imm = 0x10000282; X64-CLZ-NEXT:    tzcntl %edi, %eax283; X64-CLZ-NEXT:    # kill: def $ax killed $ax killed $eax284; X64-CLZ-NEXT:    retq285;286; X64-FASTLZCNT-LABEL: cttz_i16_zero_test:287; X64-FASTLZCNT:       # %bb.0:288; X64-FASTLZCNT-NEXT:    orl $65536, %edi # imm = 0x10000289; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax290; X64-FASTLZCNT-NEXT:    # kill: def $ax killed $ax killed $eax291; X64-FASTLZCNT-NEXT:    retq292;293; X86-FASTLZCNT-LABEL: cttz_i16_zero_test:294; X86-FASTLZCNT:       # %bb.0:295; X86-FASTLZCNT-NEXT:    movl $65536, %eax # imm = 0x10000296; X86-FASTLZCNT-NEXT:    orl {{[0-9]+}}(%esp), %eax297; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax298; X86-FASTLZCNT-NEXT:    # kill: def $ax killed $ax killed $eax299; X86-FASTLZCNT-NEXT:    retl300  %tmp1 = call i16 @llvm.cttz.i16(i16 %n, i1 false)301  ret i16 %tmp1302}303 304; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.305define i32 @cttz_i32_zero_test(i32 %n) {306; X86-NOCMOV-LABEL: cttz_i32_zero_test:307; X86-NOCMOV:       # %bb.0:308; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax309; X86-NOCMOV-NEXT:    testl %eax, %eax310; X86-NOCMOV-NEXT:    je .LBB6_1311; X86-NOCMOV-NEXT:  # %bb.2: # %cond.false312; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax313; X86-NOCMOV-NEXT:    retl314; X86-NOCMOV-NEXT:  .LBB6_1:315; X86-NOCMOV-NEXT:    movl $32, %eax316; X86-NOCMOV-NEXT:    retl317;318; X86-CMOV-LABEL: cttz_i32_zero_test:319; X86-CMOV:       # %bb.0:320; X86-CMOV-NEXT:    bsfl {{[0-9]+}}(%esp), %ecx321; X86-CMOV-NEXT:    movl $32, %eax322; X86-CMOV-NEXT:    cmovnel %ecx, %eax323; X86-CMOV-NEXT:    retl324;325; X64-LABEL: cttz_i32_zero_test:326; X64:       # %bb.0:327; X64-NEXT:    movl $32, %eax328; X64-NEXT:    rep bsfl %edi, %eax329; X64-NEXT:    retq330;331; X86-CLZ-LABEL: cttz_i32_zero_test:332; X86-CLZ:       # %bb.0:333; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax334; X86-CLZ-NEXT:    retl335;336; X64-CLZ-LABEL: cttz_i32_zero_test:337; X64-CLZ:       # %bb.0:338; X64-CLZ-NEXT:    tzcntl %edi, %eax339; X64-CLZ-NEXT:    retq340;341; X64-FASTLZCNT-LABEL: cttz_i32_zero_test:342; X64-FASTLZCNT:       # %bb.0:343; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax344; X64-FASTLZCNT-NEXT:    retq345;346; X86-FASTLZCNT-LABEL: cttz_i32_zero_test:347; X86-FASTLZCNT:       # %bb.0:348; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax349; X86-FASTLZCNT-NEXT:    retl350  %tmp1 = call i32 @llvm.cttz.i32(i32 %n, i1 false)351  ret i32 %tmp1352}353 354; Generate a test and branch to handle zero inputs because bsr/bsf are very slow.355define i64 @cttz_i64_zero_test(i64 %n) nounwind {356; X86-NOCMOV-LABEL: cttz_i64_zero_test:357; X86-NOCMOV:       # %bb.0:358; X86-NOCMOV-NEXT:    pushl %esi359; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax360; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx361; X86-NOCMOV-NEXT:    xorl %edx, %edx362; X86-NOCMOV-NEXT:    movl %ecx, %esi363; X86-NOCMOV-NEXT:    orl %eax, %esi364; X86-NOCMOV-NEXT:    je .LBB7_1365; X86-NOCMOV-NEXT:  # %bb.2: # %cond.false366; X86-NOCMOV-NEXT:    testl %ecx, %ecx367; X86-NOCMOV-NEXT:    jne .LBB7_3368; X86-NOCMOV-NEXT:  # %bb.4: # %cond.false369; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax370; X86-NOCMOV-NEXT:    addl $32, %eax371; X86-NOCMOV-NEXT:    popl %esi372; X86-NOCMOV-NEXT:    retl373; X86-NOCMOV-NEXT:  .LBB7_1:374; X86-NOCMOV-NEXT:    movl $64, %eax375; X86-NOCMOV-NEXT:    popl %esi376; X86-NOCMOV-NEXT:    retl377; X86-NOCMOV-NEXT:  .LBB7_3:378; X86-NOCMOV-NEXT:    rep bsfl %ecx, %eax379; X86-NOCMOV-NEXT:    popl %esi380; X86-NOCMOV-NEXT:    retl381;382; X86-CMOV-LABEL: cttz_i64_zero_test:383; X86-CMOV:       # %bb.0:384; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax385; X86-CMOV-NOT:     rep386; X86-CMOV-NEXT:    bsfl {{[0-9]+}}(%esp), %ecx387; X86-CMOV-NEXT:    movl $32, %edx388; X86-CMOV-NEXT:    cmovnel %ecx, %edx389; X86-CMOV-NEXT:    addl $32, %edx390; X86-CMOV-NOT:     rep391; X86-CMOV-NEXT:    bsfl %eax, %eax392; X86-CMOV-NEXT:    cmovel %edx, %eax393; X86-CMOV-NEXT:    xorl %edx, %edx394; X86-CMOV-NEXT:    retl395;396; X64-LABEL: cttz_i64_zero_test:397; X64:       # %bb.0:398; X64-NEXT:    movl $64, %eax399; X64-NEXT:    rep bsfq %rdi, %rax400; X64-NEXT:    retq401;402; X86-CLZ-LABEL: cttz_i64_zero_test:403; X86-CLZ:       # %bb.0:404; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax405; X86-CLZ-NEXT:    testl %eax, %eax406; X86-CLZ-NEXT:    jne .LBB7_1407; X86-CLZ-NEXT:  # %bb.2:408; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax409; X86-CLZ-NEXT:    addl $32, %eax410; X86-CLZ-NEXT:    xorl %edx, %edx411; X86-CLZ-NEXT:    retl412; X86-CLZ-NEXT:  .LBB7_1:413; X86-CLZ-NEXT:    tzcntl %eax, %eax414; X86-CLZ-NEXT:    xorl %edx, %edx415; X86-CLZ-NEXT:    retl416;417; X64-CLZ-LABEL: cttz_i64_zero_test:418; X64-CLZ:       # %bb.0:419; X64-CLZ-NEXT:    tzcntq %rdi, %rax420; X64-CLZ-NEXT:    retq421;422; X64-FASTLZCNT-LABEL: cttz_i64_zero_test:423; X64-FASTLZCNT:       # %bb.0:424; X64-FASTLZCNT-NEXT:    tzcntq %rdi, %rax425; X64-FASTLZCNT-NEXT:    retq426;427; X86-FASTLZCNT-LABEL: cttz_i64_zero_test:428; X86-FASTLZCNT:       # %bb.0:429; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax430; X86-FASTLZCNT-NEXT:    testl %eax, %eax431; X86-FASTLZCNT-NEXT:    jne .LBB7_1432; X86-FASTLZCNT-NEXT:  # %bb.2:433; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax434; X86-FASTLZCNT-NEXT:    addl $32, %eax435; X86-FASTLZCNT-NEXT:    xorl %edx, %edx436; X86-FASTLZCNT-NEXT:    retl437; X86-FASTLZCNT-NEXT:  .LBB7_1:438; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax439; X86-FASTLZCNT-NEXT:    xorl %edx, %edx440; X86-FASTLZCNT-NEXT:    retl441  %tmp1 = call i64 @llvm.cttz.i64(i64 %n, i1 false)442  ret i64 %tmp1443}444 445define i8 @cttz_i8_knownbits(i8 %x)  {446; X86-LABEL: cttz_i8_knownbits:447; X86:       # %bb.0:448; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax449; X86-NEXT:    orb $2, %al450; X86-NEXT:    movzbl %al, %eax451; X86-NEXT:    rep bsfl %eax, %eax452; X86-NEXT:    # kill: def $al killed $al killed $eax453; X86-NEXT:    retl454;455; X64-LABEL: cttz_i8_knownbits:456; X64:       # %bb.0:457; X64-NEXT:    orb $2, %dil458; X64-NEXT:    movzbl %dil, %eax459; X64-NEXT:    rep bsfl %eax, %eax460; X64-NEXT:    # kill: def $al killed $al killed $eax461; X64-NEXT:    retq462;463; X86-CLZ-LABEL: cttz_i8_knownbits:464; X86-CLZ:       # %bb.0:465; X86-CLZ-NEXT:    movzbl {{[0-9]+}}(%esp), %eax466; X86-CLZ-NEXT:    orb $2, %al467; X86-CLZ-NEXT:    movzbl %al, %eax468; X86-CLZ-NEXT:    tzcntl %eax, %eax469; X86-CLZ-NEXT:    # kill: def $al killed $al killed $eax470; X86-CLZ-NEXT:    retl471;472; X64-CLZ-LABEL: cttz_i8_knownbits:473; X64-CLZ:       # %bb.0:474; X64-CLZ-NEXT:    orb $2, %dil475; X64-CLZ-NEXT:    movzbl %dil, %eax476; X64-CLZ-NEXT:    tzcntl %eax, %eax477; X64-CLZ-NEXT:    # kill: def $al killed $al killed $eax478; X64-CLZ-NEXT:    retq479;480; X64-FASTLZCNT-LABEL: cttz_i8_knownbits:481; X64-FASTLZCNT:       # %bb.0:482; X64-FASTLZCNT-NEXT:    orb $2, %dil483; X64-FASTLZCNT-NEXT:    movzbl %dil, %eax484; X64-FASTLZCNT-NEXT:    tzcntl %eax, %eax485; X64-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax486; X64-FASTLZCNT-NEXT:    retq487;488; X86-FASTLZCNT-LABEL: cttz_i8_knownbits:489; X86-FASTLZCNT:       # %bb.0:490; X86-FASTLZCNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax491; X86-FASTLZCNT-NEXT:    orb $2, %al492; X86-FASTLZCNT-NEXT:    movzbl %al, %eax493; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax494; X86-FASTLZCNT-NEXT:    # kill: def $al killed $al killed $eax495; X86-FASTLZCNT-NEXT:    retl496  %x2 = or i8 %x, 2497  %tmp = call i8 @llvm.cttz.i8(i8 %x2, i1 true )498  %tmp2 = and i8 %tmp, 1499  ret i8 %tmp2500}501 502; Make sure we can detect that the input is non-zero and avoid cmov after BSF503; This is relevant for 32-bit mode without tzcnt504define i64 @cttz_i64_zero_test_knownneverzero(i64 %n) {505; X86-NOCMOV-LABEL: cttz_i64_zero_test_knownneverzero:506; X86-NOCMOV:       # %bb.0:507; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax508; X86-NOCMOV-NEXT:    testl %eax, %eax509; X86-NOCMOV-NEXT:    jne .LBB9_1510; X86-NOCMOV-NEXT:  # %bb.2:511; X86-NOCMOV-NEXT:    movl $-2147483648, %eax # imm = 0x80000000512; X86-NOCMOV-NEXT:    orl {{[0-9]+}}(%esp), %eax513; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax514; X86-NOCMOV-NEXT:    orl $32, %eax515; X86-NOCMOV-NEXT:    xorl %edx, %edx516; X86-NOCMOV-NEXT:    retl517; X86-NOCMOV-NEXT:  .LBB9_1:518; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax519; X86-NOCMOV-NEXT:    xorl %edx, %edx520; X86-NOCMOV-NEXT:    retl521;522; X86-CMOV-LABEL: cttz_i64_zero_test_knownneverzero:523; X86-CMOV:       # %bb.0:524; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx525; X86-CMOV-NEXT:    movl $-2147483648, %eax # imm = 0x80000000526; X86-CMOV-NEXT:    orl {{[0-9]+}}(%esp), %eax527; X86-CMOV-NEXT:    rep bsfl %ecx, %edx528; X86-CMOV-NEXT:    rep bsfl %eax, %eax529; X86-CMOV-NEXT:    orl $32, %eax530; X86-CMOV-NEXT:    testl %ecx, %ecx531; X86-CMOV-NEXT:    cmovnel %edx, %eax532; X86-CMOV-NEXT:    xorl %edx, %edx533; X86-CMOV-NEXT:    retl534;535; X64-LABEL: cttz_i64_zero_test_knownneverzero:536; X64:       # %bb.0:537; X64-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000538; X64-NEXT:    orq %rdi, %rax539; X64-NEXT:    rep bsfq %rax, %rax540; X64-NEXT:    retq541;542; X86-CLZ-LABEL: cttz_i64_zero_test_knownneverzero:543; X86-CLZ:       # %bb.0:544; X86-CLZ-NEXT:    movl {{[0-9]+}}(%esp), %eax545; X86-CLZ-NEXT:    testl %eax, %eax546; X86-CLZ-NEXT:    jne .LBB9_1547; X86-CLZ-NEXT:  # %bb.2:548; X86-CLZ-NEXT:    movl $-2147483648, %eax # imm = 0x80000000549; X86-CLZ-NEXT:    orl {{[0-9]+}}(%esp), %eax550; X86-CLZ-NEXT:    tzcntl %eax, %eax551; X86-CLZ-NEXT:    orl $32, %eax552; X86-CLZ-NEXT:    xorl %edx, %edx553; X86-CLZ-NEXT:    retl554; X86-CLZ-NEXT:  .LBB9_1:555; X86-CLZ-NEXT:    tzcntl %eax, %eax556; X86-CLZ-NEXT:    xorl %edx, %edx557; X86-CLZ-NEXT:    retl558;559; X64-CLZ-LABEL: cttz_i64_zero_test_knownneverzero:560; X64-CLZ:       # %bb.0:561; X64-CLZ-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000562; X64-CLZ-NEXT:    orq %rdi, %rax563; X64-CLZ-NEXT:    tzcntq %rax, %rax564; X64-CLZ-NEXT:    retq565;566; X64-FASTLZCNT-LABEL: cttz_i64_zero_test_knownneverzero:567; X64-FASTLZCNT:       # %bb.0:568; X64-FASTLZCNT-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000569; X64-FASTLZCNT-NEXT:    orq %rdi, %rax570; X64-FASTLZCNT-NEXT:    tzcntq %rax, %rax571; X64-FASTLZCNT-NEXT:    retq572;573; X86-FASTLZCNT-LABEL: cttz_i64_zero_test_knownneverzero:574; X86-FASTLZCNT:       # %bb.0:575; X86-FASTLZCNT-NEXT:    movl {{[0-9]+}}(%esp), %eax576; X86-FASTLZCNT-NEXT:    testl %eax, %eax577; X86-FASTLZCNT-NEXT:    jne .LBB9_1578; X86-FASTLZCNT-NEXT:  # %bb.2:579; X86-FASTLZCNT-NEXT:    movl $-2147483648, %eax # imm = 0x80000000580; X86-FASTLZCNT-NEXT:    orl {{[0-9]+}}(%esp), %eax581; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax582; X86-FASTLZCNT-NEXT:    orl $32, %eax583; X86-FASTLZCNT-NEXT:    xorl %edx, %edx584; X86-FASTLZCNT-NEXT:    retl585; X86-FASTLZCNT-NEXT:  .LBB9_1:586; X86-FASTLZCNT-NEXT:    tzcntl %eax, %eax587; X86-FASTLZCNT-NEXT:    xorl %edx, %edx588; X86-FASTLZCNT-NEXT:    retl589  %o = or i64 %n, -9223372036854775808 ; 0x8000000000000000590  %tmp1 = call i64 @llvm.cttz.i64(i64 %o, i1 false)591  ret i64 %tmp1592}593 594define i32 @cttz_i32_osize(i32 %x) optsize {595; X86-LABEL: cttz_i32_osize:596; X86:       # %bb.0:597; X86-NOT:     rep598; X86-NEXT:    bsfl {{[0-9]+}}(%esp), %eax599; X86-NEXT:    retl600;601; X64-LABEL: cttz_i32_osize:602; X64:       # %bb.0:603; X64-NOT:     rep604; X64-NEXT:    bsfl %edi, %eax605; X64-NEXT:    retq606;607; X86-CLZ-LABEL: cttz_i32_osize:608; X86-CLZ:       # %bb.0:609; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax610; X86-CLZ-NEXT:    retl611;612; X64-CLZ-LABEL: cttz_i32_osize:613; X64-CLZ:       # %bb.0:614; X64-CLZ-NEXT:    tzcntl %edi, %eax615; X64-CLZ-NEXT:    retq616;617; X64-FASTLZCNT-LABEL: cttz_i32_osize:618; X64-FASTLZCNT:       # %bb.0:619; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax620; X64-FASTLZCNT-NEXT:    retq621;622; X86-FASTLZCNT-LABEL: cttz_i32_osize:623; X86-FASTLZCNT:       # %bb.0:624; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax625; X86-FASTLZCNT-NEXT:    retl626  %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 true)627  ret i32 %tmp628}629 630define i32 @cttz_i32_msize(i32 %x) minsize {631; X86-LABEL: cttz_i32_msize:632; X86:       # %bb.0:633; X86-NOT:     rep634; X86-NEXT:    bsfl {{[0-9]+}}(%esp), %eax635; X86-NEXT:    retl636;637; X64-LABEL: cttz_i32_msize:638; X64:       # %bb.0:639; X64-NOT:     rep640; X64-NEXT:    bsfl %edi, %eax641; X64-NEXT:    retq642;643; X86-CLZ-LABEL: cttz_i32_msize:644; X86-CLZ:       # %bb.0:645; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax646; X86-CLZ-NEXT:    retl647;648; X64-CLZ-LABEL: cttz_i32_msize:649; X64-CLZ:       # %bb.0:650; X64-CLZ-NEXT:    tzcntl %edi, %eax651; X64-CLZ-NEXT:    retq652;653; X64-FASTLZCNT-LABEL: cttz_i32_msize:654; X64-FASTLZCNT:       # %bb.0:655; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax656; X64-FASTLZCNT-NEXT:    retq657;658; X86-FASTLZCNT-LABEL: cttz_i32_msize:659; X86-FASTLZCNT:       # %bb.0:660; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax661; X86-FASTLZCNT-NEXT:    retl662  %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 true)663  ret i32 %tmp664}665 666define i64 @cttz_i32_sext(i32 %x) {667; X86-NOCMOV-LABEL: cttz_i32_sext:668; X86-NOCMOV:       # %bb.0:669; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax670; X86-NOCMOV-NEXT:    testl %eax, %eax671; X86-NOCMOV-NEXT:    je .LBB12_1672; X86-NOCMOV-NEXT:  # %bb.2: # %cond.false673; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax674; X86-NOCMOV-NEXT:    xorl %edx, %edx675; X86-NOCMOV-NEXT:    retl676; X86-NOCMOV-NEXT:  .LBB12_1:677; X86-NOCMOV-NEXT:    movl $32, %eax678; X86-NOCMOV-NEXT:    xorl %edx, %edx679; X86-NOCMOV-NEXT:    retl680;681; X86-CMOV-LABEL: cttz_i32_sext:682; X86-CMOV:       # %bb.0:683; X86-CMOV-NEXT:    bsfl {{[0-9]+}}(%esp), %ecx684; X86-CMOV-NEXT:    movl $32, %eax685; X86-CMOV-NEXT:    cmovnel %ecx, %eax686; X86-CMOV-NEXT:    xorl %edx, %edx687; X86-CMOV-NEXT:    retl688;689; X64-LABEL: cttz_i32_sext:690; X64:       # %bb.0:691; X64-NEXT:    movl $32, %eax692; X64-NEXT:    rep bsfl %edi, %eax693; X64-NEXT:    retq694;695; X86-CLZ-LABEL: cttz_i32_sext:696; X86-CLZ:       # %bb.0:697; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax698; X86-CLZ-NEXT:    xorl %edx, %edx699; X86-CLZ-NEXT:    retl700;701; X64-CLZ-LABEL: cttz_i32_sext:702; X64-CLZ:       # %bb.0:703; X64-CLZ-NEXT:    tzcntl %edi, %eax704; X64-CLZ-NEXT:    retq705;706; X64-FASTLZCNT-LABEL: cttz_i32_sext:707; X64-FASTLZCNT:       # %bb.0:708; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax709; X64-FASTLZCNT-NEXT:    retq710;711; X86-FASTLZCNT-LABEL: cttz_i32_sext:712; X86-FASTLZCNT:       # %bb.0:713; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax714; X86-FASTLZCNT-NEXT:    xorl %edx, %edx715; X86-FASTLZCNT-NEXT:    retl716  %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 false)717  %ext = sext i32 %tmp to i64718  ret i64 %ext719}720 721define i64 @cttz_i32_zext(i32 %x) {722; X86-NOCMOV-LABEL: cttz_i32_zext:723; X86-NOCMOV:       # %bb.0:724; X86-NOCMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax725; X86-NOCMOV-NEXT:    testl %eax, %eax726; X86-NOCMOV-NEXT:    je .LBB13_1727; X86-NOCMOV-NEXT:  # %bb.2: # %cond.false728; X86-NOCMOV-NEXT:    rep bsfl %eax, %eax729; X86-NOCMOV-NEXT:    xorl %edx, %edx730; X86-NOCMOV-NEXT:    retl731; X86-NOCMOV-NEXT:  .LBB13_1:732; X86-NOCMOV-NEXT:    movl $32, %eax733; X86-NOCMOV-NEXT:    xorl %edx, %edx734; X86-NOCMOV-NEXT:    retl735;736; X86-CMOV-LABEL: cttz_i32_zext:737; X86-CMOV:       # %bb.0:738; X86-CMOV-NEXT:    bsfl {{[0-9]+}}(%esp), %ecx739; X86-CMOV-NEXT:    movl $32, %eax740; X86-CMOV-NEXT:    cmovnel %ecx, %eax741; X86-CMOV-NEXT:    xorl %edx, %edx742; X86-CMOV-NEXT:    retl743;744; X64-LABEL: cttz_i32_zext:745; X64:       # %bb.0:746; X64-NEXT:    movl $32, %eax747; X64-NEXT:    rep bsfl %edi, %eax748; X64-NEXT:    retq749;750; X86-CLZ-LABEL: cttz_i32_zext:751; X86-CLZ:       # %bb.0:752; X86-CLZ-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax753; X86-CLZ-NEXT:    xorl %edx, %edx754; X86-CLZ-NEXT:    retl755;756; X64-CLZ-LABEL: cttz_i32_zext:757; X64-CLZ:       # %bb.0:758; X64-CLZ-NEXT:    tzcntl %edi, %eax759; X64-CLZ-NEXT:    retq760;761; X64-FASTLZCNT-LABEL: cttz_i32_zext:762; X64-FASTLZCNT:       # %bb.0:763; X64-FASTLZCNT-NEXT:    tzcntl %edi, %eax764; X64-FASTLZCNT-NEXT:    retq765;766; X86-FASTLZCNT-LABEL: cttz_i32_zext:767; X86-FASTLZCNT:       # %bb.0:768; X86-FASTLZCNT-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax769; X86-FASTLZCNT-NEXT:    xorl %edx, %edx770; X86-FASTLZCNT-NEXT:    retl771  %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 false)772  %ext = zext i32 %tmp to i64773  ret i64 %ext774}775 776