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