1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X32 3; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64 4; RUN: llc < %s -mtriple=i686-unknown -mattr=+popcnt | FileCheck %s --check-prefix=X32-POPCNT 5; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+popcnt | FileCheck %s --check-prefix=X64-POPCNT 6 7define i8 @cnt8(i8 %x) nounwind readnone { 8; X32-LABEL: cnt8: 9; X32: # %bb.0: 10; X32-NEXT: movb {{[0-9]+}}(%esp), %cl 11; X32-NEXT: movl %ecx, %eax 12; X32-NEXT: shrb %al 13; X32-NEXT: andb $85, %al 14; X32-NEXT: subb %al, %cl 15; X32-NEXT: movl %ecx, %eax 16; X32-NEXT: andb $51, %al 17; X32-NEXT: shrb $2, %cl 18; X32-NEXT: andb $51, %cl 19; X32-NEXT: addb %al, %cl 20; X32-NEXT: movl %ecx, %eax 21; X32-NEXT: shrb $4, %al 22; X32-NEXT: addb %cl, %al 23; X32-NEXT: andb $15, %al 24; X32-NEXT: retl 25; 26; X64-LABEL: cnt8: 27; X64: # %bb.0: 28; X64-NEXT: movl %edi, %eax 29; X64-NEXT: shrb %al 30; X64-NEXT: andb $85, %al 31; X64-NEXT: subb %al, %dil 32; X64-NEXT: movl %edi, %eax 33; X64-NEXT: andb $51, %al 34; X64-NEXT: shrb $2, %dil 35; X64-NEXT: andb $51, %dil 36; X64-NEXT: addb %al, %dil 37; X64-NEXT: movl %edi, %eax 38; X64-NEXT: shrb $4, %al 39; X64-NEXT: addb %dil, %al 40; X64-NEXT: andb $15, %al 41; X64-NEXT: retq 42; 43; X32-POPCNT-LABEL: cnt8: 44; X32-POPCNT: # %bb.0: 45; X32-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax 46; X32-POPCNT-NEXT: popcntl %eax, %eax 47; X32-POPCNT-NEXT: # kill: def $al killed $al killed $eax 48; X32-POPCNT-NEXT: retl 49; 50; X64-POPCNT-LABEL: cnt8: 51; X64-POPCNT: # %bb.0: 52; X64-POPCNT-NEXT: movzbl %dil, %eax 53; X64-POPCNT-NEXT: popcntl %eax, %eax 54; X64-POPCNT-NEXT: # kill: def $al killed $al killed $eax 55; X64-POPCNT-NEXT: retq 56 %cnt = tail call i8 @llvm.ctpop.i8(i8 %x) 57 ret i8 %cnt 58} 59 60define i16 @cnt16(i16 %x) nounwind readnone { 61; X32-LABEL: cnt16: 62; X32: # %bb.0: 63; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 64; X32-NEXT: movl %eax, %ecx 65; X32-NEXT: shrl %ecx 66; X32-NEXT: andl $21845, %ecx # imm = 0x5555 67; X32-NEXT: subl %ecx, %eax 68; X32-NEXT: movl %eax, %ecx 69; X32-NEXT: andl $13107, %ecx # imm = 0x3333 70; X32-NEXT: shrl $2, %eax 71; X32-NEXT: andl $13107, %eax # imm = 0x3333 72; X32-NEXT: addl %ecx, %eax 73; X32-NEXT: movl %eax, %ecx 74; X32-NEXT: shrl $4, %ecx 75; X32-NEXT: addl %eax, %ecx 76; X32-NEXT: andl $3855, %ecx # imm = 0xF0F 77; X32-NEXT: movl %ecx, %eax 78; X32-NEXT: shll $8, %eax 79; X32-NEXT: addl %ecx, %eax 80; X32-NEXT: movzbl %ah, %eax 81; X32-NEXT: # kill: def $ax killed $ax killed $eax 82; X32-NEXT: retl 83; 84; X64-LABEL: cnt16: 85; X64: # %bb.0: 86; X64-NEXT: movl %edi, %eax 87; X64-NEXT: shrl %eax 88; X64-NEXT: andl $21845, %eax # imm = 0x5555 89; X64-NEXT: subl %eax, %edi 90; X64-NEXT: movl %edi, %eax 91; X64-NEXT: andl $13107, %eax # imm = 0x3333 92; X64-NEXT: shrl $2, %edi 93; X64-NEXT: andl $13107, %edi # imm = 0x3333 94; X64-NEXT: addl %eax, %edi 95; X64-NEXT: movl %edi, %eax 96; X64-NEXT: shrl $4, %eax 97; X64-NEXT: addl %edi, %eax 98; X64-NEXT: andl $3855, %eax # imm = 0xF0F 99; X64-NEXT: movl %eax, %ecx 100; X64-NEXT: shll $8, %ecx 101; X64-NEXT: addl %eax, %ecx 102; X64-NEXT: movzbl %ch, %eax 103; X64-NEXT: # kill: def $ax killed $ax killed $eax 104; X64-NEXT: retq 105; 106; X32-POPCNT-LABEL: cnt16: 107; X32-POPCNT: # %bb.0: 108; X32-POPCNT-NEXT: popcntw {{[0-9]+}}(%esp), %ax 109; X32-POPCNT-NEXT: retl 110; 111; X64-POPCNT-LABEL: cnt16: 112; X64-POPCNT: # %bb.0: 113; X64-POPCNT-NEXT: popcntw %di, %ax 114; X64-POPCNT-NEXT: retq 115 %cnt = tail call i16 @llvm.ctpop.i16(i16 %x) 116 ret i16 %cnt 117} 118 119define i32 @cnt32(i32 %x) nounwind readnone { 120; X32-LABEL: cnt32: 121; X32: # %bb.0: 122; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 123; X32-NEXT: movl %eax, %ecx 124; X32-NEXT: shrl %ecx 125; X32-NEXT: andl $1431655765, %ecx # imm = 0x55555555 126; X32-NEXT: subl %ecx, %eax 127; X32-NEXT: movl %eax, %ecx 128; X32-NEXT: andl $858993459, %ecx # imm = 0x33333333 129; X32-NEXT: shrl $2, %eax 130; X32-NEXT: andl $858993459, %eax # imm = 0x33333333 131; X32-NEXT: addl %ecx, %eax 132; X32-NEXT: movl %eax, %ecx 133; X32-NEXT: shrl $4, %ecx 134; X32-NEXT: addl %eax, %ecx 135; X32-NEXT: andl $252645135, %ecx # imm = 0xF0F0F0F 136; X32-NEXT: imull $16843009, %ecx, %eax # imm = 0x1010101 137; X32-NEXT: shrl $24, %eax 138; X32-NEXT: retl 139; 140; X64-LABEL: cnt32: 141; X64: # %bb.0: 142; X64-NEXT: movl %edi, %eax 143; X64-NEXT: shrl %eax 144; X64-NEXT: andl $1431655765, %eax # imm = 0x55555555 145; X64-NEXT: subl %eax, %edi 146; X64-NEXT: movl %edi, %eax 147; X64-NEXT: andl $858993459, %eax # imm = 0x33333333 148; X64-NEXT: shrl $2, %edi 149; X64-NEXT: andl $858993459, %edi # imm = 0x33333333 150; X64-NEXT: addl %eax, %edi 151; X64-NEXT: movl %edi, %eax 152; X64-NEXT: shrl $4, %eax 153; X64-NEXT: addl %edi, %eax 154; X64-NEXT: andl $252645135, %eax # imm = 0xF0F0F0F 155; X64-NEXT: imull $16843009, %eax, %eax # imm = 0x1010101 156; X64-NEXT: shrl $24, %eax 157; X64-NEXT: retq 158; 159; X32-POPCNT-LABEL: cnt32: 160; X32-POPCNT: # %bb.0: 161; X32-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax 162; X32-POPCNT-NEXT: retl 163; 164; X64-POPCNT-LABEL: cnt32: 165; X64-POPCNT: # %bb.0: 166; X64-POPCNT-NEXT: popcntl %edi, %eax 167; X64-POPCNT-NEXT: retq 168 %cnt = tail call i32 @llvm.ctpop.i32(i32 %x) 169 ret i32 %cnt 170} 171 172define i64 @cnt64(i64 %x) nounwind readnone { 173; X32-LABEL: cnt64: 174; X32: # %bb.0: 175; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 176; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx 177; X32-NEXT: movl %ecx, %edx 178; X32-NEXT: shrl %edx 179; X32-NEXT: andl $1431655765, %edx # imm = 0x55555555 180; X32-NEXT: subl %edx, %ecx 181; X32-NEXT: movl %ecx, %edx 182; X32-NEXT: andl $858993459, %edx # imm = 0x33333333 183; X32-NEXT: shrl $2, %ecx 184; X32-NEXT: andl $858993459, %ecx # imm = 0x33333333 185; X32-NEXT: addl %edx, %ecx 186; X32-NEXT: movl %ecx, %edx 187; X32-NEXT: shrl $4, %edx 188; X32-NEXT: addl %ecx, %edx 189; X32-NEXT: andl $252645135, %edx # imm = 0xF0F0F0F 190; X32-NEXT: imull $16843009, %edx, %ecx # imm = 0x1010101 191; X32-NEXT: shrl $24, %ecx 192; X32-NEXT: movl %eax, %edx 193; X32-NEXT: shrl %edx 194; X32-NEXT: andl $1431655765, %edx # imm = 0x55555555 195; X32-NEXT: subl %edx, %eax 196; X32-NEXT: movl %eax, %edx 197; X32-NEXT: andl $858993459, %edx # imm = 0x33333333 198; X32-NEXT: shrl $2, %eax 199; X32-NEXT: andl $858993459, %eax # imm = 0x33333333 200; X32-NEXT: addl %edx, %eax 201; X32-NEXT: movl %eax, %edx 202; X32-NEXT: shrl $4, %edx 203; X32-NEXT: addl %eax, %edx 204; X32-NEXT: andl $252645135, %edx # imm = 0xF0F0F0F 205; X32-NEXT: imull $16843009, %edx, %eax # imm = 0x1010101 206; X32-NEXT: shrl $24, %eax 207; X32-NEXT: addl %ecx, %eax 208; X32-NEXT: xorl %edx, %edx 209; X32-NEXT: retl 210; 211; X64-LABEL: cnt64: 212; X64: # %bb.0: 213; X64-NEXT: movq %rdi, %rax 214; X64-NEXT: shrq %rax 215; X64-NEXT: movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555 216; X64-NEXT: andq %rax, %rcx 217; X64-NEXT: subq %rcx, %rdi 218; X64-NEXT: movabsq $3689348814741910323, %rax # imm = 0x3333333333333333 219; X64-NEXT: movq %rdi, %rcx 220; X64-NEXT: andq %rax, %rcx 221; X64-NEXT: shrq $2, %rdi 222; X64-NEXT: andq %rax, %rdi 223; X64-NEXT: addq %rcx, %rdi 224; X64-NEXT: movq %rdi, %rax 225; X64-NEXT: shrq $4, %rax 226; X64-NEXT: leaq (%rax,%rdi), %rax 227; X64-NEXT: movabsq $1085102592571150095, %rcx # imm = 0xF0F0F0F0F0F0F0F 228; X64-NEXT: andq %rax, %rcx 229; X64-NEXT: movabsq $72340172838076673, %rax # imm = 0x101010101010101 230; X64-NEXT: imulq %rcx, %rax 231; X64-NEXT: shrq $56, %rax 232; X64-NEXT: retq 233; 234; X32-POPCNT-LABEL: cnt64: 235; X32-POPCNT: # %bb.0: 236; X32-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %ecx 237; X32-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax 238; X32-POPCNT-NEXT: addl %ecx, %eax 239; X32-POPCNT-NEXT: xorl %edx, %edx 240; X32-POPCNT-NEXT: retl 241; 242; X64-POPCNT-LABEL: cnt64: 243; X64-POPCNT: # %bb.0: 244; X64-POPCNT-NEXT: popcntq %rdi, %rax 245; X64-POPCNT-NEXT: retq 246 %cnt = tail call i64 @llvm.ctpop.i64(i64 %x) 247 ret i64 %cnt 248} 249 250declare i8 @llvm.ctpop.i8(i8) nounwind readnone 251declare i16 @llvm.ctpop.i16(i16) nounwind readnone 252declare i32 @llvm.ctpop.i32(i32) nounwind readnone 253declare i64 @llvm.ctpop.i64(i64) nounwind readnone 254