xref: /llvm-project/llvm/test/CodeGen/X86/ctpop-mask.ll (revision b8c9b0613465b2770d2ae7f61364ddce6bba4511)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown -mattr=+popcnt | FileCheck %s -check-prefixes=X86-POPCOUNT
3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+popcnt | FileCheck %s -check-prefixes=X64-POPCOUNT
4; RUN: llc < %s -mtriple=i686-unknown -mattr=-popcnt | FileCheck %s -check-prefixes=X86-NO-POPCOUNT
5; RUN: llc < %s -mtriple=i686-unknown -mattr=+sse2 -mattr=-popcnt | FileCheck %s -check-prefixes=X86-NO-POPCOUNT
6; RUN: llc < %s -mtriple=x86_64-unknown -mattr=-popcnt | FileCheck %s -check-prefixes=X64-NO-POPCOUNT
7
8declare i8 @llvm.ctpop.i8(i8) nounwind readnone
9declare i16 @llvm.ctpop.i16(i16) nounwind readnone
10declare i32 @llvm.ctpop.i32(i32) nounwind readnone
11declare i64 @llvm.ctpop.i64(i64) nounwind readnone
12
13; PR79823
14; CTPOP tests where we know only some bits are non-zero.
15; FIXME: Move shifted masked values to lsb to use smaller bitsize special cases.
16
17define i64 @ctpop_mask2(i64 %x) nounwind readnone {
18; X86-POPCOUNT-LABEL: ctpop_mask2:
19; X86-POPCOUNT:       # %bb.0:
20; X86-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
21; X86-POPCOUNT-NEXT:    andl $3, %eax
22; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
23; X86-POPCOUNT-NEXT:    xorl %edx, %edx
24; X86-POPCOUNT-NEXT:    retl
25;
26; X64-POPCOUNT-LABEL: ctpop_mask2:
27; X64-POPCOUNT:       # %bb.0:
28; X64-POPCOUNT-NEXT:    andl $3, %edi
29; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
30; X64-POPCOUNT-NEXT:    retq
31;
32; X86-NO-POPCOUNT-LABEL: ctpop_mask2:
33; X86-NO-POPCOUNT:       # %bb.0:
34; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
35; X86-NO-POPCOUNT-NEXT:    andl $3, %eax
36; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
37; X86-NO-POPCOUNT-NEXT:    shrl %ecx
38; X86-NO-POPCOUNT-NEXT:    subl %ecx, %eax
39; X86-NO-POPCOUNT-NEXT:    xorl %edx, %edx
40; X86-NO-POPCOUNT-NEXT:    retl
41;
42; X64-NO-POPCOUNT-LABEL: ctpop_mask2:
43; X64-NO-POPCOUNT:       # %bb.0:
44; X64-NO-POPCOUNT-NEXT:    movq %rdi, %rax
45; X64-NO-POPCOUNT-NEXT:    andl $3, %eax
46; X64-NO-POPCOUNT-NEXT:    movl %eax, %ecx
47; X64-NO-POPCOUNT-NEXT:    shrl %ecx
48; X64-NO-POPCOUNT-NEXT:    subl %ecx, %eax
49; X64-NO-POPCOUNT-NEXT:    retq
50  %mask = and i64 %x, 3
51  %count = tail call i64 @llvm.ctpop.i64(i64 %mask)
52  ret i64 %count
53}
54
55define i32 @ctpop_shifted_mask2(i32 %x) nounwind readnone {
56; X86-POPCOUNT-LABEL: ctpop_shifted_mask2:
57; X86-POPCOUNT:       # %bb.0:
58; X86-POPCOUNT-NEXT:    movl $1572864, %eax # imm = 0x180000
59; X86-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
60; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
61; X86-POPCOUNT-NEXT:    retl
62;
63; X64-POPCOUNT-LABEL: ctpop_shifted_mask2:
64; X64-POPCOUNT:       # %bb.0:
65; X64-POPCOUNT-NEXT:    andl $1572864, %edi # imm = 0x180000
66; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
67; X64-POPCOUNT-NEXT:    retq
68;
69; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask2:
70; X86-NO-POPCOUNT:       # %bb.0:
71; X86-NO-POPCOUNT-NEXT:    movl $1572864, %eax # imm = 0x180000
72; X86-NO-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
73; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
74; X86-NO-POPCOUNT-NEXT:    shrl $20, %ecx
75; X86-NO-POPCOUNT-NEXT:    shrl $19, %eax
76; X86-NO-POPCOUNT-NEXT:    subl %ecx, %eax
77; X86-NO-POPCOUNT-NEXT:    retl
78;
79; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask2:
80; X64-NO-POPCOUNT:       # %bb.0:
81; X64-NO-POPCOUNT-NEXT:    movl %edi, %eax
82; X64-NO-POPCOUNT-NEXT:    andl $1572864, %eax # imm = 0x180000
83; X64-NO-POPCOUNT-NEXT:    movl %eax, %ecx
84; X64-NO-POPCOUNT-NEXT:    shrl $20, %ecx
85; X64-NO-POPCOUNT-NEXT:    shrl $19, %eax
86; X64-NO-POPCOUNT-NEXT:    subl %ecx, %eax
87; X64-NO-POPCOUNT-NEXT:    retq
88  %mask = and i32 %x, 1572864 ; 3 << 19
89  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
90  ret i32 %count
91}
92
93define i32 @ctpop_mask3(i32 %x) nounwind readnone {
94; X86-POPCOUNT-LABEL: ctpop_mask3:
95; X86-POPCOUNT:       # %bb.0:
96; X86-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
97; X86-POPCOUNT-NEXT:    andl $5, %eax
98; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
99; X86-POPCOUNT-NEXT:    retl
100;
101; X64-POPCOUNT-LABEL: ctpop_mask3:
102; X64-POPCOUNT:       # %bb.0:
103; X64-POPCOUNT-NEXT:    andl $5, %edi
104; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
105; X64-POPCOUNT-NEXT:    retq
106;
107; X86-NO-POPCOUNT-LABEL: ctpop_mask3:
108; X86-NO-POPCOUNT:       # %bb.0:
109; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %ecx
110; X86-NO-POPCOUNT-NEXT:    andl $5, %ecx
111; X86-NO-POPCOUNT-NEXT:    addl %ecx, %ecx
112; X86-NO-POPCOUNT-NEXT:    movl $59796, %eax # imm = 0xE994
113; X86-NO-POPCOUNT-NEXT:    # kill: def $cl killed $cl killed $ecx
114; X86-NO-POPCOUNT-NEXT:    shrl %cl, %eax
115; X86-NO-POPCOUNT-NEXT:    andl $3, %eax
116; X86-NO-POPCOUNT-NEXT:    retl
117;
118; X64-NO-POPCOUNT-LABEL: ctpop_mask3:
119; X64-NO-POPCOUNT:       # %bb.0:
120; X64-NO-POPCOUNT-NEXT:    # kill: def $edi killed $edi def $rdi
121; X64-NO-POPCOUNT-NEXT:    andl $5, %edi
122; X64-NO-POPCOUNT-NEXT:    leal (%rdi,%rdi), %ecx
123; X64-NO-POPCOUNT-NEXT:    movl $59796, %eax # imm = 0xE994
124; X64-NO-POPCOUNT-NEXT:    # kill: def $cl killed $cl killed $ecx
125; X64-NO-POPCOUNT-NEXT:    shrl %cl, %eax
126; X64-NO-POPCOUNT-NEXT:    andl $3, %eax
127; X64-NO-POPCOUNT-NEXT:    retq
128  %mask = and i32 %x, 5 ; 0b101
129  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
130  ret i32 %count
131}
132
133define i16 @ctpop_shifted_mask3(i16 %x) nounwind readnone {
134; X86-POPCOUNT-LABEL: ctpop_shifted_mask3:
135; X86-POPCOUNT:       # %bb.0:
136; X86-POPCOUNT-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
137; X86-POPCOUNT-NEXT:    andl $14, %eax
138; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
139; X86-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
140; X86-POPCOUNT-NEXT:    retl
141;
142; X64-POPCOUNT-LABEL: ctpop_shifted_mask3:
143; X64-POPCOUNT:       # %bb.0:
144; X64-POPCOUNT-NEXT:    andl $14, %edi
145; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
146; X64-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
147; X64-POPCOUNT-NEXT:    retq
148;
149; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask3:
150; X86-NO-POPCOUNT:       # %bb.0:
151; X86-NO-POPCOUNT-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
152; X86-NO-POPCOUNT-NEXT:    andl $14, %ecx
153; X86-NO-POPCOUNT-NEXT:    movl $59796, %eax # imm = 0xE994
154; X86-NO-POPCOUNT-NEXT:    # kill: def $cl killed $cl killed $ecx
155; X86-NO-POPCOUNT-NEXT:    shrl %cl, %eax
156; X86-NO-POPCOUNT-NEXT:    andl $3, %eax
157; X86-NO-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
158; X86-NO-POPCOUNT-NEXT:    retl
159;
160; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask3:
161; X64-NO-POPCOUNT:       # %bb.0:
162; X64-NO-POPCOUNT-NEXT:    movl %edi, %ecx
163; X64-NO-POPCOUNT-NEXT:    andl $14, %ecx
164; X64-NO-POPCOUNT-NEXT:    movl $59796, %eax # imm = 0xE994
165; X64-NO-POPCOUNT-NEXT:    # kill: def $cl killed $cl killed $ecx
166; X64-NO-POPCOUNT-NEXT:    shrl %cl, %eax
167; X64-NO-POPCOUNT-NEXT:    andl $3, %eax
168; X64-NO-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
169; X64-NO-POPCOUNT-NEXT:    retq
170  %mask = and i16 %x, 14 ; 7 << 1
171  %count = tail call i16 @llvm.ctpop.i16(i16 %mask)
172  ret i16 %count
173}
174
175define i64 @ctpop_mask4(i64 %x) nounwind readnone {
176; X86-POPCOUNT-LABEL: ctpop_mask4:
177; X86-POPCOUNT:       # %bb.0:
178; X86-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
179; X86-POPCOUNT-NEXT:    andl $15, %eax
180; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
181; X86-POPCOUNT-NEXT:    xorl %edx, %edx
182; X86-POPCOUNT-NEXT:    retl
183;
184; X64-POPCOUNT-LABEL: ctpop_mask4:
185; X64-POPCOUNT:       # %bb.0:
186; X64-POPCOUNT-NEXT:    andl $15, %edi
187; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
188; X64-POPCOUNT-NEXT:    retq
189;
190; X86-NO-POPCOUNT-LABEL: ctpop_mask4:
191; X86-NO-POPCOUNT:       # %bb.0:
192; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
193; X86-NO-POPCOUNT-NEXT:    andl $15, %eax
194; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
195; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
196; X86-NO-POPCOUNT-NEXT:    andl $17895697, %eax # imm = 0x1111111
197; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
198; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
199; X86-NO-POPCOUNT-NEXT:    xorl %edx, %edx
200; X86-NO-POPCOUNT-NEXT:    retl
201;
202; X64-NO-POPCOUNT-LABEL: ctpop_mask4:
203; X64-NO-POPCOUNT:       # %bb.0:
204; X64-NO-POPCOUNT-NEXT:    andl $15, %edi
205; X64-NO-POPCOUNT-NEXT:    leal (,%rdi,4), %ecx
206; X64-NO-POPCOUNT-NEXT:    movabsq $4841987667533046032, %rax # imm = 0x4332322132212110
207; X64-NO-POPCOUNT-NEXT:    # kill: def $cl killed $cl killed $ecx
208; X64-NO-POPCOUNT-NEXT:    shrq %cl, %rax
209; X64-NO-POPCOUNT-NEXT:    andl $7, %eax
210; X64-NO-POPCOUNT-NEXT:    retq
211  %mask = and i64 %x, 15
212  %count = tail call i64 @llvm.ctpop.i64(i64 %mask)
213  ret i64 %count
214}
215
216define i32 @ctpop_shifted_mask4(i32 %x) nounwind readnone {
217; X86-POPCOUNT-LABEL: ctpop_shifted_mask4:
218; X86-POPCOUNT:       # %bb.0:
219; X86-POPCOUNT-NEXT:    movl $7680, %eax # imm = 0x1E00
220; X86-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
221; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
222; X86-POPCOUNT-NEXT:    retl
223;
224; X64-POPCOUNT-LABEL: ctpop_shifted_mask4:
225; X64-POPCOUNT:       # %bb.0:
226; X64-POPCOUNT-NEXT:    andl $7680, %edi # imm = 0x1E00
227; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
228; X64-POPCOUNT-NEXT:    retq
229;
230; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask4:
231; X86-NO-POPCOUNT:       # %bb.0:
232; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
233; X86-NO-POPCOUNT-NEXT:    shrl $9, %eax
234; X86-NO-POPCOUNT-NEXT:    andl $15, %eax
235; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
236; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
237; X86-NO-POPCOUNT-NEXT:    andl $17895697, %eax # imm = 0x1111111
238; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
239; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
240; X86-NO-POPCOUNT-NEXT:    retl
241;
242; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask4:
243; X64-NO-POPCOUNT:       # %bb.0:
244; X64-NO-POPCOUNT-NEXT:    movl %edi, %ecx
245; X64-NO-POPCOUNT-NEXT:    shrl $7, %ecx
246; X64-NO-POPCOUNT-NEXT:    andl $60, %ecx
247; X64-NO-POPCOUNT-NEXT:    movabsq $4841987667533046032, %rax # imm = 0x4332322132212110
248; X64-NO-POPCOUNT-NEXT:    # kill: def $cl killed $cl killed $ecx
249; X64-NO-POPCOUNT-NEXT:    shrq %cl, %rax
250; X64-NO-POPCOUNT-NEXT:    andl $7, %eax
251; X64-NO-POPCOUNT-NEXT:    # kill: def $eax killed $eax killed $rax
252; X64-NO-POPCOUNT-NEXT:    retq
253  %mask = and i32 %x, 7680 ; 15 << 9
254  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
255  ret i32 %count
256}
257
258define i64 @ctpop_mask5(i64 %x) nounwind readnone {
259; X86-POPCOUNT-LABEL: ctpop_mask5:
260; X86-POPCOUNT:       # %bb.0:
261; X86-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
262; X86-POPCOUNT-NEXT:    andl $31, %eax
263; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
264; X86-POPCOUNT-NEXT:    xorl %edx, %edx
265; X86-POPCOUNT-NEXT:    retl
266;
267; X64-POPCOUNT-LABEL: ctpop_mask5:
268; X64-POPCOUNT:       # %bb.0:
269; X64-POPCOUNT-NEXT:    andl $31, %edi
270; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
271; X64-POPCOUNT-NEXT:    retq
272;
273; X86-NO-POPCOUNT-LABEL: ctpop_mask5:
274; X86-NO-POPCOUNT:       # %bb.0:
275; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
276; X86-NO-POPCOUNT-NEXT:    andl $31, %eax
277; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
278; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
279; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
280; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
281; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
282; X86-NO-POPCOUNT-NEXT:    xorl %edx, %edx
283; X86-NO-POPCOUNT-NEXT:    retl
284;
285; X64-NO-POPCOUNT-LABEL: ctpop_mask5:
286; X64-NO-POPCOUNT:       # %bb.0:
287; X64-NO-POPCOUNT-NEXT:    andl $31, %edi
288; X64-NO-POPCOUNT-NEXT:    imull $134480385, %edi, %eax # imm = 0x8040201
289; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
290; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
291; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
292; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
293; X64-NO-POPCOUNT-NEXT:    retq
294  %mask = and i64 %x, 31
295  %count = tail call i64 @llvm.ctpop.i64(i64 %mask)
296  ret i64 %count
297}
298
299define i32 @ctpop_shifted_mask5(i32 %x) nounwind readnone {
300; X86-POPCOUNT-LABEL: ctpop_shifted_mask5:
301; X86-POPCOUNT:       # %bb.0:
302; X86-POPCOUNT-NEXT:    movl $11776, %eax # imm = 0x2E00
303; X86-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
304; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
305; X86-POPCOUNT-NEXT:    retl
306;
307; X64-POPCOUNT-LABEL: ctpop_shifted_mask5:
308; X64-POPCOUNT:       # %bb.0:
309; X64-POPCOUNT-NEXT:    andl $11776, %edi # imm = 0x2E00
310; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
311; X64-POPCOUNT-NEXT:    retq
312;
313; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask5:
314; X86-NO-POPCOUNT:       # %bb.0:
315; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
316; X86-NO-POPCOUNT-NEXT:    shrl $9, %eax
317; X86-NO-POPCOUNT-NEXT:    andl $23, %eax
318; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
319; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
320; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
321; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
322; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
323; X86-NO-POPCOUNT-NEXT:    retl
324;
325; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask5:
326; X64-NO-POPCOUNT:       # %bb.0:
327; X64-NO-POPCOUNT-NEXT:    shrl $9, %edi
328; X64-NO-POPCOUNT-NEXT:    andl $23, %edi
329; X64-NO-POPCOUNT-NEXT:    imull $134480385, %edi, %eax # imm = 0x8040201
330; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
331; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
332; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
333; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
334; X64-NO-POPCOUNT-NEXT:    retq
335  %mask = and i32 %x, 11776 ; 23 << 9
336  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
337  ret i32 %count
338}
339
340define i32 @ctpop_mask6(i32 %x) nounwind readnone {
341; X86-POPCOUNT-LABEL: ctpop_mask6:
342; X86-POPCOUNT:       # %bb.0:
343; X86-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
344; X86-POPCOUNT-NEXT:    andl $63, %eax
345; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
346; X86-POPCOUNT-NEXT:    retl
347;
348; X64-POPCOUNT-LABEL: ctpop_mask6:
349; X64-POPCOUNT:       # %bb.0:
350; X64-POPCOUNT-NEXT:    andl $63, %edi
351; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
352; X64-POPCOUNT-NEXT:    retq
353;
354; X86-NO-POPCOUNT-LABEL: ctpop_mask6:
355; X86-NO-POPCOUNT:       # %bb.0:
356; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
357; X86-NO-POPCOUNT-NEXT:    andl $63, %eax
358; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
359; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
360; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
361; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
362; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
363; X86-NO-POPCOUNT-NEXT:    retl
364;
365; X64-NO-POPCOUNT-LABEL: ctpop_mask6:
366; X64-NO-POPCOUNT:       # %bb.0:
367; X64-NO-POPCOUNT-NEXT:    andl $63, %edi
368; X64-NO-POPCOUNT-NEXT:    imull $134480385, %edi, %eax # imm = 0x8040201
369; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
370; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
371; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
372; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
373; X64-NO-POPCOUNT-NEXT:    retq
374  %mask = and i32 %x, 63
375  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
376  ret i32 %count
377}
378
379define i64 @ctpop_shifted_mask6(i64 %x) nounwind readnone {
380; X86-POPCOUNT-LABEL: ctpop_shifted_mask6:
381; X86-POPCOUNT:       # %bb.0:
382; X86-POPCOUNT-NEXT:    movl $26112, %eax # imm = 0x6600
383; X86-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
384; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
385; X86-POPCOUNT-NEXT:    xorl %edx, %edx
386; X86-POPCOUNT-NEXT:    retl
387;
388; X64-POPCOUNT-LABEL: ctpop_shifted_mask6:
389; X64-POPCOUNT:       # %bb.0:
390; X64-POPCOUNT-NEXT:    andl $26112, %edi # imm = 0x6600
391; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
392; X64-POPCOUNT-NEXT:    retq
393;
394; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask6:
395; X86-NO-POPCOUNT:       # %bb.0:
396; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
397; X86-NO-POPCOUNT-NEXT:    shrl $9, %eax
398; X86-NO-POPCOUNT-NEXT:    andl $51, %eax
399; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
400; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
401; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
402; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
403; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
404; X86-NO-POPCOUNT-NEXT:    xorl %edx, %edx
405; X86-NO-POPCOUNT-NEXT:    retl
406;
407; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask6:
408; X64-NO-POPCOUNT:       # %bb.0:
409; X64-NO-POPCOUNT-NEXT:    shrl $9, %edi
410; X64-NO-POPCOUNT-NEXT:    andl $51, %edi
411; X64-NO-POPCOUNT-NEXT:    imull $134480385, %edi, %eax # imm = 0x8040201
412; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
413; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
414; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
415; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
416; X64-NO-POPCOUNT-NEXT:    retq
417  %mask = and i64 %x, 26112 ; 51 << 9
418  %count = tail call i64 @llvm.ctpop.i64(i64 %mask)
419  ret i64 %count
420}
421
422define i16 @ctpop_mask7(i16 %x) nounwind readnone {
423; X86-POPCOUNT-LABEL: ctpop_mask7:
424; X86-POPCOUNT:       # %bb.0:
425; X86-POPCOUNT-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
426; X86-POPCOUNT-NEXT:    andl $127, %eax
427; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
428; X86-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
429; X86-POPCOUNT-NEXT:    retl
430;
431; X64-POPCOUNT-LABEL: ctpop_mask7:
432; X64-POPCOUNT:       # %bb.0:
433; X64-POPCOUNT-NEXT:    andl $127, %edi
434; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
435; X64-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
436; X64-POPCOUNT-NEXT:    retq
437;
438; X86-NO-POPCOUNT-LABEL: ctpop_mask7:
439; X86-NO-POPCOUNT:       # %bb.0:
440; X86-NO-POPCOUNT-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
441; X86-NO-POPCOUNT-NEXT:    andl $127, %eax
442; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
443; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
444; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
445; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
446; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
447; X86-NO-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
448; X86-NO-POPCOUNT-NEXT:    retl
449;
450; X64-NO-POPCOUNT-LABEL: ctpop_mask7:
451; X64-NO-POPCOUNT:       # %bb.0:
452; X64-NO-POPCOUNT-NEXT:    andl $127, %edi
453; X64-NO-POPCOUNT-NEXT:    imull $134480385, %edi, %eax # imm = 0x8040201
454; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
455; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
456; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
457; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
458; X64-NO-POPCOUNT-NEXT:    # kill: def $ax killed $ax killed $eax
459; X64-NO-POPCOUNT-NEXT:    retq
460  %mask = and i16 %x, 127
461  %count = tail call i16 @llvm.ctpop.i16(i16 %mask)
462  ret i16 %count
463}
464
465define i32 @ctpop_shift_mask7(i32 %x) nounwind readnone {
466; X86-POPCOUNT-LABEL: ctpop_shift_mask7:
467; X86-POPCOUNT:       # %bb.0:
468; X86-POPCOUNT-NEXT:    movl $1040384, %eax # imm = 0xFE000
469; X86-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
470; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
471; X86-POPCOUNT-NEXT:    retl
472;
473; X64-POPCOUNT-LABEL: ctpop_shift_mask7:
474; X64-POPCOUNT:       # %bb.0:
475; X64-POPCOUNT-NEXT:    andl $1040384, %edi # imm = 0xFE000
476; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
477; X64-POPCOUNT-NEXT:    retq
478;
479; X86-NO-POPCOUNT-LABEL: ctpop_shift_mask7:
480; X86-NO-POPCOUNT:       # %bb.0:
481; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %eax
482; X86-NO-POPCOUNT-NEXT:    shrl $13, %eax
483; X86-NO-POPCOUNT-NEXT:    andl $127, %eax
484; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
485; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
486; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
487; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
488; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
489; X86-NO-POPCOUNT-NEXT:    retl
490;
491; X64-NO-POPCOUNT-LABEL: ctpop_shift_mask7:
492; X64-NO-POPCOUNT:       # %bb.0:
493; X64-NO-POPCOUNT-NEXT:    shrl $13, %edi
494; X64-NO-POPCOUNT-NEXT:    andl $127, %edi
495; X64-NO-POPCOUNT-NEXT:    imull $134480385, %edi, %eax # imm = 0x8040201
496; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
497; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
498; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
499; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
500; X64-NO-POPCOUNT-NEXT:    retq
501  %mask = and i32 %x, 1040384 ; 127 << 13
502  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
503  ret i32 %count
504}
505
506define i32 @ctpop_mask8(i32 %x) nounwind readnone {
507; X86-POPCOUNT-LABEL: ctpop_mask8:
508; X86-POPCOUNT:       # %bb.0:
509; X86-POPCOUNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
510; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
511; X86-POPCOUNT-NEXT:    retl
512;
513; X64-POPCOUNT-LABEL: ctpop_mask8:
514; X64-POPCOUNT:       # %bb.0:
515; X64-POPCOUNT-NEXT:    movzbl %dil, %eax
516; X64-POPCOUNT-NEXT:    popcntl %eax, %eax
517; X64-POPCOUNT-NEXT:    retq
518;
519; X86-NO-POPCOUNT-LABEL: ctpop_mask8:
520; X86-NO-POPCOUNT:       # %bb.0:
521; X86-NO-POPCOUNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
522; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
523; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
524; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
525; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
526; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
527; X86-NO-POPCOUNT-NEXT:    retl
528;
529; X64-NO-POPCOUNT-LABEL: ctpop_mask8:
530; X64-NO-POPCOUNT:       # %bb.0:
531; X64-NO-POPCOUNT-NEXT:    movzbl %dil, %eax
532; X64-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
533; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
534; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
535; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
536; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
537; X64-NO-POPCOUNT-NEXT:    retq
538  %mask = and i32 %x, 255
539  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
540  ret i32 %count
541}
542
543define i64 @ctpop_shifted_mask8(i64 %x) nounwind readnone {
544; X86-POPCOUNT-LABEL: ctpop_shifted_mask8:
545; X86-POPCOUNT:       # %bb.0:
546; X86-POPCOUNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
547; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
548; X86-POPCOUNT-NEXT:    xorl %edx, %edx
549; X86-POPCOUNT-NEXT:    retl
550;
551; X64-POPCOUNT-LABEL: ctpop_shifted_mask8:
552; X64-POPCOUNT:       # %bb.0:
553; X64-POPCOUNT-NEXT:    andl $65280, %edi # imm = 0xFF00
554; X64-POPCOUNT-NEXT:    popcntl %edi, %eax
555; X64-POPCOUNT-NEXT:    retq
556;
557; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask8:
558; X86-NO-POPCOUNT:       # %bb.0:
559; X86-NO-POPCOUNT-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
560; X86-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
561; X86-NO-POPCOUNT-NEXT:    shrl $3, %eax
562; X86-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
563; X86-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
564; X86-NO-POPCOUNT-NEXT:    shrl $28, %eax
565; X86-NO-POPCOUNT-NEXT:    xorl %edx, %edx
566; X86-NO-POPCOUNT-NEXT:    retl
567;
568; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask8:
569; X64-NO-POPCOUNT:       # %bb.0:
570; X64-NO-POPCOUNT-NEXT:    movq %rdi, %rax
571; X64-NO-POPCOUNT-NEXT:    movzbl %ah, %eax
572; X64-NO-POPCOUNT-NEXT:    imull $134480385, %eax, %eax # imm = 0x8040201
573; X64-NO-POPCOUNT-NEXT:    shrl $3, %eax
574; X64-NO-POPCOUNT-NEXT:    andl $286331153, %eax # imm = 0x11111111
575; X64-NO-POPCOUNT-NEXT:    imull $286331153, %eax, %eax # imm = 0x11111111
576; X64-NO-POPCOUNT-NEXT:    shrl $28, %eax
577; X64-NO-POPCOUNT-NEXT:    retq
578  %mask = and i64 %x, 65280 ; 255 << 8
579  %count = tail call i64 @llvm.ctpop.i64(i64 %mask)
580  ret i64 %count
581}
582
583define i32 @ctpop_mask16(i32 %x) nounwind readnone {
584; X86-POPCOUNT-LABEL: ctpop_mask16:
585; X86-POPCOUNT:       # %bb.0:
586; X86-POPCOUNT-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
587; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
588; X86-POPCOUNT-NEXT:    retl
589;
590; X64-POPCOUNT-LABEL: ctpop_mask16:
591; X64-POPCOUNT:       # %bb.0:
592; X64-POPCOUNT-NEXT:    movzwl %di, %eax
593; X64-POPCOUNT-NEXT:    popcntl %eax, %eax
594; X64-POPCOUNT-NEXT:    retq
595;
596; X86-NO-POPCOUNT-LABEL: ctpop_mask16:
597; X86-NO-POPCOUNT:       # %bb.0:
598; X86-NO-POPCOUNT-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
599; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
600; X86-NO-POPCOUNT-NEXT:    shrl %ecx
601; X86-NO-POPCOUNT-NEXT:    andl $21845, %ecx # imm = 0x5555
602; X86-NO-POPCOUNT-NEXT:    subl %ecx, %eax
603; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
604; X86-NO-POPCOUNT-NEXT:    andl $858993459, %ecx # imm = 0x33333333
605; X86-NO-POPCOUNT-NEXT:    shrl $2, %eax
606; X86-NO-POPCOUNT-NEXT:    andl $858993459, %eax # imm = 0x33333333
607; X86-NO-POPCOUNT-NEXT:    addl %ecx, %eax
608; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
609; X86-NO-POPCOUNT-NEXT:    shrl $4, %ecx
610; X86-NO-POPCOUNT-NEXT:    addl %eax, %ecx
611; X86-NO-POPCOUNT-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
612; X86-NO-POPCOUNT-NEXT:    imull $16843009, %ecx, %eax # imm = 0x1010101
613; X86-NO-POPCOUNT-NEXT:    shrl $24, %eax
614; X86-NO-POPCOUNT-NEXT:    retl
615;
616; X64-NO-POPCOUNT-LABEL: ctpop_mask16:
617; X64-NO-POPCOUNT:       # %bb.0:
618; X64-NO-POPCOUNT-NEXT:    movzwl %di, %eax
619; X64-NO-POPCOUNT-NEXT:    shrl %edi
620; X64-NO-POPCOUNT-NEXT:    andl $21845, %edi # imm = 0x5555
621; X64-NO-POPCOUNT-NEXT:    subl %edi, %eax
622; X64-NO-POPCOUNT-NEXT:    movl %eax, %ecx
623; X64-NO-POPCOUNT-NEXT:    andl $858993459, %ecx # imm = 0x33333333
624; X64-NO-POPCOUNT-NEXT:    shrl $2, %eax
625; X64-NO-POPCOUNT-NEXT:    andl $858993459, %eax # imm = 0x33333333
626; X64-NO-POPCOUNT-NEXT:    addl %ecx, %eax
627; X64-NO-POPCOUNT-NEXT:    movl %eax, %ecx
628; X64-NO-POPCOUNT-NEXT:    shrl $4, %ecx
629; X64-NO-POPCOUNT-NEXT:    addl %eax, %ecx
630; X64-NO-POPCOUNT-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
631; X64-NO-POPCOUNT-NEXT:    imull $16843009, %ecx, %eax # imm = 0x1010101
632; X64-NO-POPCOUNT-NEXT:    shrl $24, %eax
633; X64-NO-POPCOUNT-NEXT:    retq
634  %mask = and i32 %x, 65535
635  %count = tail call i32 @llvm.ctpop.i32(i32 %mask)
636  ret i32 %count
637}
638
639define i64 @ctpop_shifted_mask16(i64 %x) nounwind readnone {
640; X86-POPCOUNT-LABEL: ctpop_shifted_mask16:
641; X86-POPCOUNT:       # %bb.0:
642; X86-POPCOUNT-NEXT:    movl $524280, %eax # imm = 0x7FFF8
643; X86-POPCOUNT-NEXT:    andl {{[0-9]+}}(%esp), %eax
644; X86-POPCOUNT-NEXT:    popcntl %eax, %eax
645; X86-POPCOUNT-NEXT:    xorl %edx, %edx
646; X86-POPCOUNT-NEXT:    retl
647;
648; X64-POPCOUNT-LABEL: ctpop_shifted_mask16:
649; X64-POPCOUNT:       # %bb.0:
650; X64-POPCOUNT-NEXT:    movabsq $2251765453946880, %rax # imm = 0x7FFF800000000
651; X64-POPCOUNT-NEXT:    andq %rdi, %rax
652; X64-POPCOUNT-NEXT:    popcntq %rax, %rax
653; X64-POPCOUNT-NEXT:    retq
654;
655; X86-NO-POPCOUNT-LABEL: ctpop_shifted_mask16:
656; X86-NO-POPCOUNT:       # %bb.0:
657; X86-NO-POPCOUNT-NEXT:    movl {{[0-9]+}}(%esp), %ecx
658; X86-NO-POPCOUNT-NEXT:    movl %ecx, %eax
659; X86-NO-POPCOUNT-NEXT:    andl $524280, %eax # imm = 0x7FFF8
660; X86-NO-POPCOUNT-NEXT:    shrl %ecx
661; X86-NO-POPCOUNT-NEXT:    andl $87380, %ecx # imm = 0x15554
662; X86-NO-POPCOUNT-NEXT:    subl %ecx, %eax
663; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
664; X86-NO-POPCOUNT-NEXT:    andl $858993456, %ecx # imm = 0x33333330
665; X86-NO-POPCOUNT-NEXT:    shrl $2, %eax
666; X86-NO-POPCOUNT-NEXT:    andl $858993459, %eax # imm = 0x33333333
667; X86-NO-POPCOUNT-NEXT:    addl %ecx, %eax
668; X86-NO-POPCOUNT-NEXT:    movl %eax, %ecx
669; X86-NO-POPCOUNT-NEXT:    shrl $4, %ecx
670; X86-NO-POPCOUNT-NEXT:    addl %eax, %ecx
671; X86-NO-POPCOUNT-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
672; X86-NO-POPCOUNT-NEXT:    imull $16843009, %ecx, %eax # imm = 0x1010101
673; X86-NO-POPCOUNT-NEXT:    shrl $24, %eax
674; X86-NO-POPCOUNT-NEXT:    xorl %edx, %edx
675; X86-NO-POPCOUNT-NEXT:    retl
676;
677; X64-NO-POPCOUNT-LABEL: ctpop_shifted_mask16:
678; X64-NO-POPCOUNT:       # %bb.0:
679; X64-NO-POPCOUNT-NEXT:    movabsq $2251765453946880, %rax # imm = 0x7FFF800000000
680; X64-NO-POPCOUNT-NEXT:    andq %rdi, %rax
681; X64-NO-POPCOUNT-NEXT:    shrq %rdi
682; X64-NO-POPCOUNT-NEXT:    movabsq $375294242324480, %rcx # imm = 0x1555400000000
683; X64-NO-POPCOUNT-NEXT:    andq %rdi, %rcx
684; X64-NO-POPCOUNT-NEXT:    subq %rcx, %rax
685; X64-NO-POPCOUNT-NEXT:    movabsq $3689348800998014976, %rcx # imm = 0x3333333000000000
686; X64-NO-POPCOUNT-NEXT:    andq %rax, %rcx
687; X64-NO-POPCOUNT-NEXT:    shrq $2, %rax
688; X64-NO-POPCOUNT-NEXT:    movabsq $3689348813882916864, %rdx # imm = 0x3333333300000000
689; X64-NO-POPCOUNT-NEXT:    andq %rax, %rdx
690; X64-NO-POPCOUNT-NEXT:    addq %rcx, %rdx
691; X64-NO-POPCOUNT-NEXT:    movq %rdx, %rax
692; X64-NO-POPCOUNT-NEXT:    shrq $4, %rax
693; X64-NO-POPCOUNT-NEXT:    addq %rdx, %rax
694; X64-NO-POPCOUNT-NEXT:    movabsq $1085102592571150095, %rcx # imm = 0xF0F0F0F0F0F0F0F
695; X64-NO-POPCOUNT-NEXT:    andq %rax, %rcx
696; X64-NO-POPCOUNT-NEXT:    movabsq $72340172838076673, %rax # imm = 0x101010101010101
697; X64-NO-POPCOUNT-NEXT:    imulq %rcx, %rax
698; X64-NO-POPCOUNT-NEXT:    shrq $56, %rax
699; X64-NO-POPCOUNT-NEXT:    retq
700  %mask = and i64 %x, 2251765453946880 ; 65535 << 35
701  %count = tail call i64 @llvm.ctpop.i64(i64 %mask)
702  ret i64 %count
703}
704