blob: c3199cc3beedbe9cdb23d0131004fe1aeb0f5d49 [file] [log] [blame]
Roman Lebedevfd79bc32018-05-21 21:40:51 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
3
4; https://bugs.llvm.org/show_bug.cgi?id=37104
5
6; All the advanced stuff (negative tests, commutativity) is handled in the
7; scalar version of the test only.
8
9; ============================================================================ ;
10; 8-bit vector width
11; ============================================================================ ;
12
13define <1 x i8> @out_v1i8(<1 x i8> %x, <1 x i8> %y, <1 x i8> %mask) nounwind {
14; CHECK-LABEL: out_v1i8:
15; CHECK: // %bb.0:
16; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
17; CHECK-NEXT: mov v0.16b, v2.16b
18; CHECK-NEXT: ret
19 %mx = and <1 x i8> %x, %mask
20 %notmask = xor <1 x i8> %mask, <i8 -1>
21 %my = and <1 x i8> %y, %notmask
22 %r = or <1 x i8> %mx, %my
23 ret <1 x i8> %r
24}
25
26; ============================================================================ ;
27; 16-bit vector width
28; ============================================================================ ;
29
30define <2 x i8> @out_v2i8(<2 x i8> %x, <2 x i8> %y, <2 x i8> %mask) nounwind {
31; CHECK-LABEL: out_v2i8:
32; CHECK: // %bb.0:
33; CHECK-NEXT: movi d3, #0x0000ff000000ff
34; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
35; CHECK-NEXT: eor v2.8b, v2.8b, v3.8b
36; CHECK-NEXT: and v1.8b, v1.8b, v2.8b
37; CHECK-NEXT: orr v0.8b, v0.8b, v1.8b
38; CHECK-NEXT: ret
39 %mx = and <2 x i8> %x, %mask
40 %notmask = xor <2 x i8> %mask, <i8 -1, i8 -1>
41 %my = and <2 x i8> %y, %notmask
42 %r = or <2 x i8> %mx, %my
43 ret <2 x i8> %r
44}
45
46define <1 x i16> @out_v1i16(<1 x i16> %x, <1 x i16> %y, <1 x i16> %mask) nounwind {
47; CHECK-LABEL: out_v1i16:
48; CHECK: // %bb.0:
49; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
50; CHECK-NEXT: mov v0.16b, v2.16b
51; CHECK-NEXT: ret
52 %mx = and <1 x i16> %x, %mask
53 %notmask = xor <1 x i16> %mask, <i16 -1>
54 %my = and <1 x i16> %y, %notmask
55 %r = or <1 x i16> %mx, %my
56 ret <1 x i16> %r
57}
58
59; ============================================================================ ;
60; 32-bit vector width
61; ============================================================================ ;
62
63define <4 x i8> @out_v4i8(<4 x i8> %x, <4 x i8> %y, <4 x i8> %mask) nounwind {
64; CHECK-LABEL: out_v4i8:
65; CHECK: // %bb.0:
66; CHECK-NEXT: movi d3, #0xff00ff00ff00ff
67; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
68; CHECK-NEXT: eor v2.8b, v2.8b, v3.8b
69; CHECK-NEXT: and v1.8b, v1.8b, v2.8b
70; CHECK-NEXT: orr v0.8b, v0.8b, v1.8b
71; CHECK-NEXT: ret
72 %mx = and <4 x i8> %x, %mask
73 %notmask = xor <4 x i8> %mask, <i8 -1, i8 -1, i8 -1, i8 -1>
74 %my = and <4 x i8> %y, %notmask
75 %r = or <4 x i8> %mx, %my
76 ret <4 x i8> %r
77}
78
79define <4 x i8> @out_v4i8_undef(<4 x i8> %x, <4 x i8> %y, <4 x i8> %mask) nounwind {
80; CHECK-LABEL: out_v4i8_undef:
81; CHECK: // %bb.0:
82; CHECK-NEXT: movi d3, #0xff00ff00ff00ff
83; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
84; CHECK-NEXT: eor v2.8b, v2.8b, v3.8b
85; CHECK-NEXT: and v1.8b, v1.8b, v2.8b
86; CHECK-NEXT: orr v0.8b, v0.8b, v1.8b
87; CHECK-NEXT: ret
88 %mx = and <4 x i8> %x, %mask
89 %notmask = xor <4 x i8> %mask, <i8 -1, i8 -1, i8 undef, i8 -1>
90 %my = and <4 x i8> %y, %notmask
91 %r = or <4 x i8> %mx, %my
92 ret <4 x i8> %r
93}
94
95define <2 x i16> @out_v2i16(<2 x i16> %x, <2 x i16> %y, <2 x i16> %mask) nounwind {
96; CHECK-LABEL: out_v2i16:
97; CHECK: // %bb.0:
98; CHECK-NEXT: movi d3, #0x00ffff0000ffff
99; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
100; CHECK-NEXT: eor v2.8b, v2.8b, v3.8b
101; CHECK-NEXT: and v1.8b, v1.8b, v2.8b
102; CHECK-NEXT: orr v0.8b, v0.8b, v1.8b
103; CHECK-NEXT: ret
104 %mx = and <2 x i16> %x, %mask
105 %notmask = xor <2 x i16> %mask, <i16 -1, i16 -1>
106 %my = and <2 x i16> %y, %notmask
107 %r = or <2 x i16> %mx, %my
108 ret <2 x i16> %r
109}
110
111define <1 x i32> @out_v1i32(<1 x i32> %x, <1 x i32> %y, <1 x i32> %mask) nounwind {
112; CHECK-LABEL: out_v1i32:
113; CHECK: // %bb.0:
114; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
115; CHECK-NEXT: mov v0.16b, v2.16b
116; CHECK-NEXT: ret
117 %mx = and <1 x i32> %x, %mask
118 %notmask = xor <1 x i32> %mask, <i32 -1>
119 %my = and <1 x i32> %y, %notmask
120 %r = or <1 x i32> %mx, %my
121 ret <1 x i32> %r
122}
123
124; ============================================================================ ;
125; 64-bit vector width
126; ============================================================================ ;
127
128define <8 x i8> @out_v8i8(<8 x i8> %x, <8 x i8> %y, <8 x i8> %mask) nounwind {
129; CHECK-LABEL: out_v8i8:
130; CHECK: // %bb.0:
131; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
132; CHECK-NEXT: mov v0.16b, v2.16b
133; CHECK-NEXT: ret
134 %mx = and <8 x i8> %x, %mask
135 %notmask = xor <8 x i8> %mask, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
136 %my = and <8 x i8> %y, %notmask
137 %r = or <8 x i8> %mx, %my
138 ret <8 x i8> %r
139}
140
141define <4 x i16> @out_v4i16(<4 x i16> %x, <4 x i16> %y, <4 x i16> %mask) nounwind {
142; CHECK-LABEL: out_v4i16:
143; CHECK: // %bb.0:
144; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
145; CHECK-NEXT: mov v0.16b, v2.16b
146; CHECK-NEXT: ret
147 %mx = and <4 x i16> %x, %mask
148 %notmask = xor <4 x i16> %mask, <i16 -1, i16 -1, i16 -1, i16 -1>
149 %my = and <4 x i16> %y, %notmask
150 %r = or <4 x i16> %mx, %my
151 ret <4 x i16> %r
152}
153
154define <4 x i16> @out_v4i16_undef(<4 x i16> %x, <4 x i16> %y, <4 x i16> %mask) nounwind {
155; CHECK-LABEL: out_v4i16_undef:
156; CHECK: // %bb.0:
157; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
158; CHECK-NEXT: mov v0.16b, v2.16b
159; CHECK-NEXT: ret
160 %mx = and <4 x i16> %x, %mask
161 %notmask = xor <4 x i16> %mask, <i16 -1, i16 -1, i16 undef, i16 -1>
162 %my = and <4 x i16> %y, %notmask
163 %r = or <4 x i16> %mx, %my
164 ret <4 x i16> %r
165}
166
167define <2 x i32> @out_v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %mask) nounwind {
168; CHECK-LABEL: out_v2i32:
169; CHECK: // %bb.0:
170; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
171; CHECK-NEXT: mov v0.16b, v2.16b
172; CHECK-NEXT: ret
173 %mx = and <2 x i32> %x, %mask
174 %notmask = xor <2 x i32> %mask, <i32 -1, i32 -1>
175 %my = and <2 x i32> %y, %notmask
176 %r = or <2 x i32> %mx, %my
177 ret <2 x i32> %r
178}
179
180define <1 x i64> @out_v1i64(<1 x i64> %x, <1 x i64> %y, <1 x i64> %mask) nounwind {
181; CHECK-LABEL: out_v1i64:
182; CHECK: // %bb.0:
183; CHECK-NEXT: bsl v2.8b, v0.8b, v1.8b
184; CHECK-NEXT: mov v0.16b, v2.16b
185; CHECK-NEXT: ret
186 %mx = and <1 x i64> %x, %mask
187 %notmask = xor <1 x i64> %mask, <i64 -1>
188 %my = and <1 x i64> %y, %notmask
189 %r = or <1 x i64> %mx, %my
190 ret <1 x i64> %r
191}
192
193; ============================================================================ ;
194; 128-bit vector width
195; ============================================================================ ;
196
197define <16 x i8> @out_v16i8(<16 x i8> %x, <16 x i8> %y, <16 x i8> %mask) nounwind {
198; CHECK-LABEL: out_v16i8:
199; CHECK: // %bb.0:
200; CHECK-NEXT: bsl v2.16b, v0.16b, v1.16b
201; CHECK-NEXT: mov v0.16b, v2.16b
202; CHECK-NEXT: ret
203 %mx = and <16 x i8> %x, %mask
204 %notmask = xor <16 x i8> %mask, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
205 %my = and <16 x i8> %y, %notmask
206 %r = or <16 x i8> %mx, %my
207 ret <16 x i8> %r
208}
209
210define <8 x i16> @out_v8i16(<8 x i16> %x, <8 x i16> %y, <8 x i16> %mask) nounwind {
211; CHECK-LABEL: out_v8i16:
212; CHECK: // %bb.0:
213; CHECK-NEXT: bsl v2.16b, v0.16b, v1.16b
214; CHECK-NEXT: mov v0.16b, v2.16b
215; CHECK-NEXT: ret
216 %mx = and <8 x i16> %x, %mask
217 %notmask = xor <8 x i16> %mask, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
218 %my = and <8 x i16> %y, %notmask
219 %r = or <8 x i16> %mx, %my
220 ret <8 x i16> %r
221}
222
223define <4 x i32> @out_v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) nounwind {
224; CHECK-LABEL: out_v4i32:
225; CHECK: // %bb.0:
226; CHECK-NEXT: bsl v2.16b, v0.16b, v1.16b
227; CHECK-NEXT: mov v0.16b, v2.16b
228; CHECK-NEXT: ret
229 %mx = and <4 x i32> %x, %mask
230 %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
231 %my = and <4 x i32> %y, %notmask
232 %r = or <4 x i32> %mx, %my
233 ret <4 x i32> %r
234}
235
236define <4 x i32> @out_v4i32_undef(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) nounwind {
237; CHECK-LABEL: out_v4i32_undef:
238; CHECK: // %bb.0:
239; CHECK-NEXT: bsl v2.16b, v0.16b, v1.16b
240; CHECK-NEXT: mov v0.16b, v2.16b
241; CHECK-NEXT: ret
242 %mx = and <4 x i32> %x, %mask
243 %notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 undef, i32 -1>
244 %my = and <4 x i32> %y, %notmask
245 %r = or <4 x i32> %mx, %my
246 ret <4 x i32> %r
247}
248
249define <2 x i64> @out_v2i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %mask) nounwind {
250; CHECK-LABEL: out_v2i64:
251; CHECK: // %bb.0:
252; CHECK-NEXT: bsl v2.16b, v0.16b, v1.16b
253; CHECK-NEXT: mov v0.16b, v2.16b
254; CHECK-NEXT: ret
255 %mx = and <2 x i64> %x, %mask
256 %notmask = xor <2 x i64> %mask, <i64 -1, i64 -1>
257 %my = and <2 x i64> %y, %notmask
258 %r = or <2 x i64> %mx, %my
259 ret <2 x i64> %r
260}
261
262;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
263; Should be the same as the previous one.
264;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
265
266; ============================================================================ ;
267; 8-bit vector width
268; ============================================================================ ;
269
270define <1 x i8> @in_v1i8(<1 x i8> %x, <1 x i8> %y, <1 x i8> %mask) nounwind {
271; CHECK-LABEL: in_v1i8:
272; CHECK: // %bb.0:
273; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
274; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
275; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
276; CHECK-NEXT: ret
277 %n0 = xor <1 x i8> %x, %y
278 %n1 = and <1 x i8> %n0, %mask
279 %r = xor <1 x i8> %n1, %y
280 ret <1 x i8> %r
281}
282
283; ============================================================================ ;
284; 16-bit vector width
285; ============================================================================ ;
286
287define <2 x i8> @in_v2i8(<2 x i8> %x, <2 x i8> %y, <2 x i8> %mask) nounwind {
288; CHECK-LABEL: in_v2i8:
289; CHECK: // %bb.0:
290; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
291; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
292; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
293; CHECK-NEXT: ret
294 %n0 = xor <2 x i8> %x, %y
295 %n1 = and <2 x i8> %n0, %mask
296 %r = xor <2 x i8> %n1, %y
297 ret <2 x i8> %r
298}
299
300define <1 x i16> @in_v1i16(<1 x i16> %x, <1 x i16> %y, <1 x i16> %mask) nounwind {
301; CHECK-LABEL: in_v1i16:
302; CHECK: // %bb.0:
303; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
304; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
305; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
306; CHECK-NEXT: ret
307 %n0 = xor <1 x i16> %x, %y
308 %n1 = and <1 x i16> %n0, %mask
309 %r = xor <1 x i16> %n1, %y
310 ret <1 x i16> %r
311}
312
313; ============================================================================ ;
314; 32-bit vector width
315; ============================================================================ ;
316
317define <4 x i8> @in_v4i8(<4 x i8> %x, <4 x i8> %y, <4 x i8> %mask) nounwind {
318; CHECK-LABEL: in_v4i8:
319; CHECK: // %bb.0:
320; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
321; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
322; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
323; CHECK-NEXT: ret
324 %n0 = xor <4 x i8> %x, %y
325 %n1 = and <4 x i8> %n0, %mask
326 %r = xor <4 x i8> %n1, %y
327 ret <4 x i8> %r
328}
329
330define <2 x i16> @in_v2i16(<2 x i16> %x, <2 x i16> %y, <2 x i16> %mask) nounwind {
331; CHECK-LABEL: in_v2i16:
332; CHECK: // %bb.0:
333; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
334; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
335; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
336; CHECK-NEXT: ret
337 %n0 = xor <2 x i16> %x, %y
338 %n1 = and <2 x i16> %n0, %mask
339 %r = xor <2 x i16> %n1, %y
340 ret <2 x i16> %r
341}
342
343define <1 x i32> @in_v1i32(<1 x i32> %x, <1 x i32> %y, <1 x i32> %mask) nounwind {
344; CHECK-LABEL: in_v1i32:
345; CHECK: // %bb.0:
346; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
347; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
348; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
349; CHECK-NEXT: ret
350 %n0 = xor <1 x i32> %x, %y
351 %n1 = and <1 x i32> %n0, %mask
352 %r = xor <1 x i32> %n1, %y
353 ret <1 x i32> %r
354}
355
356; ============================================================================ ;
357; 64-bit vector width
358; ============================================================================ ;
359
360define <8 x i8> @in_v8i8(<8 x i8> %x, <8 x i8> %y, <8 x i8> %mask) nounwind {
361; CHECK-LABEL: in_v8i8:
362; CHECK: // %bb.0:
363; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
364; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
365; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
366; CHECK-NEXT: ret
367 %n0 = xor <8 x i8> %x, %y
368 %n1 = and <8 x i8> %n0, %mask
369 %r = xor <8 x i8> %n1, %y
370 ret <8 x i8> %r
371}
372
373define <4 x i16> @in_v4i16(<4 x i16> %x, <4 x i16> %y, <4 x i16> %mask) nounwind {
374; CHECK-LABEL: in_v4i16:
375; CHECK: // %bb.0:
376; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
377; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
378; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
379; CHECK-NEXT: ret
380 %n0 = xor <4 x i16> %x, %y
381 %n1 = and <4 x i16> %n0, %mask
382 %r = xor <4 x i16> %n1, %y
383 ret <4 x i16> %r
384}
385
386define <2 x i32> @in_v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %mask) nounwind {
387; CHECK-LABEL: in_v2i32:
388; CHECK: // %bb.0:
389; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
390; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
391; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
392; CHECK-NEXT: ret
393 %n0 = xor <2 x i32> %x, %y
394 %n1 = and <2 x i32> %n0, %mask
395 %r = xor <2 x i32> %n1, %y
396 ret <2 x i32> %r
397}
398
399define <1 x i64> @in_v1i64(<1 x i64> %x, <1 x i64> %y, <1 x i64> %mask) nounwind {
400; CHECK-LABEL: in_v1i64:
401; CHECK: // %bb.0:
402; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
403; CHECK-NEXT: and v0.8b, v0.8b, v2.8b
404; CHECK-NEXT: eor v0.8b, v0.8b, v1.8b
405; CHECK-NEXT: ret
406 %n0 = xor <1 x i64> %x, %y
407 %n1 = and <1 x i64> %n0, %mask
408 %r = xor <1 x i64> %n1, %y
409 ret <1 x i64> %r
410}
411
412; ============================================================================ ;
413; 128-bit vector width
414; ============================================================================ ;
415
416define <16 x i8> @in_v16i8(<16 x i8> %x, <16 x i8> %y, <16 x i8> %mask) nounwind {
417; CHECK-LABEL: in_v16i8:
418; CHECK: // %bb.0:
419; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
420; CHECK-NEXT: and v0.16b, v0.16b, v2.16b
421; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
422; CHECK-NEXT: ret
423 %n0 = xor <16 x i8> %x, %y
424 %n1 = and <16 x i8> %n0, %mask
425 %r = xor <16 x i8> %n1, %y
426 ret <16 x i8> %r
427}
428
429define <8 x i16> @in_v8i16(<8 x i16> %x, <8 x i16> %y, <8 x i16> %mask) nounwind {
430; CHECK-LABEL: in_v8i16:
431; CHECK: // %bb.0:
432; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
433; CHECK-NEXT: and v0.16b, v0.16b, v2.16b
434; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
435; CHECK-NEXT: ret
436 %n0 = xor <8 x i16> %x, %y
437 %n1 = and <8 x i16> %n0, %mask
438 %r = xor <8 x i16> %n1, %y
439 ret <8 x i16> %r
440}
441
442define <4 x i32> @in_v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) nounwind {
443; CHECK-LABEL: in_v4i32:
444; CHECK: // %bb.0:
445; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
446; CHECK-NEXT: and v0.16b, v0.16b, v2.16b
447; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
448; CHECK-NEXT: ret
449 %n0 = xor <4 x i32> %x, %y
450 %n1 = and <4 x i32> %n0, %mask
451 %r = xor <4 x i32> %n1, %y
452 ret <4 x i32> %r
453}
454
455define <2 x i64> @in_v2i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %mask) nounwind {
456; CHECK-LABEL: in_v2i64:
457; CHECK: // %bb.0:
458; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
459; CHECK-NEXT: and v0.16b, v0.16b, v2.16b
460; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
461; CHECK-NEXT: ret
462 %n0 = xor <2 x i64> %x, %y
463 %n1 = and <2 x i64> %n0, %mask
464 %r = xor <2 x i64> %n1, %y
465 ret <2 x i64> %r
466}