xref: /llvm-project/llvm/test/CodeGen/AArch64/shift.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5define i1 @shl_i1(i1 %0, i1 %1){
6; CHECK-SD-LABEL: shl_i1:
7; CHECK-SD:       // %bb.0:
8; CHECK-SD-NEXT:    and w0, w0, #0x1
9; CHECK-SD-NEXT:    ret
10;
11; CHECK-GI-LABEL: shl_i1:
12; CHECK-GI:       // %bb.0:
13; CHECK-GI-NEXT:    and w8, w1, #0x1
14; CHECK-GI-NEXT:    lsl w8, w0, w8
15; CHECK-GI-NEXT:    and w0, w8, #0x1
16; CHECK-GI-NEXT:    ret
17    %3 = shl i1 %0, %1
18    ret i1 %3
19}
20
21define i8 @shl_i8(i8 %0, i8 %1){
22; CHECK-SD-LABEL: shl_i8:
23; CHECK-SD:       // %bb.0:
24; CHECK-SD-NEXT:    // kill: def $w1 killed $w1 def $x1
25; CHECK-SD-NEXT:    lsl w0, w0, w1
26; CHECK-SD-NEXT:    ret
27;
28; CHECK-GI-LABEL: shl_i8:
29; CHECK-GI:       // %bb.0:
30; CHECK-GI-NEXT:    and w8, w1, #0xff
31; CHECK-GI-NEXT:    lsl w0, w0, w8
32; CHECK-GI-NEXT:    ret
33    %3 = shl i8 %0, %1
34    ret i8 %3
35}
36
37define i16 @shl_i16(i16 %0, i16 %1){
38; CHECK-SD-LABEL: shl_i16:
39; CHECK-SD:       // %bb.0:
40; CHECK-SD-NEXT:    // kill: def $w1 killed $w1 def $x1
41; CHECK-SD-NEXT:    lsl w0, w0, w1
42; CHECK-SD-NEXT:    ret
43;
44; CHECK-GI-LABEL: shl_i16:
45; CHECK-GI:       // %bb.0:
46; CHECK-GI-NEXT:    and w8, w1, #0xffff
47; CHECK-GI-NEXT:    lsl w0, w0, w8
48; CHECK-GI-NEXT:    ret
49    %3 = shl i16 %0, %1
50    ret i16 %3
51}
52
53define i32 @shl_i32(i32 %0, i32 %1){
54; CHECK-LABEL: shl_i32:
55; CHECK:       // %bb.0:
56; CHECK-NEXT:    lsl w0, w0, w1
57; CHECK-NEXT:    ret
58    %3 = shl i32 %0, %1
59    ret i32 %3
60}
61
62define i64 @shl_i64(i64 %0, i64 %1){
63; CHECK-LABEL: shl_i64:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    lsl x0, x0, x1
66; CHECK-NEXT:    ret
67    %3 = shl i64 %0, %1
68    ret i64 %3
69}
70
71define i128 @shl_i128(i128 %0, i128 %1){
72; CHECK-SD-LABEL: shl_i128:
73; CHECK-SD:       // %bb.0:
74; CHECK-SD-NEXT:    lsr x8, x0, #1
75; CHECK-SD-NEXT:    mvn w9, w2
76; CHECK-SD-NEXT:    lsl x10, x1, x2
77; CHECK-SD-NEXT:    tst x2, #0x40
78; CHECK-SD-NEXT:    lsr x8, x8, x9
79; CHECK-SD-NEXT:    lsl x9, x0, x2
80; CHECK-SD-NEXT:    orr x8, x10, x8
81; CHECK-SD-NEXT:    csel x0, xzr, x9, ne
82; CHECK-SD-NEXT:    csel x1, x9, x8, ne
83; CHECK-SD-NEXT:    ret
84;
85; CHECK-GI-LABEL: shl_i128:
86; CHECK-GI:       // %bb.0:
87; CHECK-GI-NEXT:    mov w8, #64 // =0x40
88; CHECK-GI-NEXT:    sub x9, x2, #64
89; CHECK-GI-NEXT:    lsl x10, x1, x2
90; CHECK-GI-NEXT:    sub x8, x8, x2
91; CHECK-GI-NEXT:    lsl x11, x0, x2
92; CHECK-GI-NEXT:    lsl x9, x0, x9
93; CHECK-GI-NEXT:    lsr x8, x0, x8
94; CHECK-GI-NEXT:    cmp x2, #64
95; CHECK-GI-NEXT:    csel x0, x11, xzr, lo
96; CHECK-GI-NEXT:    orr x8, x8, x10
97; CHECK-GI-NEXT:    csel x8, x8, x9, lo
98; CHECK-GI-NEXT:    cmp x2, #0
99; CHECK-GI-NEXT:    csel x1, x1, x8, eq
100; CHECK-GI-NEXT:    ret
101    %3 = shl i128 %0, %1
102    ret i128 %3
103}
104
105define i1 @ashr_i1(i1 %0, i1 %1){
106; CHECK-SD-LABEL: ashr_i1:
107; CHECK-SD:       // %bb.0:
108; CHECK-SD-NEXT:    and w0, w0, #0x1
109; CHECK-SD-NEXT:    ret
110;
111; CHECK-GI-LABEL: ashr_i1:
112; CHECK-GI:       // %bb.0:
113; CHECK-GI-NEXT:    sbfx w8, w0, #0, #1
114; CHECK-GI-NEXT:    and w9, w1, #0x1
115; CHECK-GI-NEXT:    asr w8, w8, w9
116; CHECK-GI-NEXT:    and w0, w8, #0x1
117; CHECK-GI-NEXT:    ret
118    %3 = ashr i1 %0, %1
119    ret i1 %3
120}
121
122define i8 @ashr_i8(i8 %0, i8 %1){
123; CHECK-SD-LABEL: ashr_i8:
124; CHECK-SD:       // %bb.0:
125; CHECK-SD-NEXT:    sxtb w8, w0
126; CHECK-SD-NEXT:    // kill: def $w1 killed $w1 def $x1
127; CHECK-SD-NEXT:    asr w0, w8, w1
128; CHECK-SD-NEXT:    ret
129;
130; CHECK-GI-LABEL: ashr_i8:
131; CHECK-GI:       // %bb.0:
132; CHECK-GI-NEXT:    sxtb w8, w0
133; CHECK-GI-NEXT:    and w9, w1, #0xff
134; CHECK-GI-NEXT:    asr w0, w8, w9
135; CHECK-GI-NEXT:    ret
136    %3 = ashr i8 %0, %1
137    ret i8 %3
138}
139
140define i16 @ashr_i16(i16 %0, i16 %1){
141; CHECK-SD-LABEL: ashr_i16:
142; CHECK-SD:       // %bb.0:
143; CHECK-SD-NEXT:    sxth w8, w0
144; CHECK-SD-NEXT:    // kill: def $w1 killed $w1 def $x1
145; CHECK-SD-NEXT:    asr w0, w8, w1
146; CHECK-SD-NEXT:    ret
147;
148; CHECK-GI-LABEL: ashr_i16:
149; CHECK-GI:       // %bb.0:
150; CHECK-GI-NEXT:    sxth w8, w0
151; CHECK-GI-NEXT:    and w9, w1, #0xffff
152; CHECK-GI-NEXT:    asr w0, w8, w9
153; CHECK-GI-NEXT:    ret
154    %3 = ashr i16 %0, %1
155    ret i16 %3
156}
157
158define i32 @ashr_i32(i32 %0, i32 %1){
159; CHECK-LABEL: ashr_i32:
160; CHECK:       // %bb.0:
161; CHECK-NEXT:    asr w0, w0, w1
162; CHECK-NEXT:    ret
163    %3 = ashr i32 %0, %1
164    ret i32 %3
165}
166
167define i64 @ashr_i64(i64 %0, i64 %1){
168; CHECK-LABEL: ashr_i64:
169; CHECK:       // %bb.0:
170; CHECK-NEXT:    asr x0, x0, x1
171; CHECK-NEXT:    ret
172    %3 = ashr i64 %0, %1
173    ret i64 %3
174}
175
176define i128 @ashr_i128(i128 %0, i128 %1){
177; CHECK-SD-LABEL: ashr_i128:
178; CHECK-SD:       // %bb.0:
179; CHECK-SD-NEXT:    lsl x8, x1, #1
180; CHECK-SD-NEXT:    mvn w9, w2
181; CHECK-SD-NEXT:    lsr x10, x0, x2
182; CHECK-SD-NEXT:    asr x11, x1, #63
183; CHECK-SD-NEXT:    tst x2, #0x40
184; CHECK-SD-NEXT:    lsl x8, x8, x9
185; CHECK-SD-NEXT:    asr x9, x1, x2
186; CHECK-SD-NEXT:    orr x8, x8, x10
187; CHECK-SD-NEXT:    csel x1, x11, x9, ne
188; CHECK-SD-NEXT:    csel x0, x9, x8, ne
189; CHECK-SD-NEXT:    ret
190;
191; CHECK-GI-LABEL: ashr_i128:
192; CHECK-GI:       // %bb.0:
193; CHECK-GI-NEXT:    mov w8, #64 // =0x40
194; CHECK-GI-NEXT:    sub x9, x2, #64
195; CHECK-GI-NEXT:    lsr x10, x0, x2
196; CHECK-GI-NEXT:    sub x8, x8, x2
197; CHECK-GI-NEXT:    asr x9, x1, x9
198; CHECK-GI-NEXT:    cmp x2, #64
199; CHECK-GI-NEXT:    lsl x8, x1, x8
200; CHECK-GI-NEXT:    asr x11, x1, x2
201; CHECK-GI-NEXT:    orr x8, x10, x8
202; CHECK-GI-NEXT:    asr x10, x1, #63
203; CHECK-GI-NEXT:    csel x8, x8, x9, lo
204; CHECK-GI-NEXT:    cmp x2, #0
205; CHECK-GI-NEXT:    csel x0, x0, x8, eq
206; CHECK-GI-NEXT:    cmp x2, #64
207; CHECK-GI-NEXT:    csel x1, x11, x10, lo
208; CHECK-GI-NEXT:    ret
209    %3 = ashr i128 %0, %1
210    ret i128 %3
211}
212
213define i1 @lshr_i1(i1 %0, i1 %1){
214; CHECK-SD-LABEL: lshr_i1:
215; CHECK-SD:       // %bb.0:
216; CHECK-SD-NEXT:    and w0, w0, #0x1
217; CHECK-SD-NEXT:    ret
218;
219; CHECK-GI-LABEL: lshr_i1:
220; CHECK-GI:       // %bb.0:
221; CHECK-GI-NEXT:    and w8, w1, #0x1
222; CHECK-GI-NEXT:    and w9, w0, #0x1
223; CHECK-GI-NEXT:    lsr w0, w9, w8
224; CHECK-GI-NEXT:    ret
225    %3 = lshr i1 %0, %1
226    ret i1 %3
227}
228
229define i8 @lshr_i8(i8 %0, i8 %1){
230; CHECK-SD-LABEL: lshr_i8:
231; CHECK-SD:       // %bb.0:
232; CHECK-SD-NEXT:    and w8, w0, #0xff
233; CHECK-SD-NEXT:    // kill: def $w1 killed $w1 def $x1
234; CHECK-SD-NEXT:    lsr w0, w8, w1
235; CHECK-SD-NEXT:    ret
236;
237; CHECK-GI-LABEL: lshr_i8:
238; CHECK-GI:       // %bb.0:
239; CHECK-GI-NEXT:    and w8, w1, #0xff
240; CHECK-GI-NEXT:    and w9, w0, #0xff
241; CHECK-GI-NEXT:    lsr w0, w9, w8
242; CHECK-GI-NEXT:    ret
243    %3 = lshr i8 %0, %1
244    ret i8 %3
245}
246
247define i16 @lshr_i16(i16 %0, i16 %1){
248; CHECK-SD-LABEL: lshr_i16:
249; CHECK-SD:       // %bb.0:
250; CHECK-SD-NEXT:    and w8, w0, #0xffff
251; CHECK-SD-NEXT:    // kill: def $w1 killed $w1 def $x1
252; CHECK-SD-NEXT:    lsr w0, w8, w1
253; CHECK-SD-NEXT:    ret
254;
255; CHECK-GI-LABEL: lshr_i16:
256; CHECK-GI:       // %bb.0:
257; CHECK-GI-NEXT:    and w8, w1, #0xffff
258; CHECK-GI-NEXT:    and w9, w0, #0xffff
259; CHECK-GI-NEXT:    lsr w0, w9, w8
260; CHECK-GI-NEXT:    ret
261    %3 = lshr i16 %0, %1
262    ret i16 %3
263}
264
265define i32 @lshr_i32(i32 %0, i32 %1){
266; CHECK-LABEL: lshr_i32:
267; CHECK:       // %bb.0:
268; CHECK-NEXT:    lsr w0, w0, w1
269; CHECK-NEXT:    ret
270    %3 = lshr i32 %0, %1
271    ret i32 %3
272}
273
274define i64 @lshr_i64(i64 %0, i64 %1){
275; CHECK-LABEL: lshr_i64:
276; CHECK:       // %bb.0:
277; CHECK-NEXT:    lsr x0, x0, x1
278; CHECK-NEXT:    ret
279    %3 = lshr i64 %0, %1
280    ret i64 %3
281}
282
283define i128 @lshr_i128(i128 %0, i128 %1){
284; CHECK-SD-LABEL: lshr_i128:
285; CHECK-SD:       // %bb.0:
286; CHECK-SD-NEXT:    lsl x8, x1, #1
287; CHECK-SD-NEXT:    mvn w9, w2
288; CHECK-SD-NEXT:    lsr x10, x0, x2
289; CHECK-SD-NEXT:    tst x2, #0x40
290; CHECK-SD-NEXT:    lsl x8, x8, x9
291; CHECK-SD-NEXT:    lsr x9, x1, x2
292; CHECK-SD-NEXT:    orr x8, x8, x10
293; CHECK-SD-NEXT:    csel x1, xzr, x9, ne
294; CHECK-SD-NEXT:    csel x0, x9, x8, ne
295; CHECK-SD-NEXT:    ret
296;
297; CHECK-GI-LABEL: lshr_i128:
298; CHECK-GI:       // %bb.0:
299; CHECK-GI-NEXT:    mov w8, #64 // =0x40
300; CHECK-GI-NEXT:    sub x9, x2, #64
301; CHECK-GI-NEXT:    lsr x10, x0, x2
302; CHECK-GI-NEXT:    sub x8, x8, x2
303; CHECK-GI-NEXT:    lsr x9, x1, x9
304; CHECK-GI-NEXT:    cmp x2, #64
305; CHECK-GI-NEXT:    lsl x8, x1, x8
306; CHECK-GI-NEXT:    orr x8, x10, x8
307; CHECK-GI-NEXT:    lsr x10, x1, x2
308; CHECK-GI-NEXT:    csel x8, x8, x9, lo
309; CHECK-GI-NEXT:    cmp x2, #0
310; CHECK-GI-NEXT:    csel x0, x0, x8, eq
311; CHECK-GI-NEXT:    cmp x2, #64
312; CHECK-GI-NEXT:    csel x1, x10, xzr, lo
313; CHECK-GI-NEXT:    ret
314    %3 = lshr i128 %0, %1
315    ret i128 %3
316}
317
318; ===== Legal Vector Type =====
319
320define <8 x i8> @shl_v8i8(<8 x i8> %0, <8 x i8> %1){
321; CHECK-LABEL: shl_v8i8:
322; CHECK:       // %bb.0:
323; CHECK-NEXT:    ushl v0.8b, v0.8b, v1.8b
324; CHECK-NEXT:    ret
325    %3 = shl <8 x i8> %0, %1
326    ret <8 x i8> %3
327}
328
329define <16 x i8> @shl_v16i8(<16 x i8> %0, <16 x i8> %1){
330; CHECK-LABEL: shl_v16i8:
331; CHECK:       // %bb.0:
332; CHECK-NEXT:    ushl v0.16b, v0.16b, v1.16b
333; CHECK-NEXT:    ret
334    %3 = shl <16 x i8> %0, %1
335    ret <16 x i8> %3
336}
337
338define <4 x i16> @shl_v4i16(<4 x i16> %0, <4 x i16> %1){
339; CHECK-LABEL: shl_v4i16:
340; CHECK:       // %bb.0:
341; CHECK-NEXT:    ushl v0.4h, v0.4h, v1.4h
342; CHECK-NEXT:    ret
343    %3 = shl <4 x i16> %0, %1
344    ret <4 x i16> %3
345}
346
347define <8 x i16> @shl_v8i16(<8 x i16> %0, <8 x i16> %1){
348; CHECK-LABEL: shl_v8i16:
349; CHECK:       // %bb.0:
350; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
351; CHECK-NEXT:    ret
352    %3 = shl <8 x i16> %0, %1
353    ret <8 x i16> %3
354}
355
356define <2 x i32> @shl_v2i32(<2 x i32> %0, <2 x i32> %1){
357; CHECK-LABEL: shl_v2i32:
358; CHECK:       // %bb.0:
359; CHECK-NEXT:    ushl v0.2s, v0.2s, v1.2s
360; CHECK-NEXT:    ret
361    %3 = shl <2 x i32> %0, %1
362    ret <2 x i32> %3
363}
364
365define <4 x i32> @shl_v4i32(<4 x i32> %0, <4 x i32> %1){
366; CHECK-LABEL: shl_v4i32:
367; CHECK:       // %bb.0:
368; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
369; CHECK-NEXT:    ret
370    %3 = shl <4 x i32> %0, %1
371    ret <4 x i32> %3
372}
373
374define <2 x i64> @shl_v2i64(<2 x i64> %0, <2 x i64> %1){
375; CHECK-LABEL: shl_v2i64:
376; CHECK:       // %bb.0:
377; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
378; CHECK-NEXT:    ret
379    %3 = shl <2 x i64> %0, %1
380    ret <2 x i64> %3
381}
382
383define <8 x i8> @ashr_v8i8(<8 x i8> %0, <8 x i8> %1){
384; CHECK-LABEL: ashr_v8i8:
385; CHECK:       // %bb.0:
386; CHECK-NEXT:    neg v1.8b, v1.8b
387; CHECK-NEXT:    sshl v0.8b, v0.8b, v1.8b
388; CHECK-NEXT:    ret
389    %3 = ashr <8 x i8> %0, %1
390    ret <8 x i8> %3
391}
392
393define <16 x i8> @ashr_v16i8(<16 x i8> %0, <16 x i8> %1){
394; CHECK-LABEL: ashr_v16i8:
395; CHECK:       // %bb.0:
396; CHECK-NEXT:    neg v1.16b, v1.16b
397; CHECK-NEXT:    sshl v0.16b, v0.16b, v1.16b
398; CHECK-NEXT:    ret
399    %3 = ashr <16 x i8> %0, %1
400    ret <16 x i8> %3
401}
402
403define <4 x i16> @ashr_v4i16(<4 x i16> %0, <4 x i16> %1){
404; CHECK-LABEL: ashr_v4i16:
405; CHECK:       // %bb.0:
406; CHECK-NEXT:    neg v1.4h, v1.4h
407; CHECK-NEXT:    sshl v0.4h, v0.4h, v1.4h
408; CHECK-NEXT:    ret
409    %3 = ashr <4 x i16> %0, %1
410    ret <4 x i16> %3
411}
412
413define <8 x i16> @ashr_v8i16(<8 x i16> %0, <8 x i16> %1){
414; CHECK-LABEL: ashr_v8i16:
415; CHECK:       // %bb.0:
416; CHECK-NEXT:    neg v1.8h, v1.8h
417; CHECK-NEXT:    sshl v0.8h, v0.8h, v1.8h
418; CHECK-NEXT:    ret
419    %3 = ashr <8 x i16> %0, %1
420    ret <8 x i16> %3
421}
422
423define <2 x i32> @ashr_v2i32(<2 x i32> %0, <2 x i32> %1){
424; CHECK-LABEL: ashr_v2i32:
425; CHECK:       // %bb.0:
426; CHECK-NEXT:    neg v1.2s, v1.2s
427; CHECK-NEXT:    sshl v0.2s, v0.2s, v1.2s
428; CHECK-NEXT:    ret
429    %3 = ashr <2 x i32> %0, %1
430    ret <2 x i32> %3
431}
432
433define <4 x i32> @ashr_v4i32(<4 x i32> %0, <4 x i32> %1){
434; CHECK-LABEL: ashr_v4i32:
435; CHECK:       // %bb.0:
436; CHECK-NEXT:    neg v1.4s, v1.4s
437; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
438; CHECK-NEXT:    ret
439    %3 = ashr <4 x i32> %0, %1
440    ret <4 x i32> %3
441}
442
443define <2 x i64> @ashr_v2i64(<2 x i64> %0, <2 x i64> %1){
444; CHECK-LABEL: ashr_v2i64:
445; CHECK:       // %bb.0:
446; CHECK-NEXT:    neg v1.2d, v1.2d
447; CHECK-NEXT:    sshl v0.2d, v0.2d, v1.2d
448; CHECK-NEXT:    ret
449    %3 = ashr <2 x i64> %0, %1
450    ret <2 x i64> %3
451}
452
453define <8 x i8> @lshr_v8i8(<8 x i8> %0, <8 x i8> %1){
454; CHECK-LABEL: lshr_v8i8:
455; CHECK:       // %bb.0:
456; CHECK-NEXT:    neg v1.8b, v1.8b
457; CHECK-NEXT:    ushl v0.8b, v0.8b, v1.8b
458; CHECK-NEXT:    ret
459    %3 = lshr <8 x i8> %0, %1
460    ret <8 x i8> %3
461}
462
463define <16 x i8> @lshr_v16i8(<16 x i8> %0, <16 x i8> %1){
464; CHECK-LABEL: lshr_v16i8:
465; CHECK:       // %bb.0:
466; CHECK-NEXT:    neg v1.16b, v1.16b
467; CHECK-NEXT:    ushl v0.16b, v0.16b, v1.16b
468; CHECK-NEXT:    ret
469    %3 = lshr <16 x i8> %0, %1
470    ret <16 x i8> %3
471}
472
473define <4 x i16> @lshr_v4i16(<4 x i16> %0, <4 x i16> %1){
474; CHECK-LABEL: lshr_v4i16:
475; CHECK:       // %bb.0:
476; CHECK-NEXT:    neg v1.4h, v1.4h
477; CHECK-NEXT:    ushl v0.4h, v0.4h, v1.4h
478; CHECK-NEXT:    ret
479    %3 = lshr <4 x i16> %0, %1
480    ret <4 x i16> %3
481}
482
483define <8 x i16> @lshr_v8i16(<8 x i16> %0, <8 x i16> %1){
484; CHECK-LABEL: lshr_v8i16:
485; CHECK:       // %bb.0:
486; CHECK-NEXT:    neg v1.8h, v1.8h
487; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
488; CHECK-NEXT:    ret
489    %3 = lshr <8 x i16> %0, %1
490    ret <8 x i16> %3
491}
492
493define <2 x i32> @lshr_v2i32(<2 x i32> %0, <2 x i32> %1){
494; CHECK-LABEL: lshr_v2i32:
495; CHECK:       // %bb.0:
496; CHECK-NEXT:    neg v1.2s, v1.2s
497; CHECK-NEXT:    ushl v0.2s, v0.2s, v1.2s
498; CHECK-NEXT:    ret
499    %3 = lshr <2 x i32> %0, %1
500    ret <2 x i32> %3
501}
502
503define <4 x i32> @lshr_v4i32(<4 x i32> %0, <4 x i32> %1){
504; CHECK-LABEL: lshr_v4i32:
505; CHECK:       // %bb.0:
506; CHECK-NEXT:    neg v1.4s, v1.4s
507; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
508; CHECK-NEXT:    ret
509    %3 = lshr <4 x i32> %0, %1
510    ret <4 x i32> %3
511}
512
513define <2 x i64> @lshr_v2i64(<2 x i64> %0, <2 x i64> %1){
514; CHECK-LABEL: lshr_v2i64:
515; CHECK:       // %bb.0:
516; CHECK-NEXT:    neg v1.2d, v1.2d
517; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
518; CHECK-NEXT:    ret
519    %3 = lshr <2 x i64> %0, %1
520    ret <2 x i64> %3
521}
522
523; ===== Vector Larger/Smaller than Legal =====
524
525define <4 x i8> @shl_v4i8(<4 x i8> %0, <4 x i8> %1){
526; CHECK-SD-LABEL: shl_v4i8:
527; CHECK-SD:       // %bb.0:
528; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
529; CHECK-SD-NEXT:    ushl v0.4h, v0.4h, v1.4h
530; CHECK-SD-NEXT:    ret
531;
532; CHECK-GI-LABEL: shl_v4i8:
533; CHECK-GI:       // %bb.0:
534; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
535; CHECK-GI-NEXT:    uzp1 v1.8b, v1.8b, v0.8b
536; CHECK-GI-NEXT:    ushl v0.8b, v0.8b, v1.8b
537; CHECK-GI-NEXT:    ushll v0.8h, v0.8b, #0
538; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
539; CHECK-GI-NEXT:    ret
540    %3 = shl <4 x i8> %0, %1
541    ret <4 x i8> %3
542}
543
544define <32 x i8> @shl_v32i8(<32 x i8> %0, <32 x i8> %1){
545; CHECK-SD-LABEL: shl_v32i8:
546; CHECK-SD:       // %bb.0:
547; CHECK-SD-NEXT:    ushl v1.16b, v1.16b, v3.16b
548; CHECK-SD-NEXT:    ushl v0.16b, v0.16b, v2.16b
549; CHECK-SD-NEXT:    ret
550;
551; CHECK-GI-LABEL: shl_v32i8:
552; CHECK-GI:       // %bb.0:
553; CHECK-GI-NEXT:    ushl v0.16b, v0.16b, v2.16b
554; CHECK-GI-NEXT:    ushl v1.16b, v1.16b, v3.16b
555; CHECK-GI-NEXT:    ret
556    %3 = shl <32 x i8> %0, %1
557    ret <32 x i8> %3
558}
559
560define <2 x i16> @shl_v2i16(<2 x i16> %0, <2 x i16> %1){
561; CHECK-SD-LABEL: shl_v2i16:
562; CHECK-SD:       // %bb.0:
563; CHECK-SD-NEXT:    movi d2, #0x00ffff0000ffff
564; CHECK-SD-NEXT:    and v1.8b, v1.8b, v2.8b
565; CHECK-SD-NEXT:    ushl v0.2s, v0.2s, v1.2s
566; CHECK-SD-NEXT:    ret
567;
568; CHECK-GI-LABEL: shl_v2i16:
569; CHECK-GI:       // %bb.0:
570; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h
571; CHECK-GI-NEXT:    uzp1 v1.4h, v1.4h, v0.4h
572; CHECK-GI-NEXT:    ushl v0.4h, v0.4h, v1.4h
573; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
574; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
575; CHECK-GI-NEXT:    ret
576    %3 = shl <2 x i16> %0, %1
577    ret <2 x i16> %3
578}
579
580define <16 x i16> @shl_v16i16(<16 x i16> %0, <16 x i16> %1){
581; CHECK-SD-LABEL: shl_v16i16:
582; CHECK-SD:       // %bb.0:
583; CHECK-SD-NEXT:    ushl v1.8h, v1.8h, v3.8h
584; CHECK-SD-NEXT:    ushl v0.8h, v0.8h, v2.8h
585; CHECK-SD-NEXT:    ret
586;
587; CHECK-GI-LABEL: shl_v16i16:
588; CHECK-GI:       // %bb.0:
589; CHECK-GI-NEXT:    ushl v0.8h, v0.8h, v2.8h
590; CHECK-GI-NEXT:    ushl v1.8h, v1.8h, v3.8h
591; CHECK-GI-NEXT:    ret
592    %3 = shl <16 x i16> %0, %1
593    ret <16 x i16> %3
594}
595
596define <1 x i32> @shl_v1i32(<1 x i32> %0, <1 x i32> %1){
597; CHECK-SD-LABEL: shl_v1i32:
598; CHECK-SD:       // %bb.0:
599; CHECK-SD-NEXT:    ushl v0.2s, v0.2s, v1.2s
600; CHECK-SD-NEXT:    ret
601;
602; CHECK-GI-LABEL: shl_v1i32:
603; CHECK-GI:       // %bb.0:
604; CHECK-GI-NEXT:    fmov w8, s0
605; CHECK-GI-NEXT:    fmov w9, s1
606; CHECK-GI-NEXT:    lsl w8, w8, w9
607; CHECK-GI-NEXT:    mov v0.s[0], w8
608; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
609; CHECK-GI-NEXT:    ret
610    %3 = shl <1 x i32> %0, %1
611    ret <1 x i32> %3
612}
613
614define <8 x i32> @shl_v8i32(<8 x i32> %0, <8 x i32> %1){
615; CHECK-SD-LABEL: shl_v8i32:
616; CHECK-SD:       // %bb.0:
617; CHECK-SD-NEXT:    ushl v1.4s, v1.4s, v3.4s
618; CHECK-SD-NEXT:    ushl v0.4s, v0.4s, v2.4s
619; CHECK-SD-NEXT:    ret
620;
621; CHECK-GI-LABEL: shl_v8i32:
622; CHECK-GI:       // %bb.0:
623; CHECK-GI-NEXT:    ushl v0.4s, v0.4s, v2.4s
624; CHECK-GI-NEXT:    ushl v1.4s, v1.4s, v3.4s
625; CHECK-GI-NEXT:    ret
626    %3 = shl <8 x i32> %0, %1
627    ret <8 x i32> %3
628}
629
630define <4 x i64> @shl_v4i64(<4 x i64> %0, <4 x i64> %1){
631; CHECK-SD-LABEL: shl_v4i64:
632; CHECK-SD:       // %bb.0:
633; CHECK-SD-NEXT:    ushl v1.2d, v1.2d, v3.2d
634; CHECK-SD-NEXT:    ushl v0.2d, v0.2d, v2.2d
635; CHECK-SD-NEXT:    ret
636;
637; CHECK-GI-LABEL: shl_v4i64:
638; CHECK-GI:       // %bb.0:
639; CHECK-GI-NEXT:    ushl v0.2d, v0.2d, v2.2d
640; CHECK-GI-NEXT:    ushl v1.2d, v1.2d, v3.2d
641; CHECK-GI-NEXT:    ret
642    %3 = shl <4 x i64> %0, %1
643    ret <4 x i64> %3
644}
645
646define <2 x i128> @shl_v2i128(<2 x i128> %0, <2 x i128> %1){
647; CHECK-SD-LABEL: shl_v2i128:
648; CHECK-SD:       // %bb.0:
649; CHECK-SD-NEXT:    lsr x8, x0, #1
650; CHECK-SD-NEXT:    mvn w9, w4
651; CHECK-SD-NEXT:    lsl x10, x1, x4
652; CHECK-SD-NEXT:    mvn w12, w6
653; CHECK-SD-NEXT:    lsl x11, x0, x4
654; CHECK-SD-NEXT:    lsl x13, x3, x6
655; CHECK-SD-NEXT:    lsr x8, x8, x9
656; CHECK-SD-NEXT:    lsr x9, x2, #1
657; CHECK-SD-NEXT:    tst x4, #0x40
658; CHECK-SD-NEXT:    csel x0, xzr, x11, ne
659; CHECK-SD-NEXT:    lsr x9, x9, x12
660; CHECK-SD-NEXT:    orr x8, x10, x8
661; CHECK-SD-NEXT:    lsl x10, x2, x6
662; CHECK-SD-NEXT:    csel x1, x11, x8, ne
663; CHECK-SD-NEXT:    tst x6, #0x40
664; CHECK-SD-NEXT:    orr x8, x13, x9
665; CHECK-SD-NEXT:    csel x2, xzr, x10, ne
666; CHECK-SD-NEXT:    csel x3, x10, x8, ne
667; CHECK-SD-NEXT:    ret
668;
669; CHECK-GI-LABEL: shl_v2i128:
670; CHECK-GI:       // %bb.0:
671; CHECK-GI-NEXT:    mov w8, #64 // =0x40
672; CHECK-GI-NEXT:    sub x10, x4, #64
673; CHECK-GI-NEXT:    lsl x11, x1, x4
674; CHECK-GI-NEXT:    sub x9, x8, x4
675; CHECK-GI-NEXT:    lsl x10, x0, x10
676; CHECK-GI-NEXT:    lsl x12, x0, x4
677; CHECK-GI-NEXT:    lsr x9, x0, x9
678; CHECK-GI-NEXT:    cmp x4, #64
679; CHECK-GI-NEXT:    sub x8, x8, x6
680; CHECK-GI-NEXT:    lsr x8, x2, x8
681; CHECK-GI-NEXT:    csel x0, x12, xzr, lo
682; CHECK-GI-NEXT:    lsl x12, x2, x6
683; CHECK-GI-NEXT:    orr x9, x9, x11
684; CHECK-GI-NEXT:    lsl x11, x3, x6
685; CHECK-GI-NEXT:    csel x9, x9, x10, lo
686; CHECK-GI-NEXT:    sub x10, x6, #64
687; CHECK-GI-NEXT:    cmp x4, #0
688; CHECK-GI-NEXT:    lsl x10, x2, x10
689; CHECK-GI-NEXT:    csel x1, x1, x9, eq
690; CHECK-GI-NEXT:    orr x8, x8, x11
691; CHECK-GI-NEXT:    cmp x6, #64
692; CHECK-GI-NEXT:    csel x2, x12, xzr, lo
693; CHECK-GI-NEXT:    csel x8, x8, x10, lo
694; CHECK-GI-NEXT:    cmp x6, #0
695; CHECK-GI-NEXT:    csel x3, x3, x8, eq
696; CHECK-GI-NEXT:    ret
697    %3 = shl <2 x i128> %0, %1
698    ret <2 x i128> %3
699}
700
701define <4 x i8> @ashr_v4i8(<4 x i8> %0, <4 x i8> %1){
702; CHECK-SD-LABEL: ashr_v4i8:
703; CHECK-SD:       // %bb.0:
704; CHECK-SD-NEXT:    shl v0.4h, v0.4h, #8
705; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
706; CHECK-SD-NEXT:    sshr v0.4h, v0.4h, #8
707; CHECK-SD-NEXT:    neg v1.4h, v1.4h
708; CHECK-SD-NEXT:    sshl v0.4h, v0.4h, v1.4h
709; CHECK-SD-NEXT:    ret
710;
711; CHECK-GI-LABEL: ashr_v4i8:
712; CHECK-GI:       // %bb.0:
713; CHECK-GI-NEXT:    uzp1 v1.8b, v1.8b, v0.8b
714; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
715; CHECK-GI-NEXT:    neg v1.8b, v1.8b
716; CHECK-GI-NEXT:    sshl v0.8b, v0.8b, v1.8b
717; CHECK-GI-NEXT:    ushll v0.8h, v0.8b, #0
718; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
719; CHECK-GI-NEXT:    ret
720    %3 = ashr <4 x i8> %0, %1
721    ret <4 x i8> %3
722}
723
724define <32 x i8> @ashr_v32i8(<32 x i8> %0, <32 x i8> %1){
725; CHECK-LABEL: ashr_v32i8:
726; CHECK:       // %bb.0:
727; CHECK-NEXT:    neg v2.16b, v2.16b
728; CHECK-NEXT:    neg v3.16b, v3.16b
729; CHECK-NEXT:    sshl v0.16b, v0.16b, v2.16b
730; CHECK-NEXT:    sshl v1.16b, v1.16b, v3.16b
731; CHECK-NEXT:    ret
732    %3 = ashr <32 x i8> %0, %1
733    ret <32 x i8> %3
734}
735
736define <2 x i16> @ashr_v2i16(<2 x i16> %0, <2 x i16> %1){
737; CHECK-SD-LABEL: ashr_v2i16:
738; CHECK-SD:       // %bb.0:
739; CHECK-SD-NEXT:    movi d2, #0x00ffff0000ffff
740; CHECK-SD-NEXT:    shl v0.2s, v0.2s, #16
741; CHECK-SD-NEXT:    sshr v0.2s, v0.2s, #16
742; CHECK-SD-NEXT:    and v1.8b, v1.8b, v2.8b
743; CHECK-SD-NEXT:    neg v1.2s, v1.2s
744; CHECK-SD-NEXT:    sshl v0.2s, v0.2s, v1.2s
745; CHECK-SD-NEXT:    ret
746;
747; CHECK-GI-LABEL: ashr_v2i16:
748; CHECK-GI:       // %bb.0:
749; CHECK-GI-NEXT:    uzp1 v1.4h, v1.4h, v0.4h
750; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h
751; CHECK-GI-NEXT:    neg v1.4h, v1.4h
752; CHECK-GI-NEXT:    sshl v0.4h, v0.4h, v1.4h
753; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
754; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
755; CHECK-GI-NEXT:    ret
756    %3 = ashr <2 x i16> %0, %1
757    ret <2 x i16> %3
758}
759
760define <16 x i16> @ashr_v16i16(<16 x i16> %0, <16 x i16> %1){
761; CHECK-LABEL: ashr_v16i16:
762; CHECK:       // %bb.0:
763; CHECK-NEXT:    neg v2.8h, v2.8h
764; CHECK-NEXT:    neg v3.8h, v3.8h
765; CHECK-NEXT:    sshl v0.8h, v0.8h, v2.8h
766; CHECK-NEXT:    sshl v1.8h, v1.8h, v3.8h
767; CHECK-NEXT:    ret
768    %3 = ashr <16 x i16> %0, %1
769    ret <16 x i16> %3
770}
771
772define <1 x i32> @ashr_v1i32(<1 x i32> %0, <1 x i32> %1){
773; CHECK-SD-LABEL: ashr_v1i32:
774; CHECK-SD:       // %bb.0:
775; CHECK-SD-NEXT:    neg v1.2s, v1.2s
776; CHECK-SD-NEXT:    sshl v0.2s, v0.2s, v1.2s
777; CHECK-SD-NEXT:    ret
778;
779; CHECK-GI-LABEL: ashr_v1i32:
780; CHECK-GI:       // %bb.0:
781; CHECK-GI-NEXT:    fmov w8, s0
782; CHECK-GI-NEXT:    fmov w9, s1
783; CHECK-GI-NEXT:    asr w8, w8, w9
784; CHECK-GI-NEXT:    mov v0.s[0], w8
785; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
786; CHECK-GI-NEXT:    ret
787    %3 = ashr <1 x i32> %0, %1
788    ret <1 x i32> %3
789}
790
791define <8 x i32> @ashr_v8i32(<8 x i32> %0, <8 x i32> %1){
792; CHECK-LABEL: ashr_v8i32:
793; CHECK:       // %bb.0:
794; CHECK-NEXT:    neg v2.4s, v2.4s
795; CHECK-NEXT:    neg v3.4s, v3.4s
796; CHECK-NEXT:    sshl v0.4s, v0.4s, v2.4s
797; CHECK-NEXT:    sshl v1.4s, v1.4s, v3.4s
798; CHECK-NEXT:    ret
799    %3 = ashr <8 x i32> %0, %1
800    ret <8 x i32> %3
801}
802
803define <4 x i64> @ashr_v4i64(<4 x i64> %0, <4 x i64> %1){
804; CHECK-LABEL: ashr_v4i64:
805; CHECK:       // %bb.0:
806; CHECK-NEXT:    neg v2.2d, v2.2d
807; CHECK-NEXT:    neg v3.2d, v3.2d
808; CHECK-NEXT:    sshl v0.2d, v0.2d, v2.2d
809; CHECK-NEXT:    sshl v1.2d, v1.2d, v3.2d
810; CHECK-NEXT:    ret
811    %3 = ashr <4 x i64> %0, %1
812    ret <4 x i64> %3
813}
814
815define <2 x i128> @ashr_v2i128(<2 x i128> %0, <2 x i128> %1){
816; CHECK-SD-LABEL: ashr_v2i128:
817; CHECK-SD:       // %bb.0:
818; CHECK-SD-NEXT:    lsl x8, x1, #1
819; CHECK-SD-NEXT:    mvn w9, w4
820; CHECK-SD-NEXT:    lsl x10, x3, #1
821; CHECK-SD-NEXT:    lsr x11, x0, x4
822; CHECK-SD-NEXT:    lsr x12, x2, x6
823; CHECK-SD-NEXT:    asr x13, x1, #63
824; CHECK-SD-NEXT:    lsl x8, x8, x9
825; CHECK-SD-NEXT:    mvn w9, w6
826; CHECK-SD-NEXT:    tst x4, #0x40
827; CHECK-SD-NEXT:    lsl x9, x10, x9
828; CHECK-SD-NEXT:    asr x10, x1, x4
829; CHECK-SD-NEXT:    asr x14, x3, #63
830; CHECK-SD-NEXT:    orr x8, x8, x11
831; CHECK-SD-NEXT:    asr x11, x3, x6
832; CHECK-SD-NEXT:    csel x0, x10, x8, ne
833; CHECK-SD-NEXT:    orr x8, x9, x12
834; CHECK-SD-NEXT:    csel x1, x13, x10, ne
835; CHECK-SD-NEXT:    tst x6, #0x40
836; CHECK-SD-NEXT:    csel x2, x11, x8, ne
837; CHECK-SD-NEXT:    csel x3, x14, x11, ne
838; CHECK-SD-NEXT:    ret
839;
840; CHECK-GI-LABEL: ashr_v2i128:
841; CHECK-GI:       // %bb.0:
842; CHECK-GI-NEXT:    mov w8, #64 // =0x40
843; CHECK-GI-NEXT:    sub x10, x4, #64
844; CHECK-GI-NEXT:    lsr x11, x0, x4
845; CHECK-GI-NEXT:    sub x9, x8, x4
846; CHECK-GI-NEXT:    asr x10, x1, x10
847; CHECK-GI-NEXT:    cmp x4, #64
848; CHECK-GI-NEXT:    lsl x9, x1, x9
849; CHECK-GI-NEXT:    sub x8, x8, x6
850; CHECK-GI-NEXT:    asr x12, x1, x4
851; CHECK-GI-NEXT:    lsl x8, x3, x8
852; CHECK-GI-NEXT:    orr x9, x11, x9
853; CHECK-GI-NEXT:    asr x11, x1, #63
854; CHECK-GI-NEXT:    csel x9, x9, x10, lo
855; CHECK-GI-NEXT:    cmp x4, #0
856; CHECK-GI-NEXT:    lsr x10, x2, x6
857; CHECK-GI-NEXT:    csel x0, x0, x9, eq
858; CHECK-GI-NEXT:    sub x9, x6, #64
859; CHECK-GI-NEXT:    cmp x4, #64
860; CHECK-GI-NEXT:    asr x9, x3, x9
861; CHECK-GI-NEXT:    csel x1, x12, x11, lo
862; CHECK-GI-NEXT:    orr x8, x10, x8
863; CHECK-GI-NEXT:    cmp x6, #64
864; CHECK-GI-NEXT:    asr x11, x3, x6
865; CHECK-GI-NEXT:    asr x10, x3, #63
866; CHECK-GI-NEXT:    csel x8, x8, x9, lo
867; CHECK-GI-NEXT:    cmp x6, #0
868; CHECK-GI-NEXT:    csel x2, x2, x8, eq
869; CHECK-GI-NEXT:    cmp x6, #64
870; CHECK-GI-NEXT:    csel x3, x11, x10, lo
871; CHECK-GI-NEXT:    ret
872    %3 = ashr <2 x i128> %0, %1
873    ret <2 x i128> %3
874}
875
876define <4 x i8> @lshr_v4i8(<4 x i8> %0, <4 x i8> %1){
877; CHECK-SD-LABEL: lshr_v4i8:
878; CHECK-SD:       // %bb.0:
879; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
880; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
881; CHECK-SD-NEXT:    neg v1.4h, v1.4h
882; CHECK-SD-NEXT:    ushl v0.4h, v0.4h, v1.4h
883; CHECK-SD-NEXT:    ret
884;
885; CHECK-GI-LABEL: lshr_v4i8:
886; CHECK-GI:       // %bb.0:
887; CHECK-GI-NEXT:    uzp1 v1.8b, v1.8b, v0.8b
888; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
889; CHECK-GI-NEXT:    neg v1.8b, v1.8b
890; CHECK-GI-NEXT:    ushl v0.8b, v0.8b, v1.8b
891; CHECK-GI-NEXT:    ushll v0.8h, v0.8b, #0
892; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
893; CHECK-GI-NEXT:    ret
894    %3 = lshr <4 x i8> %0, %1
895    ret <4 x i8> %3
896}
897
898define <32 x i8> @lshr_v32i8(<32 x i8> %0, <32 x i8> %1){
899; CHECK-LABEL: lshr_v32i8:
900; CHECK:       // %bb.0:
901; CHECK-NEXT:    neg v2.16b, v2.16b
902; CHECK-NEXT:    neg v3.16b, v3.16b
903; CHECK-NEXT:    ushl v0.16b, v0.16b, v2.16b
904; CHECK-NEXT:    ushl v1.16b, v1.16b, v3.16b
905; CHECK-NEXT:    ret
906    %3 = lshr <32 x i8> %0, %1
907    ret <32 x i8> %3
908}
909
910define <2 x i16> @lshr_v2i16(<2 x i16> %0, <2 x i16> %1){
911; CHECK-SD-LABEL: lshr_v2i16:
912; CHECK-SD:       // %bb.0:
913; CHECK-SD-NEXT:    movi d2, #0x00ffff0000ffff
914; CHECK-SD-NEXT:    and v1.8b, v1.8b, v2.8b
915; CHECK-SD-NEXT:    and v0.8b, v0.8b, v2.8b
916; CHECK-SD-NEXT:    neg v1.2s, v1.2s
917; CHECK-SD-NEXT:    ushl v0.2s, v0.2s, v1.2s
918; CHECK-SD-NEXT:    ret
919;
920; CHECK-GI-LABEL: lshr_v2i16:
921; CHECK-GI:       // %bb.0:
922; CHECK-GI-NEXT:    uzp1 v1.4h, v1.4h, v0.4h
923; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h
924; CHECK-GI-NEXT:    neg v1.4h, v1.4h
925; CHECK-GI-NEXT:    ushl v0.4h, v0.4h, v1.4h
926; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
927; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
928; CHECK-GI-NEXT:    ret
929    %3 = lshr <2 x i16> %0, %1
930    ret <2 x i16> %3
931}
932
933define <16 x i16> @lshr_v16i16(<16 x i16> %0, <16 x i16> %1){
934; CHECK-LABEL: lshr_v16i16:
935; CHECK:       // %bb.0:
936; CHECK-NEXT:    neg v2.8h, v2.8h
937; CHECK-NEXT:    neg v3.8h, v3.8h
938; CHECK-NEXT:    ushl v0.8h, v0.8h, v2.8h
939; CHECK-NEXT:    ushl v1.8h, v1.8h, v3.8h
940; CHECK-NEXT:    ret
941    %3 = lshr <16 x i16> %0, %1
942    ret <16 x i16> %3
943}
944
945define <1 x i32> @lshr_v1i32(<1 x i32> %0, <1 x i32> %1){
946; CHECK-SD-LABEL: lshr_v1i32:
947; CHECK-SD:       // %bb.0:
948; CHECK-SD-NEXT:    neg v1.2s, v1.2s
949; CHECK-SD-NEXT:    ushl v0.2s, v0.2s, v1.2s
950; CHECK-SD-NEXT:    ret
951;
952; CHECK-GI-LABEL: lshr_v1i32:
953; CHECK-GI:       // %bb.0:
954; CHECK-GI-NEXT:    fmov w8, s0
955; CHECK-GI-NEXT:    fmov w9, s1
956; CHECK-GI-NEXT:    lsr w8, w8, w9
957; CHECK-GI-NEXT:    mov v0.s[0], w8
958; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
959; CHECK-GI-NEXT:    ret
960    %3 = lshr <1 x i32> %0, %1
961    ret <1 x i32> %3
962}
963
964define <8 x i32> @lshr_v8i32(<8 x i32> %0, <8 x i32> %1){
965; CHECK-LABEL: lshr_v8i32:
966; CHECK:       // %bb.0:
967; CHECK-NEXT:    neg v2.4s, v2.4s
968; CHECK-NEXT:    neg v3.4s, v3.4s
969; CHECK-NEXT:    ushl v0.4s, v0.4s, v2.4s
970; CHECK-NEXT:    ushl v1.4s, v1.4s, v3.4s
971; CHECK-NEXT:    ret
972    %3 = lshr <8 x i32> %0, %1
973    ret <8 x i32> %3
974}
975
976define <4 x i64> @lshr_v4i64(<4 x i64> %0, <4 x i64> %1){
977; CHECK-LABEL: lshr_v4i64:
978; CHECK:       // %bb.0:
979; CHECK-NEXT:    neg v2.2d, v2.2d
980; CHECK-NEXT:    neg v3.2d, v3.2d
981; CHECK-NEXT:    ushl v0.2d, v0.2d, v2.2d
982; CHECK-NEXT:    ushl v1.2d, v1.2d, v3.2d
983; CHECK-NEXT:    ret
984    %3 = lshr <4 x i64> %0, %1
985    ret <4 x i64> %3
986}
987
988define <2 x i128> @lshr_v2i128(<2 x i128> %0, <2 x i128> %1){
989; CHECK-SD-LABEL: lshr_v2i128:
990; CHECK-SD:       // %bb.0:
991; CHECK-SD-NEXT:    lsl x8, x1, #1
992; CHECK-SD-NEXT:    mvn w9, w4
993; CHECK-SD-NEXT:    lsr x10, x0, x4
994; CHECK-SD-NEXT:    mvn w12, w6
995; CHECK-SD-NEXT:    lsr x11, x1, x4
996; CHECK-SD-NEXT:    lsr x13, x2, x6
997; CHECK-SD-NEXT:    lsl x8, x8, x9
998; CHECK-SD-NEXT:    lsl x9, x3, #1
999; CHECK-SD-NEXT:    tst x4, #0x40
1000; CHECK-SD-NEXT:    csel x1, xzr, x11, ne
1001; CHECK-SD-NEXT:    lsl x9, x9, x12
1002; CHECK-SD-NEXT:    orr x8, x8, x10
1003; CHECK-SD-NEXT:    lsr x10, x3, x6
1004; CHECK-SD-NEXT:    csel x0, x11, x8, ne
1005; CHECK-SD-NEXT:    tst x6, #0x40
1006; CHECK-SD-NEXT:    orr x8, x9, x13
1007; CHECK-SD-NEXT:    csel x3, xzr, x10, ne
1008; CHECK-SD-NEXT:    csel x2, x10, x8, ne
1009; CHECK-SD-NEXT:    ret
1010;
1011; CHECK-GI-LABEL: lshr_v2i128:
1012; CHECK-GI:       // %bb.0:
1013; CHECK-GI-NEXT:    mov w8, #64 // =0x40
1014; CHECK-GI-NEXT:    sub x10, x4, #64
1015; CHECK-GI-NEXT:    lsr x11, x0, x4
1016; CHECK-GI-NEXT:    sub x9, x8, x4
1017; CHECK-GI-NEXT:    lsr x10, x1, x10
1018; CHECK-GI-NEXT:    cmp x4, #64
1019; CHECK-GI-NEXT:    lsl x9, x1, x9
1020; CHECK-GI-NEXT:    sub x8, x8, x6
1021; CHECK-GI-NEXT:    lsr x12, x1, x4
1022; CHECK-GI-NEXT:    lsl x8, x3, x8
1023; CHECK-GI-NEXT:    orr x9, x11, x9
1024; CHECK-GI-NEXT:    lsr x11, x2, x6
1025; CHECK-GI-NEXT:    csel x9, x9, x10, lo
1026; CHECK-GI-NEXT:    cmp x4, #0
1027; CHECK-GI-NEXT:    sub x10, x6, #64
1028; CHECK-GI-NEXT:    csel x0, x0, x9, eq
1029; CHECK-GI-NEXT:    cmp x4, #64
1030; CHECK-GI-NEXT:    lsr x9, x3, x10
1031; CHECK-GI-NEXT:    csel x1, x12, xzr, lo
1032; CHECK-GI-NEXT:    orr x8, x11, x8
1033; CHECK-GI-NEXT:    cmp x6, #64
1034; CHECK-GI-NEXT:    lsr x10, x3, x6
1035; CHECK-GI-NEXT:    csel x8, x8, x9, lo
1036; CHECK-GI-NEXT:    cmp x6, #0
1037; CHECK-GI-NEXT:    csel x2, x2, x8, eq
1038; CHECK-GI-NEXT:    cmp x6, #64
1039; CHECK-GI-NEXT:    csel x3, x10, xzr, lo
1040; CHECK-GI-NEXT:    ret
1041    %3 = lshr <2 x i128> %0, %1
1042    ret <2 x i128> %3
1043}
1044
1045; ===== Vector with Non-Pow 2 Width =====
1046
1047define <3 x i8> @shl_v3i8(<3 x i8> %0, <3 x i8> %1){
1048; CHECK-SD-LABEL: shl_v3i8:
1049; CHECK-SD:       // %bb.0:
1050; CHECK-SD-NEXT:    fmov s0, w3
1051; CHECK-SD-NEXT:    fmov s1, w0
1052; CHECK-SD-NEXT:    mov v0.h[1], w4
1053; CHECK-SD-NEXT:    mov v1.h[1], w1
1054; CHECK-SD-NEXT:    mov v0.h[2], w5
1055; CHECK-SD-NEXT:    mov v1.h[2], w2
1056; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
1057; CHECK-SD-NEXT:    ushl v0.4h, v1.4h, v0.4h
1058; CHECK-SD-NEXT:    umov w0, v0.h[0]
1059; CHECK-SD-NEXT:    umov w1, v0.h[1]
1060; CHECK-SD-NEXT:    umov w2, v0.h[2]
1061; CHECK-SD-NEXT:    ret
1062;
1063; CHECK-GI-LABEL: shl_v3i8:
1064; CHECK-GI:       // %bb.0:
1065; CHECK-GI-NEXT:    fmov s0, w0
1066; CHECK-GI-NEXT:    fmov s1, w3
1067; CHECK-GI-NEXT:    mov v0.b[1], w1
1068; CHECK-GI-NEXT:    mov v1.b[1], w4
1069; CHECK-GI-NEXT:    mov v0.b[2], w2
1070; CHECK-GI-NEXT:    mov v1.b[2], w5
1071; CHECK-GI-NEXT:    ushl v0.8b, v0.8b, v1.8b
1072; CHECK-GI-NEXT:    umov w0, v0.b[0]
1073; CHECK-GI-NEXT:    umov w1, v0.b[1]
1074; CHECK-GI-NEXT:    umov w2, v0.b[2]
1075; CHECK-GI-NEXT:    ret
1076    %3 = shl <3 x i8> %0, %1
1077    ret <3 x i8> %3
1078}
1079
1080define <7 x i8> @shl_v7i8(<7 x i8> %0, <7 x i8> %1){
1081; CHECK-LABEL: shl_v7i8:
1082; CHECK:       // %bb.0:
1083; CHECK-NEXT:    ushl v0.8b, v0.8b, v1.8b
1084; CHECK-NEXT:    ret
1085    %3 = shl <7 x i8> %0, %1
1086    ret <7 x i8> %3
1087}
1088
1089define <3 x i16> @shl_v3i16(<3 x i16> %0, <3 x i16> %1){
1090; CHECK-LABEL: shl_v3i16:
1091; CHECK:       // %bb.0:
1092; CHECK-NEXT:    ushl v0.4h, v0.4h, v1.4h
1093; CHECK-NEXT:    ret
1094    %3 = shl <3 x i16> %0, %1
1095    ret <3 x i16> %3
1096}
1097
1098define <7 x i16> @shl_v7i16(<7 x i16> %0, <7 x i16> %1){
1099; CHECK-LABEL: shl_v7i16:
1100; CHECK:       // %bb.0:
1101; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
1102; CHECK-NEXT:    ret
1103    %3 = shl <7 x i16> %0, %1
1104    ret <7 x i16> %3
1105}
1106
1107define <3 x i32> @shl_v3i32(<3 x i32> %0, <3 x i32> %1){
1108; CHECK-LABEL: shl_v3i32:
1109; CHECK:       // %bb.0:
1110; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
1111; CHECK-NEXT:    ret
1112    %3 = shl <3 x i32> %0, %1
1113    ret <3 x i32> %3
1114}
1115
1116define <3 x i8> @ashr_v3i8(<3 x i8> %0, <3 x i8> %1){
1117; CHECK-SD-LABEL: ashr_v3i8:
1118; CHECK-SD:       // %bb.0:
1119; CHECK-SD-NEXT:    fmov s0, w0
1120; CHECK-SD-NEXT:    fmov s1, w3
1121; CHECK-SD-NEXT:    mov v0.h[1], w1
1122; CHECK-SD-NEXT:    mov v1.h[1], w4
1123; CHECK-SD-NEXT:    mov v0.h[2], w2
1124; CHECK-SD-NEXT:    mov v1.h[2], w5
1125; CHECK-SD-NEXT:    shl v0.4h, v0.4h, #8
1126; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
1127; CHECK-SD-NEXT:    sshr v0.4h, v0.4h, #8
1128; CHECK-SD-NEXT:    neg v1.4h, v1.4h
1129; CHECK-SD-NEXT:    sshl v0.4h, v0.4h, v1.4h
1130; CHECK-SD-NEXT:    umov w0, v0.h[0]
1131; CHECK-SD-NEXT:    umov w1, v0.h[1]
1132; CHECK-SD-NEXT:    umov w2, v0.h[2]
1133; CHECK-SD-NEXT:    ret
1134;
1135; CHECK-GI-LABEL: ashr_v3i8:
1136; CHECK-GI:       // %bb.0:
1137; CHECK-GI-NEXT:    fmov s0, w3
1138; CHECK-GI-NEXT:    fmov s1, w0
1139; CHECK-GI-NEXT:    mov v0.b[1], w4
1140; CHECK-GI-NEXT:    mov v1.b[1], w1
1141; CHECK-GI-NEXT:    mov v0.b[2], w5
1142; CHECK-GI-NEXT:    mov v1.b[2], w2
1143; CHECK-GI-NEXT:    neg v0.8b, v0.8b
1144; CHECK-GI-NEXT:    sshl v0.8b, v1.8b, v0.8b
1145; CHECK-GI-NEXT:    umov w0, v0.b[0]
1146; CHECK-GI-NEXT:    umov w1, v0.b[1]
1147; CHECK-GI-NEXT:    umov w2, v0.b[2]
1148; CHECK-GI-NEXT:    ret
1149    %3 = ashr <3 x i8> %0, %1
1150    ret <3 x i8> %3
1151}
1152
1153define <7 x i8> @ashr_v7i8(<7 x i8> %0, <7 x i8> %1){
1154; CHECK-LABEL: ashr_v7i8:
1155; CHECK:       // %bb.0:
1156; CHECK-NEXT:    neg v1.8b, v1.8b
1157; CHECK-NEXT:    sshl v0.8b, v0.8b, v1.8b
1158; CHECK-NEXT:    ret
1159    %3 = ashr <7 x i8> %0, %1
1160    ret <7 x i8> %3
1161}
1162
1163define <3 x i16> @ashr_v3i16(<3 x i16> %0, <3 x i16> %1){
1164; CHECK-LABEL: ashr_v3i16:
1165; CHECK:       // %bb.0:
1166; CHECK-NEXT:    neg v1.4h, v1.4h
1167; CHECK-NEXT:    sshl v0.4h, v0.4h, v1.4h
1168; CHECK-NEXT:    ret
1169    %3 = ashr <3 x i16> %0, %1
1170    ret <3 x i16> %3
1171}
1172
1173define <7 x i16> @ashr_v7i16(<7 x i16> %0, <7 x i16> %1){
1174; CHECK-LABEL: ashr_v7i16:
1175; CHECK:       // %bb.0:
1176; CHECK-NEXT:    neg v1.8h, v1.8h
1177; CHECK-NEXT:    sshl v0.8h, v0.8h, v1.8h
1178; CHECK-NEXT:    ret
1179    %3 = ashr <7 x i16> %0, %1
1180    ret <7 x i16> %3
1181}
1182
1183define <3 x i32> @ashr_v3i32(<3 x i32> %0, <3 x i32> %1){
1184; CHECK-LABEL: ashr_v3i32:
1185; CHECK:       // %bb.0:
1186; CHECK-NEXT:    neg v1.4s, v1.4s
1187; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
1188; CHECK-NEXT:    ret
1189    %3 = ashr <3 x i32> %0, %1
1190    ret <3 x i32> %3
1191}
1192
1193define <3 x i8> @lshr_v3i8(<3 x i8> %0, <3 x i8> %1){
1194; CHECK-SD-LABEL: lshr_v3i8:
1195; CHECK-SD:       // %bb.0:
1196; CHECK-SD-NEXT:    fmov s0, w3
1197; CHECK-SD-NEXT:    fmov s1, w0
1198; CHECK-SD-NEXT:    mov v0.h[1], w4
1199; CHECK-SD-NEXT:    mov v1.h[1], w1
1200; CHECK-SD-NEXT:    mov v0.h[2], w5
1201; CHECK-SD-NEXT:    mov v1.h[2], w2
1202; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
1203; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
1204; CHECK-SD-NEXT:    neg v0.4h, v0.4h
1205; CHECK-SD-NEXT:    ushl v0.4h, v1.4h, v0.4h
1206; CHECK-SD-NEXT:    umov w0, v0.h[0]
1207; CHECK-SD-NEXT:    umov w1, v0.h[1]
1208; CHECK-SD-NEXT:    umov w2, v0.h[2]
1209; CHECK-SD-NEXT:    ret
1210;
1211; CHECK-GI-LABEL: lshr_v3i8:
1212; CHECK-GI:       // %bb.0:
1213; CHECK-GI-NEXT:    fmov s0, w3
1214; CHECK-GI-NEXT:    fmov s1, w0
1215; CHECK-GI-NEXT:    mov v0.b[1], w4
1216; CHECK-GI-NEXT:    mov v1.b[1], w1
1217; CHECK-GI-NEXT:    mov v0.b[2], w5
1218; CHECK-GI-NEXT:    mov v1.b[2], w2
1219; CHECK-GI-NEXT:    neg v0.8b, v0.8b
1220; CHECK-GI-NEXT:    ushl v0.8b, v1.8b, v0.8b
1221; CHECK-GI-NEXT:    umov w0, v0.b[0]
1222; CHECK-GI-NEXT:    umov w1, v0.b[1]
1223; CHECK-GI-NEXT:    umov w2, v0.b[2]
1224; CHECK-GI-NEXT:    ret
1225    %3 = lshr <3 x i8> %0, %1
1226    ret <3 x i8> %3
1227}
1228
1229define <7 x i8> @lshr_v7i8(<7 x i8> %0, <7 x i8> %1){
1230; CHECK-LABEL: lshr_v7i8:
1231; CHECK:       // %bb.0:
1232; CHECK-NEXT:    neg v1.8b, v1.8b
1233; CHECK-NEXT:    ushl v0.8b, v0.8b, v1.8b
1234; CHECK-NEXT:    ret
1235    %3 = lshr <7 x i8> %0, %1
1236    ret <7 x i8> %3
1237}
1238
1239define <3 x i16> @lshr_v3i16(<3 x i16> %0, <3 x i16> %1){
1240; CHECK-LABEL: lshr_v3i16:
1241; CHECK:       // %bb.0:
1242; CHECK-NEXT:    neg v1.4h, v1.4h
1243; CHECK-NEXT:    ushl v0.4h, v0.4h, v1.4h
1244; CHECK-NEXT:    ret
1245    %3 = lshr <3 x i16> %0, %1
1246    ret <3 x i16> %3
1247}
1248
1249define <7 x i16> @lshr_v7i16(<7 x i16> %0, <7 x i16> %1){
1250; CHECK-LABEL: lshr_v7i16:
1251; CHECK:       // %bb.0:
1252; CHECK-NEXT:    neg v1.8h, v1.8h
1253; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
1254; CHECK-NEXT:    ret
1255    %3 = lshr <7 x i16> %0, %1
1256    ret <7 x i16> %3
1257}
1258
1259define <3 x i32> @lshr_v3i32(<3 x i32> %0, <3 x i32> %1){
1260; CHECK-LABEL: lshr_v3i32:
1261; CHECK:       // %bb.0:
1262; CHECK-NEXT:    neg v1.4s, v1.4s
1263; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
1264; CHECK-NEXT:    ret
1265    %3 = lshr <3 x i32> %0, %1
1266    ret <3 x i32> %3
1267}
1268
1269; TODO:
1270; ===== Vector with Odd Element Sizes =====
1271