1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s --check-prefix=CHECK
3
4declare i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %a)
5declare i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %a)
6declare i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %a)
7declare i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %a)
8declare i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a)
9declare i1 @llvm.vector.reduce.and.v32i1(<32 x i1> %a)
10
11declare i1 @llvm.vector.reduce.or.v1i1(<1 x i1> %a)
12declare i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %a)
13declare i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %a)
14declare i1 @llvm.vector.reduce.or.v8i1(<8 x i1> %a)
15declare i1 @llvm.vector.reduce.or.v16i1(<16 x i1> %a)
16declare i1 @llvm.vector.reduce.or.v32i1(<32 x i1> %a)
17
18define i32 @reduce_and_v1(<1 x i8> %a0, i32 %a1, i32 %a2) nounwind {
19; CHECK-LABEL: reduce_and_v1:
20; CHECK:       // %bb.0:
21; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
22; CHECK-NEXT:    smov w8, v0.b[0]
23; CHECK-NEXT:    cmp w8, #0
24; CHECK-NEXT:    csel w0, w0, w1, lt
25; CHECK-NEXT:    ret
26  %x = icmp slt <1 x i8> %a0, zeroinitializer
27  %y = call i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %x)
28  %z = select i1 %y, i32 %a1, i32 %a2
29  ret i32 %z
30}
31
32define i32 @reduce_and_v2(<2 x i8> %a0, i32 %a1, i32 %a2) nounwind {
33; CHECK-LABEL: reduce_and_v2:
34; CHECK:       // %bb.0:
35; CHECK-NEXT:    shl v0.2s, v0.2s, #24
36; CHECK-NEXT:    sshr v0.2s, v0.2s, #24
37; CHECK-NEXT:    cmlt v0.2s, v0.2s, #0
38; CHECK-NEXT:    uminp v0.2s, v0.2s, v0.2s
39; CHECK-NEXT:    fmov w8, s0
40; CHECK-NEXT:    tst w8, #0x1
41; CHECK-NEXT:    csel w0, w0, w1, ne
42; CHECK-NEXT:    ret
43  %x = icmp slt <2 x i8> %a0, zeroinitializer
44  %y = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %x)
45  %z = select i1 %y, i32 %a1, i32 %a2
46  ret i32 %z
47}
48
49define i32 @reduce_and_v4(<4 x i8> %a0, i32 %a1, i32 %a2) nounwind {
50; CHECK-LABEL: reduce_and_v4:
51; CHECK:       // %bb.0:
52; CHECK-NEXT:    shl v0.4h, v0.4h, #8
53; CHECK-NEXT:    sshr v0.4h, v0.4h, #8
54; CHECK-NEXT:    cmlt v0.4h, v0.4h, #0
55; CHECK-NEXT:    uminv h0, v0.4h
56; CHECK-NEXT:    fmov w8, s0
57; CHECK-NEXT:    tst w8, #0x1
58; CHECK-NEXT:    csel w0, w0, w1, ne
59; CHECK-NEXT:    ret
60  %x = icmp slt <4 x i8> %a0, zeroinitializer
61  %y = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %x)
62  %z = select i1 %y, i32 %a1, i32 %a2
63  ret i32 %z
64}
65
66define i32 @reduce_and_v8(<8 x i8> %a0, i32 %a1, i32 %a2) nounwind {
67; CHECK-LABEL: reduce_and_v8:
68; CHECK:       // %bb.0:
69; CHECK-NEXT:    cmlt v0.8b, v0.8b, #0
70; CHECK-NEXT:    uminv b0, v0.8b
71; CHECK-NEXT:    fmov w8, s0
72; CHECK-NEXT:    tst w8, #0x1
73; CHECK-NEXT:    csel w0, w0, w1, ne
74; CHECK-NEXT:    ret
75  %x = icmp slt <8 x i8> %a0, zeroinitializer
76  %y = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %x)
77  %z = select i1 %y, i32 %a1, i32 %a2
78  ret i32 %z
79}
80
81define i32 @reduce_and_v16(<16 x i8> %a0, i32 %a1, i32 %a2) nounwind {
82; CHECK-LABEL: reduce_and_v16:
83; CHECK:       // %bb.0:
84; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
85; CHECK-NEXT:    uminv b0, v0.16b
86; CHECK-NEXT:    fmov w8, s0
87; CHECK-NEXT:    tst w8, #0x1
88; CHECK-NEXT:    csel w0, w0, w1, ne
89; CHECK-NEXT:    ret
90  %x = icmp slt <16 x i8> %a0, zeroinitializer
91  %y = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %x)
92  %z = select i1 %y, i32 %a1, i32 %a2
93  ret i32 %z
94}
95
96define i32 @reduce_and_v32(<32 x i8> %a0, i32 %a1, i32 %a2) nounwind {
97; CHECK-LABEL: reduce_and_v32:
98; CHECK:       // %bb.0:
99; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
100; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
101; CHECK-NEXT:    uminv b0, v0.16b
102; CHECK-NEXT:    fmov w8, s0
103; CHECK-NEXT:    tst w8, #0x1
104; CHECK-NEXT:    csel w0, w0, w1, ne
105; CHECK-NEXT:    ret
106  %x = icmp slt <32 x i8> %a0, zeroinitializer
107  %y = call i1 @llvm.vector.reduce.and.v32i1(<32 x i1> %x)
108  %z = select i1 %y, i32 %a1, i32 %a2
109  ret i32 %z
110}
111
112define i32 @reduce_or_v1(<1 x i8> %a0, i32 %a1, i32 %a2) nounwind {
113; CHECK-LABEL: reduce_or_v1:
114; CHECK:       // %bb.0:
115; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
116; CHECK-NEXT:    smov w8, v0.b[0]
117; CHECK-NEXT:    cmp w8, #0
118; CHECK-NEXT:    csel w0, w0, w1, lt
119; CHECK-NEXT:    ret
120  %x = icmp slt <1 x i8> %a0, zeroinitializer
121  %y = call i1 @llvm.vector.reduce.or.v1i1(<1 x i1> %x)
122  %z = select i1 %y, i32 %a1, i32 %a2
123  ret i32 %z
124}
125
126define i32 @reduce_or_v2(<2 x i8> %a0, i32 %a1, i32 %a2) nounwind {
127; CHECK-LABEL: reduce_or_v2:
128; CHECK:       // %bb.0:
129; CHECK-NEXT:    shl v0.2s, v0.2s, #24
130; CHECK-NEXT:    sshr v0.2s, v0.2s, #24
131; CHECK-NEXT:    cmlt v0.2s, v0.2s, #0
132; CHECK-NEXT:    umaxp v0.2s, v0.2s, v0.2s
133; CHECK-NEXT:    fmov w8, s0
134; CHECK-NEXT:    tst w8, #0x1
135; CHECK-NEXT:    csel w0, w0, w1, ne
136; CHECK-NEXT:    ret
137  %x = icmp slt <2 x i8> %a0, zeroinitializer
138  %y = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %x)
139  %z = select i1 %y, i32 %a1, i32 %a2
140  ret i32 %z
141}
142
143define i32 @reduce_or_v4(<4 x i8> %a0, i32 %a1, i32 %a2) nounwind {
144; CHECK-LABEL: reduce_or_v4:
145; CHECK:       // %bb.0:
146; CHECK-NEXT:    shl v0.4h, v0.4h, #8
147; CHECK-NEXT:    sshr v0.4h, v0.4h, #8
148; CHECK-NEXT:    cmlt v0.4h, v0.4h, #0
149; CHECK-NEXT:    umaxv h0, v0.4h
150; CHECK-NEXT:    fmov w8, s0
151; CHECK-NEXT:    tst w8, #0x1
152; CHECK-NEXT:    csel w0, w0, w1, ne
153; CHECK-NEXT:    ret
154  %x = icmp slt <4 x i8> %a0, zeroinitializer
155  %y = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %x)
156  %z = select i1 %y, i32 %a1, i32 %a2
157  ret i32 %z
158}
159
160define i32 @reduce_or_v8(<8 x i8> %a0, i32 %a1, i32 %a2) nounwind {
161; CHECK-LABEL: reduce_or_v8:
162; CHECK:       // %bb.0:
163; CHECK-NEXT:    cmlt v0.8b, v0.8b, #0
164; CHECK-NEXT:    umaxv b0, v0.8b
165; CHECK-NEXT:    fmov w8, s0
166; CHECK-NEXT:    tst w8, #0x1
167; CHECK-NEXT:    csel w0, w0, w1, ne
168; CHECK-NEXT:    ret
169  %x = icmp slt <8 x i8> %a0, zeroinitializer
170  %y = call i1 @llvm.vector.reduce.or.v8i1(<8 x i1> %x)
171  %z = select i1 %y, i32 %a1, i32 %a2
172  ret i32 %z
173}
174
175define i32 @reduce_or_v16(<16 x i8> %a0, i32 %a1, i32 %a2) nounwind {
176; CHECK-LABEL: reduce_or_v16:
177; CHECK:       // %bb.0:
178; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
179; CHECK-NEXT:    umaxv b0, v0.16b
180; CHECK-NEXT:    fmov w8, s0
181; CHECK-NEXT:    tst w8, #0x1
182; CHECK-NEXT:    csel w0, w0, w1, ne
183; CHECK-NEXT:    ret
184  %x = icmp slt <16 x i8> %a0, zeroinitializer
185  %y = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> %x)
186  %z = select i1 %y, i32 %a1, i32 %a2
187  ret i32 %z
188}
189
190define i32 @reduce_or_v32(<32 x i8> %a0, i32 %a1, i32 %a2) nounwind {
191; CHECK-LABEL: reduce_or_v32:
192; CHECK:       // %bb.0:
193; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
194; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
195; CHECK-NEXT:    umaxv b0, v0.16b
196; CHECK-NEXT:    fmov w8, s0
197; CHECK-NEXT:    tst w8, #0x1
198; CHECK-NEXT:    csel w0, w0, w1, ne
199; CHECK-NEXT:    ret
200  %x = icmp slt <32 x i8> %a0, zeroinitializer
201  %y = call i1 @llvm.vector.reduce.or.v32i1(<32 x i1> %x)
202  %z = select i1 %y, i32 %a1, i32 %a2
203  ret i32 %z
204}
205