xref: /llvm-project/llvm/test/CodeGen/X86/parity-vec.ll (revision 1c4880a2d39fbd95edced0dd97c34a9f53bf62ff)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-popcnt,+sse2 | FileCheck %s --check-prefix=NOPOPCNT
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+popcnt,+sse2 | FileCheck %s --check-prefix=POPCNT
4
5define i1 @noncanonical_parity(<16 x i1> %x) {
6; NOPOPCNT-LABEL: noncanonical_parity:
7; NOPOPCNT:       # %bb.0:
8; NOPOPCNT-NEXT:    psllw $7, %xmm0
9; NOPOPCNT-NEXT:    pmovmskb %xmm0, %eax
10; NOPOPCNT-NEXT:    xorb %ah, %al
11; NOPOPCNT-NEXT:    setnp %al
12; NOPOPCNT-NEXT:    retq
13;
14; POPCNT-LABEL: noncanonical_parity:
15; POPCNT:       # %bb.0:
16; POPCNT-NEXT:    psllw $7, %xmm0
17; POPCNT-NEXT:    pmovmskb %xmm0, %eax
18; POPCNT-NEXT:    popcntl %eax, %eax
19; POPCNT-NEXT:    andl $1, %eax
20; POPCNT-NEXT:    # kill: def $al killed $al killed $eax
21; POPCNT-NEXT:    retq
22  %r = call i1 @llvm.vector.reduce.xor.v16i1(<16 x i1> %x)
23  ret i1 %r
24}
25define i1 @canonical_parity(<16 x i1> %x) {
26; NOPOPCNT-LABEL: canonical_parity:
27; NOPOPCNT:       # %bb.0:
28; NOPOPCNT-NEXT:    psllw $7, %xmm0
29; NOPOPCNT-NEXT:    pmovmskb %xmm0, %eax
30; NOPOPCNT-NEXT:    xorb %ah, %al
31; NOPOPCNT-NEXT:    setnp %al
32; NOPOPCNT-NEXT:    retq
33;
34; POPCNT-LABEL: canonical_parity:
35; POPCNT:       # %bb.0:
36; POPCNT-NEXT:    psllw $7, %xmm0
37; POPCNT-NEXT:    pmovmskb %xmm0, %eax
38; POPCNT-NEXT:    popcntl %eax, %eax
39; POPCNT-NEXT:    andl $1, %eax
40; POPCNT-NEXT:    # kill: def $al killed $al killed $eax
41; POPCNT-NEXT:    retq
42  %i1 = bitcast <16 x i1> %x to i16
43  %i2 = call i16 @llvm.ctpop.i16(i16 %i1)
44  %i3 = and i16 %i2, 1
45  %i4 = icmp ne i16 %i3, 0
46  ret i1 %i4
47}
48define i1 @canonical_parity_noncanonical_pred(<16 x i1> %x) {
49; NOPOPCNT-LABEL: canonical_parity_noncanonical_pred:
50; NOPOPCNT:       # %bb.0:
51; NOPOPCNT-NEXT:    psllw $7, %xmm0
52; NOPOPCNT-NEXT:    pmovmskb %xmm0, %eax
53; NOPOPCNT-NEXT:    movl %eax, %ecx
54; NOPOPCNT-NEXT:    shrl %ecx
55; NOPOPCNT-NEXT:    andl $21845, %ecx # imm = 0x5555
56; NOPOPCNT-NEXT:    subl %ecx, %eax
57; NOPOPCNT-NEXT:    movl %eax, %ecx
58; NOPOPCNT-NEXT:    andl $13107, %ecx # imm = 0x3333
59; NOPOPCNT-NEXT:    shrl $2, %eax
60; NOPOPCNT-NEXT:    andl $13107, %eax # imm = 0x3333
61; NOPOPCNT-NEXT:    addl %ecx, %eax
62; NOPOPCNT-NEXT:    movl %eax, %ecx
63; NOPOPCNT-NEXT:    shrl $4, %ecx
64; NOPOPCNT-NEXT:    addl %eax, %ecx
65; NOPOPCNT-NEXT:    andl $3855, %ecx # imm = 0xF0F
66; NOPOPCNT-NEXT:    movl %ecx, %eax
67; NOPOPCNT-NEXT:    shrl $8, %eax
68; NOPOPCNT-NEXT:    addl %ecx, %eax
69; NOPOPCNT-NEXT:    # kill: def $al killed $al killed $eax
70; NOPOPCNT-NEXT:    retq
71;
72; POPCNT-LABEL: canonical_parity_noncanonical_pred:
73; POPCNT:       # %bb.0:
74; POPCNT-NEXT:    psllw $7, %xmm0
75; POPCNT-NEXT:    pmovmskb %xmm0, %eax
76; POPCNT-NEXT:    popcntl %eax, %eax
77; POPCNT-NEXT:    # kill: def $al killed $al killed $eax
78; POPCNT-NEXT:    retq
79  %i1 = bitcast <16 x i1> %x to i16
80  %i2 = call i16 @llvm.ctpop.i16(i16 %i1)
81  %i3 = and i16 %i2, 1
82  %i4 = icmp eq i16 %i3, 1
83  ret i1 %i4
84}
85
86define i1 @noncanonical_nonparity(<16 x i1> %x) {
87; NOPOPCNT-LABEL: noncanonical_nonparity:
88; NOPOPCNT:       # %bb.0:
89; NOPOPCNT-NEXT:    psllw $7, %xmm0
90; NOPOPCNT-NEXT:    pmovmskb %xmm0, %eax
91; NOPOPCNT-NEXT:    xorb %ah, %al
92; NOPOPCNT-NEXT:    setp %al
93; NOPOPCNT-NEXT:    retq
94;
95; POPCNT-LABEL: noncanonical_nonparity:
96; POPCNT:       # %bb.0:
97; POPCNT-NEXT:    psllw $7, %xmm0
98; POPCNT-NEXT:    pmovmskb %xmm0, %eax
99; POPCNT-NEXT:    popcntl %eax, %eax
100; POPCNT-NEXT:    andl $1, %eax
101; POPCNT-NEXT:    xorb $1, %al
102; POPCNT-NEXT:    # kill: def $al killed $al killed $eax
103; POPCNT-NEXT:    retq
104  %r.inv = call i1 @llvm.vector.reduce.xor.v16i1(<16 x i1> %x)
105  %r = xor i1 %r.inv, -1
106  ret i1 %r
107}
108define i1 @canonical_nonparity(<16 x i1> %x) {
109; NOPOPCNT-LABEL: canonical_nonparity:
110; NOPOPCNT:       # %bb.0:
111; NOPOPCNT-NEXT:    psllw $7, %xmm0
112; NOPOPCNT-NEXT:    pmovmskb %xmm0, %eax
113; NOPOPCNT-NEXT:    xorb %ah, %al
114; NOPOPCNT-NEXT:    setp %al
115; NOPOPCNT-NEXT:    retq
116;
117; POPCNT-LABEL: canonical_nonparity:
118; POPCNT:       # %bb.0:
119; POPCNT-NEXT:    psllw $7, %xmm0
120; POPCNT-NEXT:    pmovmskb %xmm0, %eax
121; POPCNT-NEXT:    popcntl %eax, %eax
122; POPCNT-NEXT:    testb $1, %al
123; POPCNT-NEXT:    sete %al
124; POPCNT-NEXT:    retq
125  %i1 = bitcast <16 x i1> %x to i16
126  %i2 = call i16 @llvm.ctpop.i16(i16 %i1)
127  %i3 = and i16 %i2, 1
128  %i4 = icmp eq i16 %i3, 0
129  ret i1 %i4
130}
131define i1 @canonical_nonparity_noncanonical_pred(<16 x i1> %x) {
132; NOPOPCNT-LABEL: canonical_nonparity_noncanonical_pred:
133; NOPOPCNT:       # %bb.0:
134; NOPOPCNT-NEXT:    psllw $7, %xmm0
135; NOPOPCNT-NEXT:    pmovmskb %xmm0, %eax
136; NOPOPCNT-NEXT:    xorb %ah, %al
137; NOPOPCNT-NEXT:    setp %al
138; NOPOPCNT-NEXT:    retq
139;
140; POPCNT-LABEL: canonical_nonparity_noncanonical_pred:
141; POPCNT:       # %bb.0:
142; POPCNT-NEXT:    psllw $7, %xmm0
143; POPCNT-NEXT:    pmovmskb %xmm0, %eax
144; POPCNT-NEXT:    popcntl %eax, %eax
145; POPCNT-NEXT:    andl $1, %eax
146; POPCNT-NEXT:    xorb $1, %al
147; POPCNT-NEXT:    # kill: def $al killed $al killed $eax
148; POPCNT-NEXT:    retq
149  %i1 = bitcast <16 x i1> %x to i16
150  %i2 = call i16 @llvm.ctpop.i16(i16 %i1)
151  %i3 = and i16 %i2, 1
152  %i4 = icmp ne i16 %i3, 1
153  ret i1 %i4
154}
155
156declare i1 @llvm.vector.reduce.xor.v16i1(<16 x i1>)
157declare i16 @llvm.ctpop.i16(i16)
158