444 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=i686-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X86-CLZ8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X64-CLZ9 10declare i8 @llvm.ctlz.i8(i8, i1)11declare i16 @llvm.ctlz.i16(i16, i1)12declare i32 @llvm.ctlz.i32(i32, i1)13declare i64 @llvm.ctlz.i64(i64, i1)14 15define i8 @ctlo_i8(i8 %x) {16; X86-NOCMOV-LABEL: ctlo_i8:17; X86-NOCMOV: # %bb.0:18; X86-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax19; X86-NOCMOV-NEXT: xorb $-1, %al20; X86-NOCMOV-NEXT: je .LBB0_121; X86-NOCMOV-NEXT: # %bb.2: # %cond.false22; X86-NOCMOV-NEXT: movzbl %al, %eax23; X86-NOCMOV-NEXT: bsrl %eax, %eax24; X86-NOCMOV-NEXT: xorl $7, %eax25; X86-NOCMOV-NEXT: # kill: def $al killed $al killed $eax26; X86-NOCMOV-NEXT: retl27; X86-NOCMOV-NEXT: .LBB0_1:28; X86-NOCMOV-NEXT: movb $8, %al29; X86-NOCMOV-NEXT: # kill: def $al killed $al killed $eax30; X86-NOCMOV-NEXT: retl31;32; X86-CMOV-LABEL: ctlo_i8:33; X86-CMOV: # %bb.0:34; X86-CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax35; X86-CMOV-NEXT: notb %al36; X86-CMOV-NEXT: movzbl %al, %eax37; X86-CMOV-NEXT: bsrl %eax, %ecx38; X86-CMOV-NEXT: movl $15, %eax39; X86-CMOV-NEXT: cmovnel %ecx, %eax40; X86-CMOV-NEXT: xorl $7, %eax41; X86-CMOV-NEXT: # kill: def $al killed $al killed $eax42; X86-CMOV-NEXT: retl43;44; X64-LABEL: ctlo_i8:45; X64: # %bb.0:46; X64-NEXT: notb %dil47; X64-NEXT: movzbl %dil, %ecx48; X64-NEXT: movl $15, %eax49; X64-NEXT: bsrl %ecx, %eax50; X64-NEXT: xorl $7, %eax51; X64-NEXT: # kill: def $al killed $al killed $eax52; X64-NEXT: retq53;54; X86-CLZ-LABEL: ctlo_i8:55; X86-CLZ: # %bb.0:56; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax57; X86-CLZ-NEXT: shll $24, %eax58; X86-CLZ-NEXT: notl %eax59; X86-CLZ-NEXT: lzcntl %eax, %eax60; X86-CLZ-NEXT: # kill: def $al killed $al killed $eax61; X86-CLZ-NEXT: retl62;63; X64-CLZ-LABEL: ctlo_i8:64; X64-CLZ: # %bb.0:65; X64-CLZ-NEXT: shll $24, %edi66; X64-CLZ-NEXT: notl %edi67; X64-CLZ-NEXT: lzcntl %edi, %eax68; X64-CLZ-NEXT: # kill: def $al killed $al killed $eax69; X64-CLZ-NEXT: retq70 %tmp1 = xor i8 %x, -171 %tmp2 = call i8 @llvm.ctlz.i8( i8 %tmp1, i1 false )72 ret i8 %tmp273}74 75define i8 @ctlo_i8_undef(i8 %x) {76; X86-LABEL: ctlo_i8_undef:77; X86: # %bb.0:78; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax79; X86-NEXT: notb %al80; X86-NEXT: movzbl %al, %eax81; X86-NEXT: bsrl %eax, %eax82; X86-NEXT: xorl $7, %eax83; X86-NEXT: # kill: def $al killed $al killed $eax84; X86-NEXT: retl85;86; X64-LABEL: ctlo_i8_undef:87; X64: # %bb.0:88; X64-NEXT: notb %dil89; X64-NEXT: movzbl %dil, %eax90; X64-NEXT: bsrl %eax, %eax91; X64-NEXT: xorl $7, %eax92; X64-NEXT: # kill: def $al killed $al killed $eax93; X64-NEXT: retq94;95; X86-CLZ-LABEL: ctlo_i8_undef:96; X86-CLZ: # %bb.0:97; X86-CLZ-NEXT: movzbl {{[0-9]+}}(%esp), %eax98; X86-CLZ-NEXT: notb %al99; X86-CLZ-NEXT: movzbl %al, %eax100; X86-CLZ-NEXT: shll $24, %eax101; X86-CLZ-NEXT: lzcntl %eax, %eax102; X86-CLZ-NEXT: # kill: def $al killed $al killed $eax103; X86-CLZ-NEXT: retl104;105; X64-CLZ-LABEL: ctlo_i8_undef:106; X64-CLZ: # %bb.0:107; X64-CLZ-NEXT: notb %dil108; X64-CLZ-NEXT: movzbl %dil, %eax109; X64-CLZ-NEXT: shll $24, %eax110; X64-CLZ-NEXT: lzcntl %eax, %eax111; X64-CLZ-NEXT: # kill: def $al killed $al killed $eax112; X64-CLZ-NEXT: retq113 %tmp1 = xor i8 %x, -1114 %tmp2 = call i8 @llvm.ctlz.i8( i8 %tmp1, i1 true )115 ret i8 %tmp2116}117 118define i16 @ctlo_i16(i16 %x) {119; X86-NOCMOV-LABEL: ctlo_i16:120; X86-NOCMOV: # %bb.0:121; X86-NOCMOV-NEXT: movzwl {{[0-9]+}}(%esp), %eax122; X86-NOCMOV-NEXT: xorw $-1, %ax123; X86-NOCMOV-NEXT: je .LBB2_1124; X86-NOCMOV-NEXT: # %bb.2: # %cond.false125; X86-NOCMOV-NEXT: bsrw %ax, %ax126; X86-NOCMOV-NEXT: xorl $15, %eax127; X86-NOCMOV-NEXT: # kill: def $ax killed $ax killed $eax128; X86-NOCMOV-NEXT: retl129; X86-NOCMOV-NEXT: .LBB2_1:130; X86-NOCMOV-NEXT: movw $16, %ax131; X86-NOCMOV-NEXT: # kill: def $ax killed $ax killed $eax132; X86-NOCMOV-NEXT: retl133;134; X86-CMOV-LABEL: ctlo_i16:135; X86-CMOV: # %bb.0:136; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax137; X86-CMOV-NEXT: notl %eax138; X86-CMOV-NEXT: bsrw %ax, %cx139; X86-CMOV-NEXT: movw $31, %ax140; X86-CMOV-NEXT: cmovnew %cx, %ax141; X86-CMOV-NEXT: xorl $15, %eax142; X86-CMOV-NEXT: # kill: def $ax killed $ax killed $eax143; X86-CMOV-NEXT: retl144;145; X64-LABEL: ctlo_i16:146; X64: # %bb.0:147; X64-NEXT: notl %edi148; X64-NEXT: movw $31, %ax149; X64-NEXT: bsrw %di, %ax150; X64-NEXT: xorl $15, %eax151; X64-NEXT: # kill: def $ax killed $ax killed $eax152; X64-NEXT: retq153;154; X86-CLZ-LABEL: ctlo_i16:155; X86-CLZ: # %bb.0:156; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax157; X86-CLZ-NEXT: notl %eax158; X86-CLZ-NEXT: lzcntw %ax, %ax159; X86-CLZ-NEXT: retl160;161; X64-CLZ-LABEL: ctlo_i16:162; X64-CLZ: # %bb.0:163; X64-CLZ-NEXT: notl %edi164; X64-CLZ-NEXT: lzcntw %di, %ax165; X64-CLZ-NEXT: retq166 %tmp1 = xor i16 %x, -1167 %tmp2 = call i16 @llvm.ctlz.i16( i16 %tmp1, i1 false )168 ret i16 %tmp2169}170 171define i16 @ctlo_i16_undef(i16 %x) {172; X86-LABEL: ctlo_i16_undef:173; X86: # %bb.0:174; X86-NEXT: movl {{[0-9]+}}(%esp), %eax175; X86-NEXT: notl %eax176; X86-NEXT: bsrw %ax, %ax177; X86-NEXT: xorl $15, %eax178; X86-NEXT: # kill: def $ax killed $ax killed $eax179; X86-NEXT: retl180;181; X64-LABEL: ctlo_i16_undef:182; X64: # %bb.0:183; X64-NEXT: notl %edi184; X64-NEXT: bsrw %di, %ax185; X64-NEXT: xorl $15, %eax186; X64-NEXT: # kill: def $ax killed $ax killed $eax187; X64-NEXT: retq188;189; X86-CLZ-LABEL: ctlo_i16_undef:190; X86-CLZ: # %bb.0:191; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax192; X86-CLZ-NEXT: notl %eax193; X86-CLZ-NEXT: lzcntw %ax, %ax194; X86-CLZ-NEXT: retl195;196; X64-CLZ-LABEL: ctlo_i16_undef:197; X64-CLZ: # %bb.0:198; X64-CLZ-NEXT: notl %edi199; X64-CLZ-NEXT: lzcntw %di, %ax200; X64-CLZ-NEXT: retq201 %tmp1 = xor i16 %x, -1202 %tmp2 = call i16 @llvm.ctlz.i16( i16 %tmp1, i1 true )203 ret i16 %tmp2204}205 206define i32 @ctlo_i32(i32 %x) {207; X86-NOCMOV-LABEL: ctlo_i32:208; X86-NOCMOV: # %bb.0:209; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax210; X86-NOCMOV-NEXT: xorl $-1, %eax211; X86-NOCMOV-NEXT: je .LBB4_1212; X86-NOCMOV-NEXT: # %bb.2: # %cond.false213; X86-NOCMOV-NEXT: bsrl %eax, %eax214; X86-NOCMOV-NEXT: xorl $31, %eax215; X86-NOCMOV-NEXT: retl216; X86-NOCMOV-NEXT: .LBB4_1:217; X86-NOCMOV-NEXT: movl $32, %eax218; X86-NOCMOV-NEXT: retl219;220; X86-CMOV-LABEL: ctlo_i32:221; X86-CMOV: # %bb.0:222; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax223; X86-CMOV-NEXT: notl %eax224; X86-CMOV-NEXT: bsrl %eax, %ecx225; X86-CMOV-NEXT: movl $63, %eax226; X86-CMOV-NEXT: cmovnel %ecx, %eax227; X86-CMOV-NEXT: xorl $31, %eax228; X86-CMOV-NEXT: retl229;230; X64-LABEL: ctlo_i32:231; X64: # %bb.0:232; X64-NEXT: notl %edi233; X64-NEXT: movl $63, %eax234; X64-NEXT: bsrl %edi, %eax235; X64-NEXT: xorl $31, %eax236; X64-NEXT: retq237;238; X86-CLZ-LABEL: ctlo_i32:239; X86-CLZ: # %bb.0:240; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax241; X86-CLZ-NEXT: notl %eax242; X86-CLZ-NEXT: lzcntl %eax, %eax243; X86-CLZ-NEXT: retl244;245; X64-CLZ-LABEL: ctlo_i32:246; X64-CLZ: # %bb.0:247; X64-CLZ-NEXT: notl %edi248; X64-CLZ-NEXT: lzcntl %edi, %eax249; X64-CLZ-NEXT: retq250 %tmp1 = xor i32 %x, -1251 %tmp2 = call i32 @llvm.ctlz.i32( i32 %tmp1, i1 false )252 ret i32 %tmp2253}254 255define i32 @ctlo_i32_undef(i32 %x) {256; X86-LABEL: ctlo_i32_undef:257; X86: # %bb.0:258; X86-NEXT: movl {{[0-9]+}}(%esp), %eax259; X86-NEXT: notl %eax260; X86-NEXT: bsrl %eax, %eax261; X86-NEXT: xorl $31, %eax262; X86-NEXT: retl263;264; X64-LABEL: ctlo_i32_undef:265; X64: # %bb.0:266; X64-NEXT: notl %edi267; X64-NEXT: bsrl %edi, %eax268; X64-NEXT: xorl $31, %eax269; X64-NEXT: retq270;271; X86-CLZ-LABEL: ctlo_i32_undef:272; X86-CLZ: # %bb.0:273; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax274; X86-CLZ-NEXT: notl %eax275; X86-CLZ-NEXT: lzcntl %eax, %eax276; X86-CLZ-NEXT: retl277;278; X64-CLZ-LABEL: ctlo_i32_undef:279; X64-CLZ: # %bb.0:280; X64-CLZ-NEXT: notl %edi281; X64-CLZ-NEXT: lzcntl %edi, %eax282; X64-CLZ-NEXT: retq283 %tmp1 = xor i32 %x, -1284 %tmp2 = call i32 @llvm.ctlz.i32( i32 %tmp1, i1 true )285 ret i32 %tmp2286}287 288define i64 @ctlo_i64(i64 %x) nounwind {289; X86-NOCMOV-LABEL: ctlo_i64:290; X86-NOCMOV: # %bb.0:291; X86-NOCMOV-NEXT: pushl %esi292; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax293; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx294; X86-NOCMOV-NEXT: notl %ecx295; X86-NOCMOV-NEXT: notl %eax296; X86-NOCMOV-NEXT: xorl %edx, %edx297; X86-NOCMOV-NEXT: movl %eax, %esi298; X86-NOCMOV-NEXT: orl %ecx, %esi299; X86-NOCMOV-NEXT: je .LBB6_1300; X86-NOCMOV-NEXT: # %bb.2: # %cond.false301; X86-NOCMOV-NEXT: testl %ecx, %ecx302; X86-NOCMOV-NEXT: jne .LBB6_3303; X86-NOCMOV-NEXT: # %bb.4: # %cond.false304; X86-NOCMOV-NEXT: bsrl %eax, %eax305; X86-NOCMOV-NEXT: xorl $31, %eax306; X86-NOCMOV-NEXT: orl $32, %eax307; X86-NOCMOV-NEXT: popl %esi308; X86-NOCMOV-NEXT: retl309; X86-NOCMOV-NEXT: .LBB6_1:310; X86-NOCMOV-NEXT: movl $64, %eax311; X86-NOCMOV-NEXT: popl %esi312; X86-NOCMOV-NEXT: retl313; X86-NOCMOV-NEXT: .LBB6_3:314; X86-NOCMOV-NEXT: bsrl %ecx, %eax315; X86-NOCMOV-NEXT: xorl $31, %eax316; X86-NOCMOV-NEXT: popl %esi317; X86-NOCMOV-NEXT: retl318;319; X86-CMOV-LABEL: ctlo_i64:320; X86-CMOV: # %bb.0:321; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax322; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx323; X86-CMOV-NEXT: notl %ecx324; X86-CMOV-NEXT: notl %eax325; X86-CMOV-NEXT: bsrl %eax, %eax326; X86-CMOV-NEXT: movl $63, %edx327; X86-CMOV-NEXT: cmovnel %eax, %edx328; X86-CMOV-NEXT: xorl $31, %edx329; X86-CMOV-NEXT: addl $32, %edx330; X86-CMOV-NEXT: bsrl %ecx, %eax331; X86-CMOV-NEXT: xorl $31, %eax332; X86-CMOV-NEXT: testl %ecx, %ecx333; X86-CMOV-NEXT: cmovel %edx, %eax334; X86-CMOV-NEXT: xorl %edx, %edx335; X86-CMOV-NEXT: retl336;337; X64-LABEL: ctlo_i64:338; X64: # %bb.0:339; X64-NEXT: notq %rdi340; X64-NEXT: movl $127, %eax341; X64-NEXT: bsrq %rdi, %rax342; X64-NEXT: xorq $63, %rax343; X64-NEXT: retq344;345; X86-CLZ-LABEL: ctlo_i64:346; X86-CLZ: # %bb.0:347; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax348; X86-CLZ-NEXT: notl %eax349; X86-CLZ-NEXT: testl %eax, %eax350; X86-CLZ-NEXT: jne .LBB6_1351; X86-CLZ-NEXT: # %bb.2:352; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax353; X86-CLZ-NEXT: notl %eax354; X86-CLZ-NEXT: lzcntl %eax, %eax355; X86-CLZ-NEXT: addl $32, %eax356; X86-CLZ-NEXT: xorl %edx, %edx357; X86-CLZ-NEXT: retl358; X86-CLZ-NEXT: .LBB6_1:359; X86-CLZ-NEXT: lzcntl %eax, %eax360; X86-CLZ-NEXT: xorl %edx, %edx361; X86-CLZ-NEXT: retl362;363; X64-CLZ-LABEL: ctlo_i64:364; X64-CLZ: # %bb.0:365; X64-CLZ-NEXT: notq %rdi366; X64-CLZ-NEXT: lzcntq %rdi, %rax367; X64-CLZ-NEXT: retq368 %tmp1 = xor i64 %x, -1369 %tmp2 = call i64 @llvm.ctlz.i64( i64 %tmp1, i1 false )370 ret i64 %tmp2371}372 373define i64 @ctlo_i64_undef(i64 %x) {374; X86-NOCMOV-LABEL: ctlo_i64_undef:375; X86-NOCMOV: # %bb.0:376; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax377; X86-NOCMOV-NEXT: notl %eax378; X86-NOCMOV-NEXT: testl %eax, %eax379; X86-NOCMOV-NEXT: jne .LBB7_1380; X86-NOCMOV-NEXT: # %bb.2:381; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax382; X86-NOCMOV-NEXT: notl %eax383; X86-NOCMOV-NEXT: bsrl %eax, %eax384; X86-NOCMOV-NEXT: xorl $31, %eax385; X86-NOCMOV-NEXT: orl $32, %eax386; X86-NOCMOV-NEXT: xorl %edx, %edx387; X86-NOCMOV-NEXT: retl388; X86-NOCMOV-NEXT: .LBB7_1:389; X86-NOCMOV-NEXT: bsrl %eax, %eax390; X86-NOCMOV-NEXT: xorl $31, %eax391; X86-NOCMOV-NEXT: xorl %edx, %edx392; X86-NOCMOV-NEXT: retl393;394; X86-CMOV-LABEL: ctlo_i64_undef:395; X86-CMOV: # %bb.0:396; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax397; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx398; X86-CMOV-NEXT: notl %eax399; X86-CMOV-NEXT: notl %ecx400; X86-CMOV-NEXT: bsrl %ecx, %edx401; X86-CMOV-NEXT: xorl $31, %edx402; X86-CMOV-NEXT: bsrl %eax, %eax403; X86-CMOV-NEXT: xorl $31, %eax404; X86-CMOV-NEXT: orl $32, %eax405; X86-CMOV-NEXT: testl %ecx, %ecx406; X86-CMOV-NEXT: cmovnel %edx, %eax407; X86-CMOV-NEXT: xorl %edx, %edx408; X86-CMOV-NEXT: retl409;410; X64-LABEL: ctlo_i64_undef:411; X64: # %bb.0:412; X64-NEXT: notq %rdi413; X64-NEXT: bsrq %rdi, %rax414; X64-NEXT: xorq $63, %rax415; X64-NEXT: retq416;417; X86-CLZ-LABEL: ctlo_i64_undef:418; X86-CLZ: # %bb.0:419; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax420; X86-CLZ-NEXT: notl %eax421; X86-CLZ-NEXT: testl %eax, %eax422; X86-CLZ-NEXT: jne .LBB7_1423; X86-CLZ-NEXT: # %bb.2:424; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax425; X86-CLZ-NEXT: notl %eax426; X86-CLZ-NEXT: lzcntl %eax, %eax427; X86-CLZ-NEXT: addl $32, %eax428; X86-CLZ-NEXT: xorl %edx, %edx429; X86-CLZ-NEXT: retl430; X86-CLZ-NEXT: .LBB7_1:431; X86-CLZ-NEXT: lzcntl %eax, %eax432; X86-CLZ-NEXT: xorl %edx, %edx433; X86-CLZ-NEXT: retl434;435; X64-CLZ-LABEL: ctlo_i64_undef:436; X64-CLZ: # %bb.0:437; X64-CLZ-NEXT: notq %rdi438; X64-CLZ-NEXT: lzcntq %rdi, %rax439; X64-CLZ-NEXT: retq440 %tmp1 = xor i64 %x, -1441 %tmp2 = call i64 @llvm.ctlz.i64( i64 %tmp1, i1 true )442 ret i64 %tmp2443}444