xref: /llvm-project/llvm/test/CodeGen/AArch64/reduce-and.ll (revision 1dd0d3cf40f21b842dbee107b3d203db9fbaa4ae)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+neon | FileCheck %s
3; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL
4
5
6define i1 @test_redand_v1i1(<1 x i1> %a) {
7; CHECK-LABEL: test_redand_v1i1:
8; CHECK:       // %bb.0:
9; CHECK-NEXT:    and w0, w0, #0x1
10; CHECK-NEXT:    ret
11;
12; GISEL-LABEL: test_redand_v1i1:
13; GISEL:       // %bb.0:
14; GISEL-NEXT:    and w0, w0, #0x1
15; GISEL-NEXT:    ret
16  %or_result = call i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %a)
17  ret i1 %or_result
18}
19
20define i1 @test_redand_v2i1(<2 x i1> %a) {
21; CHECK-LABEL: test_redand_v2i1:
22; CHECK:       // %bb.0:
23; CHECK-NEXT:    shl v0.2s, v0.2s, #31
24; CHECK-NEXT:    cmlt v0.2s, v0.2s, #0
25; CHECK-NEXT:    uminp v0.2s, v0.2s, v0.2s
26; CHECK-NEXT:    fmov w8, s0
27; CHECK-NEXT:    and w0, w8, #0x1
28; CHECK-NEXT:    ret
29;
30; GISEL-LABEL: test_redand_v2i1:
31; GISEL:       // %bb.0:
32; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
33; GISEL-NEXT:    mov w8, v0.s[1]
34; GISEL-NEXT:    fmov w9, s0
35; GISEL-NEXT:    and w8, w9, w8
36; GISEL-NEXT:    and w0, w8, #0x1
37; GISEL-NEXT:    ret
38  %or_result = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %a)
39  ret i1 %or_result
40}
41
42define i1 @test_redand_v4i1(<4 x i1> %a) {
43; CHECK-LABEL: test_redand_v4i1:
44; CHECK:       // %bb.0:
45; CHECK-NEXT:    shl v0.4h, v0.4h, #15
46; CHECK-NEXT:    cmlt v0.4h, v0.4h, #0
47; CHECK-NEXT:    uminv h0, v0.4h
48; CHECK-NEXT:    fmov w8, s0
49; CHECK-NEXT:    and w0, w8, #0x1
50; CHECK-NEXT:    ret
51;
52; GISEL-LABEL: test_redand_v4i1:
53; GISEL:       // %bb.0:
54; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
55; GISEL-NEXT:    umov w8, v0.h[0]
56; GISEL-NEXT:    umov w9, v0.h[1]
57; GISEL-NEXT:    umov w10, v0.h[2]
58; GISEL-NEXT:    umov w11, v0.h[3]
59; GISEL-NEXT:    and w8, w8, w9
60; GISEL-NEXT:    and w9, w10, w11
61; GISEL-NEXT:    and w8, w8, w9
62; GISEL-NEXT:    and w0, w8, #0x1
63; GISEL-NEXT:    ret
64  %or_result = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %a)
65  ret i1 %or_result
66}
67
68define i1 @test_redand_v8i1(<8 x i1> %a) {
69; CHECK-LABEL: test_redand_v8i1:
70; CHECK:       // %bb.0:
71; CHECK-NEXT:    shl v0.8b, v0.8b, #7
72; CHECK-NEXT:    cmlt v0.8b, v0.8b, #0
73; CHECK-NEXT:    uminv b0, v0.8b
74; CHECK-NEXT:    fmov w8, s0
75; CHECK-NEXT:    and w0, w8, #0x1
76; CHECK-NEXT:    ret
77;
78; GISEL-LABEL: test_redand_v8i1:
79; GISEL:       // %bb.0:
80; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
81; GISEL-NEXT:    umov w8, v0.b[0]
82; GISEL-NEXT:    umov w9, v0.b[1]
83; GISEL-NEXT:    umov w10, v0.b[2]
84; GISEL-NEXT:    umov w11, v0.b[3]
85; GISEL-NEXT:    umov w12, v0.b[4]
86; GISEL-NEXT:    umov w13, v0.b[5]
87; GISEL-NEXT:    umov w14, v0.b[6]
88; GISEL-NEXT:    umov w15, v0.b[7]
89; GISEL-NEXT:    and w8, w8, w9
90; GISEL-NEXT:    and w9, w10, w11
91; GISEL-NEXT:    and w10, w12, w13
92; GISEL-NEXT:    and w11, w14, w15
93; GISEL-NEXT:    and w8, w8, w9
94; GISEL-NEXT:    and w9, w10, w11
95; GISEL-NEXT:    and w8, w8, w9
96; GISEL-NEXT:    and w0, w8, #0x1
97; GISEL-NEXT:    ret
98  %or_result = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %a)
99  ret i1 %or_result
100}
101
102define i1 @test_redand_v16i1(<16 x i1> %a) {
103; CHECK-LABEL: test_redand_v16i1:
104; CHECK:       // %bb.0:
105; CHECK-NEXT:    shl v0.16b, v0.16b, #7
106; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
107; CHECK-NEXT:    uminv b0, v0.16b
108; CHECK-NEXT:    fmov w8, s0
109; CHECK-NEXT:    and w0, w8, #0x1
110; CHECK-NEXT:    ret
111;
112; GISEL-LABEL: test_redand_v16i1:
113; GISEL:       // %bb.0:
114; GISEL-NEXT:    umov w8, v0.b[0]
115; GISEL-NEXT:    umov w9, v0.b[1]
116; GISEL-NEXT:    umov w10, v0.b[2]
117; GISEL-NEXT:    umov w11, v0.b[3]
118; GISEL-NEXT:    umov w12, v0.b[4]
119; GISEL-NEXT:    umov w13, v0.b[5]
120; GISEL-NEXT:    umov w14, v0.b[6]
121; GISEL-NEXT:    umov w15, v0.b[7]
122; GISEL-NEXT:    umov w16, v0.b[8]
123; GISEL-NEXT:    umov w17, v0.b[9]
124; GISEL-NEXT:    umov w18, v0.b[10]
125; GISEL-NEXT:    umov w0, v0.b[11]
126; GISEL-NEXT:    and w8, w8, w9
127; GISEL-NEXT:    umov w1, v0.b[12]
128; GISEL-NEXT:    umov w2, v0.b[13]
129; GISEL-NEXT:    and w9, w10, w11
130; GISEL-NEXT:    and w10, w12, w13
131; GISEL-NEXT:    umov w3, v0.b[14]
132; GISEL-NEXT:    and w11, w14, w15
133; GISEL-NEXT:    and w8, w8, w9
134; GISEL-NEXT:    umov w4, v0.b[15]
135; GISEL-NEXT:    and w12, w16, w17
136; GISEL-NEXT:    and w13, w18, w0
137; GISEL-NEXT:    and w9, w10, w11
138; GISEL-NEXT:    and w14, w1, w2
139; GISEL-NEXT:    and w10, w12, w13
140; GISEL-NEXT:    and w8, w8, w9
141; GISEL-NEXT:    and w15, w3, w4
142; GISEL-NEXT:    and w11, w14, w15
143; GISEL-NEXT:    and w9, w10, w11
144; GISEL-NEXT:    and w8, w8, w9
145; GISEL-NEXT:    and w0, w8, #0x1
146; GISEL-NEXT:    ret
147  %or_result = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a)
148  ret i1 %or_result
149}
150
151define <16 x i1> @test_redand_ins_v16i1(<16 x i1> %a) {
152; CHECK-LABEL: test_redand_ins_v16i1:
153; CHECK:       // %bb.0:
154; CHECK-NEXT:    shl v0.16b, v0.16b, #7
155; CHECK-NEXT:    cmlt v0.16b, v0.16b, #0
156; CHECK-NEXT:    uminv b0, v0.16b
157; CHECK-NEXT:    ret
158;
159; GISEL-LABEL: test_redand_ins_v16i1:
160; GISEL:       // %bb.0:
161; GISEL-NEXT:    umov w8, v0.b[0]
162; GISEL-NEXT:    umov w9, v0.b[1]
163; GISEL-NEXT:    umov w10, v0.b[2]
164; GISEL-NEXT:    umov w11, v0.b[3]
165; GISEL-NEXT:    umov w12, v0.b[4]
166; GISEL-NEXT:    umov w13, v0.b[5]
167; GISEL-NEXT:    umov w14, v0.b[6]
168; GISEL-NEXT:    umov w15, v0.b[7]
169; GISEL-NEXT:    umov w16, v0.b[8]
170; GISEL-NEXT:    umov w17, v0.b[9]
171; GISEL-NEXT:    umov w18, v0.b[10]
172; GISEL-NEXT:    umov w0, v0.b[11]
173; GISEL-NEXT:    and w8, w8, w9
174; GISEL-NEXT:    umov w1, v0.b[12]
175; GISEL-NEXT:    umov w2, v0.b[13]
176; GISEL-NEXT:    and w9, w10, w11
177; GISEL-NEXT:    and w10, w12, w13
178; GISEL-NEXT:    umov w3, v0.b[14]
179; GISEL-NEXT:    and w11, w14, w15
180; GISEL-NEXT:    and w8, w8, w9
181; GISEL-NEXT:    umov w4, v0.b[15]
182; GISEL-NEXT:    and w12, w16, w17
183; GISEL-NEXT:    and w13, w18, w0
184; GISEL-NEXT:    and w9, w10, w11
185; GISEL-NEXT:    and w14, w1, w2
186; GISEL-NEXT:    and w10, w12, w13
187; GISEL-NEXT:    and w8, w8, w9
188; GISEL-NEXT:    and w15, w3, w4
189; GISEL-NEXT:    and w11, w14, w15
190; GISEL-NEXT:    and w9, w10, w11
191; GISEL-NEXT:    and w8, w8, w9
192; GISEL-NEXT:    fmov s0, w8
193; GISEL-NEXT:    ret
194  %and_result = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a)
195  %ins = insertelement <16 x i1> poison, i1 %and_result, i64 0
196  ret <16 x i1> %ins
197}
198
199define i8 @test_redand_v1i8(<1 x i8> %a) {
200; CHECK-LABEL: test_redand_v1i8:
201; CHECK:       // %bb.0:
202; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
203; CHECK-NEXT:    umov w0, v0.b[0]
204; CHECK-NEXT:    ret
205;
206; GISEL-LABEL: test_redand_v1i8:
207; GISEL:       // %bb.0:
208; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
209; GISEL-NEXT:    umov w0, v0.b[0]
210; GISEL-NEXT:    ret
211  %and_result = call i8 @llvm.vector.reduce.and.v1i8(<1 x i8> %a)
212  ret i8 %and_result
213}
214
215define i8 @test_redand_v3i8(<3 x i8> %a) {
216; CHECK-LABEL: test_redand_v3i8:
217; CHECK:       // %bb.0:
218; CHECK-NEXT:    movi d0, #0xff00ff00ff00ff
219; CHECK-NEXT:    mov v0.h[0], w0
220; CHECK-NEXT:    mov v0.h[1], w1
221; CHECK-NEXT:    mov v0.h[2], w2
222; CHECK-NEXT:    fmov x8, d0
223; CHECK-NEXT:    and x8, x8, x8, lsr #32
224; CHECK-NEXT:    lsr x9, x8, #16
225; CHECK-NEXT:    and w0, w8, w9
226; CHECK-NEXT:    ret
227;
228; GISEL-LABEL: test_redand_v3i8:
229; GISEL:       // %bb.0:
230; GISEL-NEXT:    and w8, w0, w1
231; GISEL-NEXT:    and w0, w8, w2
232; GISEL-NEXT:    ret
233  %and_result = call i8 @llvm.vector.reduce.and.v3i8(<3 x i8> %a)
234  ret i8 %and_result
235}
236
237define i8 @test_redand_v4i8(<4 x i8> %a) {
238; CHECK-LABEL: test_redand_v4i8:
239; CHECK:       // %bb.0:
240; CHECK-NEXT:    fmov x8, d0
241; CHECK-NEXT:    and x8, x8, x8, lsr #32
242; CHECK-NEXT:    lsr x9, x8, #16
243; CHECK-NEXT:    and w0, w8, w9
244; CHECK-NEXT:    ret
245;
246; GISEL-LABEL: test_redand_v4i8:
247; GISEL:       // %bb.0:
248; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
249; GISEL-NEXT:    umov w8, v0.h[0]
250; GISEL-NEXT:    umov w9, v0.h[1]
251; GISEL-NEXT:    umov w10, v0.h[2]
252; GISEL-NEXT:    umov w11, v0.h[3]
253; GISEL-NEXT:    and w8, w8, w9
254; GISEL-NEXT:    and w9, w10, w11
255; GISEL-NEXT:    and w0, w8, w9
256; GISEL-NEXT:    ret
257  %and_result = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %a)
258  ret i8 %and_result
259}
260
261define i8 @test_redand_v8i8(<8 x i8> %a) {
262; CHECK-LABEL: test_redand_v8i8:
263; CHECK:       // %bb.0:
264; CHECK-NEXT:    fmov x8, d0
265; CHECK-NEXT:    and x8, x8, x8, lsr #32
266; CHECK-NEXT:    and x8, x8, x8, lsr #16
267; CHECK-NEXT:    lsr x9, x8, #8
268; CHECK-NEXT:    and w0, w8, w9
269; CHECK-NEXT:    ret
270;
271; GISEL-LABEL: test_redand_v8i8:
272; GISEL:       // %bb.0:
273; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
274; GISEL-NEXT:    umov w8, v0.b[0]
275; GISEL-NEXT:    umov w9, v0.b[1]
276; GISEL-NEXT:    umov w10, v0.b[2]
277; GISEL-NEXT:    umov w11, v0.b[3]
278; GISEL-NEXT:    umov w12, v0.b[4]
279; GISEL-NEXT:    umov w13, v0.b[5]
280; GISEL-NEXT:    umov w14, v0.b[6]
281; GISEL-NEXT:    umov w15, v0.b[7]
282; GISEL-NEXT:    and w8, w8, w9
283; GISEL-NEXT:    and w9, w10, w11
284; GISEL-NEXT:    and w10, w12, w13
285; GISEL-NEXT:    and w11, w14, w15
286; GISEL-NEXT:    and w8, w8, w9
287; GISEL-NEXT:    and w9, w10, w11
288; GISEL-NEXT:    and w0, w8, w9
289; GISEL-NEXT:    ret
290  %and_result = call i8 @llvm.vector.reduce.and.v8i8(<8 x i8> %a)
291  ret i8 %and_result
292}
293
294define i8 @test_redand_v16i8(<16 x i8> %a) {
295; CHECK-LABEL: test_redand_v16i8:
296; CHECK:       // %bb.0:
297; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
298; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
299; CHECK-NEXT:    fmov x8, d0
300; CHECK-NEXT:    and x8, x8, x8, lsr #32
301; CHECK-NEXT:    and x8, x8, x8, lsr #16
302; CHECK-NEXT:    lsr x9, x8, #8
303; CHECK-NEXT:    and w0, w8, w9
304; CHECK-NEXT:    ret
305;
306; GISEL-LABEL: test_redand_v16i8:
307; GISEL:       // %bb.0:
308; GISEL-NEXT:    mov d1, v0.d[1]
309; GISEL-NEXT:    and v0.8b, v0.8b, v1.8b
310; GISEL-NEXT:    umov w8, v0.b[0]
311; GISEL-NEXT:    umov w9, v0.b[1]
312; GISEL-NEXT:    umov w10, v0.b[2]
313; GISEL-NEXT:    umov w11, v0.b[3]
314; GISEL-NEXT:    umov w12, v0.b[4]
315; GISEL-NEXT:    umov w13, v0.b[5]
316; GISEL-NEXT:    umov w14, v0.b[6]
317; GISEL-NEXT:    umov w15, v0.b[7]
318; GISEL-NEXT:    and w8, w8, w9
319; GISEL-NEXT:    and w9, w10, w11
320; GISEL-NEXT:    and w10, w12, w13
321; GISEL-NEXT:    and w11, w14, w15
322; GISEL-NEXT:    and w8, w8, w9
323; GISEL-NEXT:    and w9, w10, w11
324; GISEL-NEXT:    and w0, w8, w9
325; GISEL-NEXT:    ret
326  %and_result = call i8 @llvm.vector.reduce.and.v16i8(<16 x i8> %a)
327  ret i8 %and_result
328}
329
330define i8 @test_redand_v32i8(<32 x i8> %a) {
331; CHECK-LABEL: test_redand_v32i8:
332; CHECK:       // %bb.0:
333; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
334; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
335; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
336; CHECK-NEXT:    fmov x8, d0
337; CHECK-NEXT:    and x8, x8, x8, lsr #32
338; CHECK-NEXT:    and x8, x8, x8, lsr #16
339; CHECK-NEXT:    lsr x9, x8, #8
340; CHECK-NEXT:    and w0, w8, w9
341; CHECK-NEXT:    ret
342;
343; GISEL-LABEL: test_redand_v32i8:
344; GISEL:       // %bb.0:
345; GISEL-NEXT:    and v0.16b, v0.16b, v1.16b
346; GISEL-NEXT:    mov d1, v0.d[1]
347; GISEL-NEXT:    and v0.8b, v0.8b, v1.8b
348; GISEL-NEXT:    umov w8, v0.b[0]
349; GISEL-NEXT:    umov w9, v0.b[1]
350; GISEL-NEXT:    umov w10, v0.b[2]
351; GISEL-NEXT:    umov w11, v0.b[3]
352; GISEL-NEXT:    umov w12, v0.b[4]
353; GISEL-NEXT:    umov w13, v0.b[5]
354; GISEL-NEXT:    umov w14, v0.b[6]
355; GISEL-NEXT:    umov w15, v0.b[7]
356; GISEL-NEXT:    and w8, w8, w9
357; GISEL-NEXT:    and w9, w10, w11
358; GISEL-NEXT:    and w10, w12, w13
359; GISEL-NEXT:    and w11, w14, w15
360; GISEL-NEXT:    and w8, w8, w9
361; GISEL-NEXT:    and w9, w10, w11
362; GISEL-NEXT:    and w0, w8, w9
363; GISEL-NEXT:    ret
364  %and_result = call i8 @llvm.vector.reduce.and.v32i8(<32 x i8> %a)
365  ret i8 %and_result
366}
367
368define i16 @test_redand_v4i16(<4 x i16> %a) {
369; CHECK-LABEL: test_redand_v4i16:
370; CHECK:       // %bb.0:
371; CHECK-NEXT:    fmov x8, d0
372; CHECK-NEXT:    and x8, x8, x8, lsr #32
373; CHECK-NEXT:    lsr x9, x8, #16
374; CHECK-NEXT:    and w0, w8, w9
375; CHECK-NEXT:    ret
376;
377; GISEL-LABEL: test_redand_v4i16:
378; GISEL:       // %bb.0:
379; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
380; GISEL-NEXT:    umov w8, v0.h[0]
381; GISEL-NEXT:    umov w9, v0.h[1]
382; GISEL-NEXT:    umov w10, v0.h[2]
383; GISEL-NEXT:    umov w11, v0.h[3]
384; GISEL-NEXT:    and w8, w8, w9
385; GISEL-NEXT:    and w9, w10, w11
386; GISEL-NEXT:    and w0, w8, w9
387; GISEL-NEXT:    ret
388  %and_result = call i16 @llvm.vector.reduce.and.v4i16(<4 x i16> %a)
389  ret i16 %and_result
390}
391
392define i16 @test_redand_v8i16(<8 x i16> %a) {
393; CHECK-LABEL: test_redand_v8i16:
394; CHECK:       // %bb.0:
395; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
396; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
397; CHECK-NEXT:    fmov x8, d0
398; CHECK-NEXT:    and x8, x8, x8, lsr #32
399; CHECK-NEXT:    lsr x9, x8, #16
400; CHECK-NEXT:    and w0, w8, w9
401; CHECK-NEXT:    ret
402;
403; GISEL-LABEL: test_redand_v8i16:
404; GISEL:       // %bb.0:
405; GISEL-NEXT:    mov d1, v0.d[1]
406; GISEL-NEXT:    and v0.8b, v0.8b, v1.8b
407; GISEL-NEXT:    umov w8, v0.h[0]
408; GISEL-NEXT:    umov w9, v0.h[1]
409; GISEL-NEXT:    umov w10, v0.h[2]
410; GISEL-NEXT:    umov w11, v0.h[3]
411; GISEL-NEXT:    and w8, w8, w9
412; GISEL-NEXT:    and w9, w10, w11
413; GISEL-NEXT:    and w0, w8, w9
414; GISEL-NEXT:    ret
415  %and_result = call i16 @llvm.vector.reduce.and.v8i16(<8 x i16> %a)
416  ret i16 %and_result
417}
418
419define i16 @test_redand_v16i16(<16 x i16> %a) {
420; CHECK-LABEL: test_redand_v16i16:
421; CHECK:       // %bb.0:
422; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
423; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
424; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
425; CHECK-NEXT:    fmov x8, d0
426; CHECK-NEXT:    and x8, x8, x8, lsr #32
427; CHECK-NEXT:    lsr x9, x8, #16
428; CHECK-NEXT:    and w0, w8, w9
429; CHECK-NEXT:    ret
430;
431; GISEL-LABEL: test_redand_v16i16:
432; GISEL:       // %bb.0:
433; GISEL-NEXT:    and v0.16b, v0.16b, v1.16b
434; GISEL-NEXT:    mov d1, v0.d[1]
435; GISEL-NEXT:    and v0.8b, v0.8b, v1.8b
436; GISEL-NEXT:    umov w8, v0.h[0]
437; GISEL-NEXT:    umov w9, v0.h[1]
438; GISEL-NEXT:    umov w10, v0.h[2]
439; GISEL-NEXT:    umov w11, v0.h[3]
440; GISEL-NEXT:    and w8, w8, w9
441; GISEL-NEXT:    and w9, w10, w11
442; GISEL-NEXT:    and w0, w8, w9
443; GISEL-NEXT:    ret
444  %and_result = call i16 @llvm.vector.reduce.and.v16i16(<16 x i16> %a)
445  ret i16 %and_result
446}
447
448define i32 @test_redand_v2i32(<2 x i32> %a) {
449; CHECK-LABEL: test_redand_v2i32:
450; CHECK:       // %bb.0:
451; CHECK-NEXT:    fmov x8, d0
452; CHECK-NEXT:    lsr x9, x8, #32
453; CHECK-NEXT:    and w0, w8, w9
454; CHECK-NEXT:    ret
455;
456; GISEL-LABEL: test_redand_v2i32:
457; GISEL:       // %bb.0:
458; GISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
459; GISEL-NEXT:    mov w8, v0.s[1]
460; GISEL-NEXT:    fmov w9, s0
461; GISEL-NEXT:    and w0, w9, w8
462; GISEL-NEXT:    ret
463  %and_result = call i32 @llvm.vector.reduce.and.v2i32(<2 x i32> %a)
464  ret i32 %and_result
465}
466
467define i32 @test_redand_v4i32(<4 x i32> %a) {
468; CHECK-LABEL: test_redand_v4i32:
469; CHECK:       // %bb.0:
470; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
471; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
472; CHECK-NEXT:    fmov x8, d0
473; CHECK-NEXT:    lsr x9, x8, #32
474; CHECK-NEXT:    and w0, w8, w9
475; CHECK-NEXT:    ret
476;
477; GISEL-LABEL: test_redand_v4i32:
478; GISEL:       // %bb.0:
479; GISEL-NEXT:    mov d1, v0.d[1]
480; GISEL-NEXT:    and v0.8b, v0.8b, v1.8b
481; GISEL-NEXT:    mov w8, v0.s[1]
482; GISEL-NEXT:    fmov w9, s0
483; GISEL-NEXT:    and w0, w9, w8
484; GISEL-NEXT:    ret
485  %and_result = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %a)
486  ret i32 %and_result
487}
488
489define i32 @test_redand_v8i32(<8 x i32> %a) {
490; CHECK-LABEL: test_redand_v8i32:
491; CHECK:       // %bb.0:
492; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
493; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
494; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
495; CHECK-NEXT:    fmov x8, d0
496; CHECK-NEXT:    lsr x9, x8, #32
497; CHECK-NEXT:    and w0, w8, w9
498; CHECK-NEXT:    ret
499;
500; GISEL-LABEL: test_redand_v8i32:
501; GISEL:       // %bb.0:
502; GISEL-NEXT:    and v0.16b, v0.16b, v1.16b
503; GISEL-NEXT:    mov d1, v0.d[1]
504; GISEL-NEXT:    and v0.8b, v0.8b, v1.8b
505; GISEL-NEXT:    mov w8, v0.s[1]
506; GISEL-NEXT:    fmov w9, s0
507; GISEL-NEXT:    and w0, w9, w8
508; GISEL-NEXT:    ret
509  %and_result = call i32 @llvm.vector.reduce.and.v8i32(<8 x i32> %a)
510  ret i32 %and_result
511}
512
513define i64 @test_redand_v2i64(<2 x i64> %a) {
514; CHECK-LABEL: test_redand_v2i64:
515; CHECK:       // %bb.0:
516; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
517; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
518; CHECK-NEXT:    fmov x0, d0
519; CHECK-NEXT:    ret
520;
521; GISEL-LABEL: test_redand_v2i64:
522; GISEL:       // %bb.0:
523; GISEL-NEXT:    mov x8, v0.d[1]
524; GISEL-NEXT:    fmov x9, d0
525; GISEL-NEXT:    and x0, x9, x8
526; GISEL-NEXT:    ret
527  %and_result = call i64 @llvm.vector.reduce.and.v2i64(<2 x i64> %a)
528  ret i64 %and_result
529}
530
531define i64 @test_redand_v4i64(<4 x i64> %a) {
532; CHECK-LABEL: test_redand_v4i64:
533; CHECK:       // %bb.0:
534; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
535; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8
536; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
537; CHECK-NEXT:    fmov x0, d0
538; CHECK-NEXT:    ret
539;
540; GISEL-LABEL: test_redand_v4i64:
541; GISEL:       // %bb.0:
542; GISEL-NEXT:    and v0.16b, v0.16b, v1.16b
543; GISEL-NEXT:    mov x8, v0.d[1]
544; GISEL-NEXT:    fmov x9, d0
545; GISEL-NEXT:    and x0, x9, x8
546; GISEL-NEXT:    ret
547  %and_result = call i64 @llvm.vector.reduce.and.v4i64(<4 x i64> %a)
548  ret i64 %and_result
549}
550
551declare i1 @llvm.vector.reduce.and.v1i1(<1 x i1>)
552declare i1 @llvm.vector.reduce.and.v2i1(<2 x i1>)
553declare i1 @llvm.vector.reduce.and.v4i1(<4 x i1>)
554declare i1 @llvm.vector.reduce.and.v8i1(<8 x i1>)
555declare i1 @llvm.vector.reduce.and.v16i1(<16 x i1>)
556declare i64 @llvm.vector.reduce.and.v2i64(<2 x i64>)
557declare i64 @llvm.vector.reduce.and.v4i64(<4 x i64>)
558declare i32 @llvm.vector.reduce.and.v2i32(<2 x i32>)
559declare i32 @llvm.vector.reduce.and.v4i32(<4 x i32>)
560declare i32 @llvm.vector.reduce.and.v8i32(<8 x i32>)
561declare i16 @llvm.vector.reduce.and.v4i16(<4 x i16>)
562declare i16 @llvm.vector.reduce.and.v8i16(<8 x i16>)
563declare i16 @llvm.vector.reduce.and.v16i16(<16 x i16>)
564declare i8 @llvm.vector.reduce.and.v1i8(<1 x i8>)
565declare i8 @llvm.vector.reduce.and.v3i8(<3 x i8>)
566declare i8 @llvm.vector.reduce.and.v4i8(<4 x i8>)
567declare i8 @llvm.vector.reduce.and.v8i8(<8 x i8>)
568declare i8 @llvm.vector.reduce.and.v16i8(<16 x i8>)
569declare i8 @llvm.vector.reduce.and.v32i8(<32 x i8>)
570