1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-linux-gnu | FileCheck %s
3
4define i4 @parity_4(i4 %x) {
5; CHECK-LABEL: parity_4:
6; CHECK:       // %bb.0:
7; CHECK-NEXT:    and w8, w0, #0xf
8; CHECK-NEXT:    eor w8, w8, w8, lsr #2
9; CHECK-NEXT:    eor w8, w8, w8, lsr #1
10; CHECK-NEXT:    and w0, w8, #0x1
11; CHECK-NEXT:    ret
12  %1 = tail call i4 @llvm.ctpop.i4(i4 %x)
13  %2 = and i4 %1, 1
14  ret i4 %2
15}
16
17define i8 @parity_8(i8 %x) {
18; CHECK-LABEL: parity_8:
19; CHECK:       // %bb.0:
20; CHECK-NEXT:    and w8, w0, #0xff
21; CHECK-NEXT:    eor w8, w8, w8, lsr #4
22; CHECK-NEXT:    eor w8, w8, w8, lsr #2
23; CHECK-NEXT:    eor w8, w8, w8, lsr #1
24; CHECK-NEXT:    and w0, w8, #0x1
25; CHECK-NEXT:    ret
26  %1 = tail call i8 @llvm.ctpop.i8(i8 %x)
27  %2 = and i8 %1, 1
28  ret i8 %2
29}
30
31define i16 @parity_16(i16 %x) {
32; CHECK-LABEL: parity_16:
33; CHECK:       // %bb.0:
34; CHECK-NEXT:    and w8, w0, #0xffff
35; CHECK-NEXT:    eor w8, w8, w8, lsr #8
36; CHECK-NEXT:    eor w8, w8, w8, lsr #4
37; CHECK-NEXT:    eor w8, w8, w8, lsr #2
38; CHECK-NEXT:    eor w8, w8, w8, lsr #1
39; CHECK-NEXT:    and w0, w8, #0x1
40; CHECK-NEXT:    ret
41  %1 = tail call i16 @llvm.ctpop.i16(i16 %x)
42  %2 = and i16 %1, 1
43  ret i16 %2
44}
45
46define i17 @parity_17(i17 %x) {
47; CHECK-LABEL: parity_17:
48; CHECK:       // %bb.0:
49; CHECK-NEXT:    and w8, w0, #0x1ffff
50; CHECK-NEXT:    eor w8, w8, w8, lsr #16
51; CHECK-NEXT:    eor w8, w8, w8, lsr #8
52; CHECK-NEXT:    eor w8, w8, w8, lsr #4
53; CHECK-NEXT:    eor w8, w8, w8, lsr #2
54; CHECK-NEXT:    eor w8, w8, w8, lsr #1
55; CHECK-NEXT:    and w0, w8, #0x1
56; CHECK-NEXT:    ret
57  %1 = tail call i17 @llvm.ctpop.i17(i17 %x)
58  %2 = and i17 %1, 1
59  ret i17 %2
60}
61
62define i32 @parity_32(i32 %x) {
63; CHECK-LABEL: parity_32:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    eor w8, w0, w0, lsr #16
66; CHECK-NEXT:    eor w8, w8, w8, lsr #8
67; CHECK-NEXT:    eor w8, w8, w8, lsr #4
68; CHECK-NEXT:    eor w8, w8, w8, lsr #2
69; CHECK-NEXT:    eor w8, w8, w8, lsr #1
70; CHECK-NEXT:    and w0, w8, #0x1
71; CHECK-NEXT:    ret
72  %1 = tail call i32 @llvm.ctpop.i32(i32 %x)
73  %2 = and i32 %1, 1
74  ret i32 %2
75}
76
77define i64 @parity_64(i64 %x) {
78; CHECK-LABEL: parity_64:
79; CHECK:       // %bb.0:
80; CHECK-NEXT:    fmov d0, x0
81; CHECK-NEXT:    cnt v0.8b, v0.8b
82; CHECK-NEXT:    uaddlv h0, v0.8b
83; CHECK-NEXT:    fmov w8, s0
84; CHECK-NEXT:    and w0, w8, #0x1
85; CHECK-NEXT:    ret
86  %1 = tail call i64 @llvm.ctpop.i64(i64 %x)
87  %2 = and i64 %1, 1
88  ret i64 %2
89}
90
91define i128 @parity_128(i128 %x) {
92; CHECK-LABEL: parity_128:
93; CHECK:       // %bb.0:
94; CHECK-NEXT:    fmov d0, x0
95; CHECK-NEXT:    mov v0.d[1], x1
96; CHECK-NEXT:    mov x1, xzr
97; CHECK-NEXT:    cnt v0.16b, v0.16b
98; CHECK-NEXT:    uaddlv h0, v0.16b
99; CHECK-NEXT:    fmov w8, s0
100; CHECK-NEXT:    and w0, w8, #0x1
101; CHECK-NEXT:    ret
102  %1 = tail call i128 @llvm.ctpop.i128(i128 %x)
103  %2 = and i128 %1, 1
104  ret i128 %2
105}
106
107define i32 @parity_64_trunc(i64 %x) {
108; CHECK-LABEL: parity_64_trunc:
109; CHECK:       // %bb.0:
110; CHECK-NEXT:    fmov d0, x0
111; CHECK-NEXT:    cnt v0.8b, v0.8b
112; CHECK-NEXT:    uaddlv h0, v0.8b
113; CHECK-NEXT:    fmov w8, s0
114; CHECK-NEXT:    and w0, w8, #0x1
115; CHECK-NEXT:    ret
116  %1 = tail call i64 @llvm.ctpop.i64(i64 %x)
117  %2 = trunc i64 %1 to i32
118  %3 = and i32 %2, 1
119  ret i32 %3
120}
121
122define i8 @parity_32_trunc(i32 %x) {
123; CHECK-LABEL: parity_32_trunc:
124; CHECK:       // %bb.0:
125; CHECK-NEXT:    eor w8, w0, w0, lsr #16
126; CHECK-NEXT:    eor w8, w8, w8, lsr #8
127; CHECK-NEXT:    eor w8, w8, w8, lsr #4
128; CHECK-NEXT:    eor w8, w8, w8, lsr #2
129; CHECK-NEXT:    eor w8, w8, w8, lsr #1
130; CHECK-NEXT:    and w0, w8, #0x1
131; CHECK-NEXT:    ret
132  %1 = tail call i32 @llvm.ctpop.i32(i32 %x)
133  %2 = trunc i32 %1 to i8
134  %3 = and i8 %2, 1
135  ret i8 %3
136}
137
138define i32 @parity_8_zext(i8 %x) {
139; CHECK-LABEL: parity_8_zext:
140; CHECK:       // %bb.0:
141; CHECK-NEXT:    and w8, w0, #0xff
142; CHECK-NEXT:    eor w8, w8, w8, lsr #4
143; CHECK-NEXT:    eor w8, w8, w8, lsr #2
144; CHECK-NEXT:    eor w8, w8, w8, lsr #1
145; CHECK-NEXT:    and w0, w8, #0x1
146; CHECK-NEXT:    ret
147  %a = zext i8 %x to i32
148  %b = tail call i32 @llvm.ctpop.i32(i32 %a)
149  %c = and i32 %b, 1
150  ret i32 %c
151}
152
153define i32 @parity_8_mask(i32 %x) {
154; CHECK-LABEL: parity_8_mask:
155; CHECK:       // %bb.0:
156; CHECK-NEXT:    and w8, w0, #0xff
157; CHECK-NEXT:    eor w8, w8, w8, lsr #4
158; CHECK-NEXT:    eor w8, w8, w8, lsr #2
159; CHECK-NEXT:    eor w8, w8, w8, lsr #1
160; CHECK-NEXT:    and w0, w8, #0x1
161; CHECK-NEXT:    ret
162  %a = and i32 %x, 255
163  %b = tail call i32 @llvm.ctpop.i32(i32 %a)
164  %c = and i32 %b, 1
165  ret i32 %c
166}
167
168declare i4 @llvm.ctpop.i4(i4 %x)
169declare i8 @llvm.ctpop.i8(i8 %x)
170declare i16 @llvm.ctpop.i16(i16 %x)
171declare i17 @llvm.ctpop.i17(i17 %x)
172declare i32 @llvm.ctpop.i32(i32 %x)
173declare i64 @llvm.ctpop.i64(i64 %x)
174declare i128 @llvm.ctpop.i128(i128 %x)
175