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