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:    eor x8, x0, x0, lsr #32
81; CHECK-NEXT:    eor x8, x8, x8, lsr #16
82; CHECK-NEXT:    eor x8, x8, x8, lsr #8
83; CHECK-NEXT:    eor x8, x8, x8, lsr #4
84; CHECK-NEXT:    eor x8, x8, x8, lsr #2
85; CHECK-NEXT:    eor w8, w8, w8, lsr #1
86; CHECK-NEXT:    and x0, x8, #0x1
87; CHECK-NEXT:    ret
88  %1 = tail call i64 @llvm.ctpop.i64(i64 %x)
89  %2 = and i64 %1, 1
90  ret i64 %2
91}
92
93define i32 @parity_64_trunc(i64 %x) {
94; CHECK-LABEL: parity_64_trunc:
95; CHECK:       // %bb.0:
96; CHECK-NEXT:    eor x8, x0, x0, lsr #32
97; CHECK-NEXT:    eor x8, x8, x8, lsr #16
98; CHECK-NEXT:    eor x8, x8, x8, lsr #8
99; CHECK-NEXT:    eor x8, x8, x8, lsr #4
100; CHECK-NEXT:    eor x8, x8, x8, lsr #2
101; CHECK-NEXT:    eor w8, w8, w8, lsr #1
102; CHECK-NEXT:    and w0, w8, #0x1
103; CHECK-NEXT:    ret
104  %1 = tail call i64 @llvm.ctpop.i64(i64 %x)
105  %2 = trunc i64 %1 to i32
106  %3 = and i32 %2, 1
107  ret i32 %3
108}
109
110define i8 @parity_32_trunc(i32 %x) {
111; CHECK-LABEL: parity_32_trunc:
112; CHECK:       // %bb.0:
113; CHECK-NEXT:    eor w8, w0, w0, lsr #16
114; CHECK-NEXT:    eor w8, w8, w8, lsr #8
115; CHECK-NEXT:    eor w8, w8, w8, lsr #4
116; CHECK-NEXT:    eor w8, w8, w8, lsr #2
117; CHECK-NEXT:    eor w8, w8, w8, lsr #1
118; CHECK-NEXT:    and w0, w8, #0x1
119; CHECK-NEXT:    ret
120  %1 = tail call i32 @llvm.ctpop.i32(i32 %x)
121  %2 = trunc i32 %1 to i8
122  %3 = and i8 %2, 1
123  ret i8 %3
124}
125
126define i32 @parity_8_zext(i8 %x) {
127; CHECK-LABEL: parity_8_zext:
128; CHECK:       // %bb.0:
129; CHECK-NEXT:    and w8, w0, #0xff
130; CHECK-NEXT:    eor w8, w8, w8, lsr #4
131; CHECK-NEXT:    eor w8, w8, w8, lsr #2
132; CHECK-NEXT:    eor w8, w8, w8, lsr #1
133; CHECK-NEXT:    and w0, w8, #0x1
134; CHECK-NEXT:    ret
135  %a = zext i8 %x to i32
136  %b = tail call i32 @llvm.ctpop.i32(i32 %a)
137  %c = and i32 %b, 1
138  ret i32 %c
139}
140
141define i32 @parity_8_mask(i32 %x) {
142; CHECK-LABEL: parity_8_mask:
143; CHECK:       // %bb.0:
144; CHECK-NEXT:    and w8, w0, #0xff
145; CHECK-NEXT:    eor w8, w8, w8, lsr #4
146; CHECK-NEXT:    eor w8, w8, w8, lsr #2
147; CHECK-NEXT:    eor w8, w8, w8, lsr #1
148; CHECK-NEXT:    and w0, w8, #0x1
149; CHECK-NEXT:    ret
150  %a = and i32 %x, 255
151  %b = tail call i32 @llvm.ctpop.i32(i32 %a)
152  %c = and i32 %b, 1
153  ret i32 %c
154}
155
156declare i4 @llvm.ctpop.i4(i4 %x)
157declare i8 @llvm.ctpop.i8(i8 %x)
158declare i16 @llvm.ctpop.i16(i16 %x)
159declare i17 @llvm.ctpop.i17(i17 %x)
160declare i32 @llvm.ctpop.i32(i32 %x)
161declare i64 @llvm.ctpop.i64(i64 %x)
162