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
7 define i8 @cnt8(i8 %x) nounwind readnone {
10 ; X32-NEXT: movb {{[0-9]+}}(%esp), %cl
11 ; X32-NEXT: movl %ecx, %eax
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
28 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
29 ; X64-NEXT: movl %edi, %eax
31 ; X64-NEXT: andb $85, %al
32 ; X64-NEXT: subb %al, %dil
33 ; X64-NEXT: movl %edi, %eax
34 ; X64-NEXT: andb $51, %al
35 ; X64-NEXT: shrb $2, %dil
36 ; X64-NEXT: andb $51, %dil
37 ; X64-NEXT: addb %al, %dil
38 ; X64-NEXT: movl %edi, %eax
39 ; X64-NEXT: shrb $4, %al
40 ; X64-NEXT: leal (%rax,%rdi), %eax
41 ; X64-NEXT: andb $15, %al
42 ; X64-NEXT: # kill: def $al killed $al killed $eax
45 ; X32-POPCNT-LABEL: cnt8:
46 ; X32-POPCNT: # %bb.0:
47 ; X32-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax
48 ; X32-POPCNT-NEXT: popcntl %eax, %eax
49 ; X32-POPCNT-NEXT: # kill: def $al killed $al killed $eax
50 ; X32-POPCNT-NEXT: retl
52 ; X64-POPCNT-LABEL: cnt8:
53 ; X64-POPCNT: # %bb.0:
54 ; X64-POPCNT-NEXT: movzbl %dil, %eax
55 ; X64-POPCNT-NEXT: popcntl %eax, %eax
56 ; X64-POPCNT-NEXT: # kill: def $al killed $al killed $eax
57 ; X64-POPCNT-NEXT: retq
58 %cnt = tail call i8 @llvm.ctpop.i8(i8 %x)
62 define i16 @cnt16(i16 %x) nounwind readnone {
65 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
66 ; X32-NEXT: movl %eax, %ecx
68 ; X32-NEXT: andl $21845, %ecx # imm = 0x5555
69 ; X32-NEXT: subl %ecx, %eax
70 ; X32-NEXT: movl %eax, %ecx
71 ; X32-NEXT: andl $13107, %ecx # imm = 0x3333
72 ; X32-NEXT: shrl $2, %eax
73 ; X32-NEXT: andl $13107, %eax # imm = 0x3333
74 ; X32-NEXT: addl %ecx, %eax
75 ; X32-NEXT: movl %eax, %ecx
76 ; X32-NEXT: shrl $4, %ecx
77 ; X32-NEXT: addl %eax, %ecx
78 ; X32-NEXT: andl $3855, %ecx # imm = 0xF0F
79 ; X32-NEXT: movl %ecx, %eax
80 ; X32-NEXT: shll $8, %eax
81 ; X32-NEXT: addl %ecx, %eax
82 ; X32-NEXT: movzbl %ah, %eax
83 ; X32-NEXT: # kill: def $ax killed $ax killed $eax
88 ; X64-NEXT: movl %edi, %eax
90 ; X64-NEXT: andl $21845, %eax # imm = 0x5555
91 ; X64-NEXT: subl %eax, %edi
92 ; X64-NEXT: movl %edi, %eax
93 ; X64-NEXT: andl $13107, %eax # imm = 0x3333
94 ; X64-NEXT: shrl $2, %edi
95 ; X64-NEXT: andl $13107, %edi # imm = 0x3333
96 ; X64-NEXT: addl %eax, %edi
97 ; X64-NEXT: movl %edi, %eax
98 ; X64-NEXT: shrl $4, %eax
99 ; X64-NEXT: addl %edi, %eax
100 ; X64-NEXT: andl $3855, %eax # imm = 0xF0F
101 ; X64-NEXT: movl %eax, %ecx
102 ; X64-NEXT: shll $8, %ecx
103 ; X64-NEXT: addl %eax, %ecx
104 ; X64-NEXT: movzbl %ch, %eax
105 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
108 ; X32-POPCNT-LABEL: cnt16:
109 ; X32-POPCNT: # %bb.0:
110 ; X32-POPCNT-NEXT: popcntw {{[0-9]+}}(%esp), %ax
111 ; X32-POPCNT-NEXT: retl
113 ; X64-POPCNT-LABEL: cnt16:
114 ; X64-POPCNT: # %bb.0:
115 ; X64-POPCNT-NEXT: popcntw %di, %ax
116 ; X64-POPCNT-NEXT: retq
117 %cnt = tail call i16 @llvm.ctpop.i16(i16 %x)
121 define i32 @cnt32(i32 %x) nounwind readnone {
124 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
125 ; X32-NEXT: movl %eax, %ecx
126 ; X32-NEXT: shrl %ecx
127 ; X32-NEXT: andl $1431655765, %ecx # imm = 0x55555555
128 ; X32-NEXT: subl %ecx, %eax
129 ; X32-NEXT: movl %eax, %ecx
130 ; X32-NEXT: andl $858993459, %ecx # imm = 0x33333333
131 ; X32-NEXT: shrl $2, %eax
132 ; X32-NEXT: andl $858993459, %eax # imm = 0x33333333
133 ; X32-NEXT: addl %ecx, %eax
134 ; X32-NEXT: movl %eax, %ecx
135 ; X32-NEXT: shrl $4, %ecx
136 ; X32-NEXT: addl %eax, %ecx
137 ; X32-NEXT: andl $252645135, %ecx # imm = 0xF0F0F0F
138 ; X32-NEXT: imull $16843009, %ecx, %eax # imm = 0x1010101
139 ; X32-NEXT: shrl $24, %eax
144 ; X64-NEXT: movl %edi, %eax
145 ; X64-NEXT: shrl %eax
146 ; X64-NEXT: andl $1431655765, %eax # imm = 0x55555555
147 ; X64-NEXT: subl %eax, %edi
148 ; X64-NEXT: movl %edi, %eax
149 ; X64-NEXT: andl $858993459, %eax # imm = 0x33333333
150 ; X64-NEXT: shrl $2, %edi
151 ; X64-NEXT: andl $858993459, %edi # imm = 0x33333333
152 ; X64-NEXT: addl %eax, %edi
153 ; X64-NEXT: movl %edi, %eax
154 ; X64-NEXT: shrl $4, %eax
155 ; X64-NEXT: addl %edi, %eax
156 ; X64-NEXT: andl $252645135, %eax # imm = 0xF0F0F0F
157 ; X64-NEXT: imull $16843009, %eax, %eax # imm = 0x1010101
158 ; X64-NEXT: shrl $24, %eax
161 ; X32-POPCNT-LABEL: cnt32:
162 ; X32-POPCNT: # %bb.0:
163 ; X32-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax
164 ; X32-POPCNT-NEXT: retl
166 ; X64-POPCNT-LABEL: cnt32:
167 ; X64-POPCNT: # %bb.0:
168 ; X64-POPCNT-NEXT: popcntl %edi, %eax
169 ; X64-POPCNT-NEXT: retq
170 %cnt = tail call i32 @llvm.ctpop.i32(i32 %x)
174 define i64 @cnt64(i64 %x) nounwind readnone {
177 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
178 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
179 ; X32-NEXT: movl %ecx, %edx
180 ; X32-NEXT: shrl %edx
181 ; X32-NEXT: andl $1431655765, %edx # imm = 0x55555555
182 ; X32-NEXT: subl %edx, %ecx
183 ; X32-NEXT: movl %ecx, %edx
184 ; X32-NEXT: andl $858993459, %edx # imm = 0x33333333
185 ; X32-NEXT: shrl $2, %ecx
186 ; X32-NEXT: andl $858993459, %ecx # imm = 0x33333333
187 ; X32-NEXT: addl %edx, %ecx
188 ; X32-NEXT: movl %ecx, %edx
189 ; X32-NEXT: shrl $4, %edx
190 ; X32-NEXT: addl %ecx, %edx
191 ; X32-NEXT: andl $252645135, %edx # imm = 0xF0F0F0F
192 ; X32-NEXT: imull $16843009, %edx, %ecx # imm = 0x1010101
193 ; X32-NEXT: shrl $24, %ecx
194 ; X32-NEXT: movl %eax, %edx
195 ; X32-NEXT: shrl %edx
196 ; X32-NEXT: andl $1431655765, %edx # imm = 0x55555555
197 ; X32-NEXT: subl %edx, %eax
198 ; X32-NEXT: movl %eax, %edx
199 ; X32-NEXT: andl $858993459, %edx # imm = 0x33333333
200 ; X32-NEXT: shrl $2, %eax
201 ; X32-NEXT: andl $858993459, %eax # imm = 0x33333333
202 ; X32-NEXT: addl %edx, %eax
203 ; X32-NEXT: movl %eax, %edx
204 ; X32-NEXT: shrl $4, %edx
205 ; X32-NEXT: addl %eax, %edx
206 ; X32-NEXT: andl $252645135, %edx # imm = 0xF0F0F0F
207 ; X32-NEXT: imull $16843009, %edx, %eax # imm = 0x1010101
208 ; X32-NEXT: shrl $24, %eax
209 ; X32-NEXT: addl %ecx, %eax
210 ; X32-NEXT: xorl %edx, %edx
215 ; X64-NEXT: movq %rdi, %rax
216 ; X64-NEXT: shrq %rax
217 ; X64-NEXT: movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555
218 ; X64-NEXT: andq %rax, %rcx
219 ; X64-NEXT: subq %rcx, %rdi
220 ; X64-NEXT: movabsq $3689348814741910323, %rax # imm = 0x3333333333333333
221 ; X64-NEXT: movq %rdi, %rcx
222 ; X64-NEXT: andq %rax, %rcx
223 ; X64-NEXT: shrq $2, %rdi
224 ; X64-NEXT: andq %rax, %rdi
225 ; X64-NEXT: addq %rcx, %rdi
226 ; X64-NEXT: movq %rdi, %rax
227 ; X64-NEXT: shrq $4, %rax
228 ; X64-NEXT: leaq (%rax,%rdi), %rax
229 ; X64-NEXT: movabsq $1085102592571150095, %rcx # imm = 0xF0F0F0F0F0F0F0F
230 ; X64-NEXT: andq %rax, %rcx
231 ; X64-NEXT: movabsq $72340172838076673, %rax # imm = 0x101010101010101
232 ; X64-NEXT: imulq %rcx, %rax
233 ; X64-NEXT: shrq $56, %rax
236 ; X32-POPCNT-LABEL: cnt64:
237 ; X32-POPCNT: # %bb.0:
238 ; X32-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %ecx
239 ; X32-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax
240 ; X32-POPCNT-NEXT: addl %ecx, %eax
241 ; X32-POPCNT-NEXT: xorl %edx, %edx
242 ; X32-POPCNT-NEXT: retl
244 ; X64-POPCNT-LABEL: cnt64:
245 ; X64-POPCNT: # %bb.0:
246 ; X64-POPCNT-NEXT: popcntq %rdi, %rax
247 ; X64-POPCNT-NEXT: retq
248 %cnt = tail call i64 @llvm.ctpop.i64(i64 %x)
252 declare i8 @llvm.ctpop.i8(i8) nounwind readnone
253 declare i16 @llvm.ctpop.i16(i16) nounwind readnone
254 declare i32 @llvm.ctpop.i32(i32) nounwind readnone
255 declare i64 @llvm.ctpop.i64(i64) nounwind readnone