xref: /llvm-project/llvm/test/CodeGen/AArch64/xtn.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2; RUN: llc -mtriple=aarch64 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=2 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5define i8 @xtn_i16_to_i8(i16 %a) {
6; CHECK-LABEL: xtn_i16_to_i8:
7; CHECK:       // %bb.0: // %entry
8; CHECK-NEXT:    ret
9entry:
10  %arg1 = trunc i16 %a to i8
11  ret i8 %arg1
12}
13
14define i8 @xtn_i32_to_i8(i32 %a) {
15; CHECK-LABEL: xtn_i32_to_i8:
16; CHECK:       // %bb.0: // %entry
17; CHECK-NEXT:    ret
18entry:
19  %arg1 = trunc i32 %a to i8
20  ret i8 %arg1
21}
22
23define i8 @xtn_i64_to_i8(i64 %a) {
24; CHECK-LABEL: xtn_i64_to_i8:
25; CHECK:       // %bb.0: // %entry
26; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
27; CHECK-NEXT:    ret
28entry:
29  %arg1 = trunc i64 %a to i8
30  ret i8 %arg1
31}
32
33define i8 @xtn_i128_to_i8(i128 %a) {
34; CHECK-LABEL: xtn_i128_to_i8:
35; CHECK:       // %bb.0: // %entry
36; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
37; CHECK-NEXT:    ret
38entry:
39  %arg1 = trunc i128 %a to i8
40  ret i8 %arg1
41}
42
43define i16 @xtn_i32_to_i16(i32 %a) {
44; CHECK-LABEL: xtn_i32_to_i16:
45; CHECK:       // %bb.0: // %entry
46; CHECK-NEXT:    ret
47entry:
48  %arg1 = trunc i32 %a to i16
49  ret i16 %arg1
50}
51
52define i16 @xtn_i64_to_i16(i64 %a) {
53; CHECK-LABEL: xtn_i64_to_i16:
54; CHECK:       // %bb.0: // %entry
55; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
56; CHECK-NEXT:    ret
57entry:
58  %arg1 = trunc i64 %a to i16
59  ret i16 %arg1
60}
61
62define i16 @xtn_i128_to_i16(i128 %a) {
63; CHECK-LABEL: xtn_i128_to_i16:
64; CHECK:       // %bb.0: // %entry
65; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
66; CHECK-NEXT:    ret
67entry:
68  %arg1 = trunc i128 %a to i16
69  ret i16 %arg1
70}
71
72define i32 @xtn_i64_to_i32(i64 %a) {
73; CHECK-LABEL: xtn_i64_to_i32:
74; CHECK:       // %bb.0: // %entry
75; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
76; CHECK-NEXT:    ret
77entry:
78  %arg1 = trunc i64 %a to i32
79  ret i32 %arg1
80}
81
82define i32 @xtn_i128_to_i32(i128 %a) {
83; CHECK-LABEL: xtn_i128_to_i32:
84; CHECK:       // %bb.0: // %entry
85; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
86; CHECK-NEXT:    ret
87entry:
88  %arg1 = trunc i128 %a to i32
89  ret i32 %arg1
90}
91
92define i64 @xtn_i128_to_i64(i128 %a) {
93; CHECK-LABEL: xtn_i128_to_i64:
94; CHECK:       // %bb.0: // %entry
95; CHECK-NEXT:    ret
96entry:
97  %arg1 = trunc i128 %a to i64
98  ret i64 %arg1
99}
100
101define <2 x i8> @xtn_v2i16_v2i8(<2 x i16> %a) {
102; CHECK-LABEL: xtn_v2i16_v2i8:
103; CHECK:       // %bb.0: // %entry
104; CHECK-NEXT:    ret
105entry:
106  %arg1 = trunc <2 x i16> %a to <2 x i8>
107  ret <2 x i8> %arg1
108}
109
110define <2 x i8> @xtn_v2i32_v2i8(<2 x i32> %a) {
111; CHECK-LABEL: xtn_v2i32_v2i8:
112; CHECK:       // %bb.0: // %entry
113; CHECK-NEXT:    ret
114entry:
115  %arg1 = trunc <2 x i32> %a to <2 x i8>
116  ret <2 x i8> %arg1
117}
118
119define <2 x i8> @xtn_v2i64_v2i8(<2 x i64> %a) {
120; CHECK-LABEL: xtn_v2i64_v2i8:
121; CHECK:       // %bb.0: // %entry
122; CHECK-NEXT:    xtn v0.2s, v0.2d
123; CHECK-NEXT:    ret
124entry:
125  %arg1 = trunc <2 x i64> %a to <2 x i8>
126  ret <2 x i8> %arg1
127}
128
129define <2 x i8> @xtn_v2i128_v2i8(<2 x i128> %a) {
130; CHECK-SD-LABEL: xtn_v2i128_v2i8:
131; CHECK-SD:       // %bb.0: // %entry
132; CHECK-SD-NEXT:    fmov s0, w0
133; CHECK-SD-NEXT:    mov v0.s[1], w2
134; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
135; CHECK-SD-NEXT:    ret
136;
137; CHECK-GI-LABEL: xtn_v2i128_v2i8:
138; CHECK-GI:       // %bb.0: // %entry
139; CHECK-GI-NEXT:    mov v0.s[0], w0
140; CHECK-GI-NEXT:    mov v0.s[1], w2
141; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
142; CHECK-GI-NEXT:    ret
143entry:
144  %arg1 = trunc <2 x i128> %a to <2 x i8>
145  ret <2 x i8> %arg1
146}
147
148define <2 x i16> @xtn_v2i32_v2i16(<2 x i32> %a) {
149; CHECK-LABEL: xtn_v2i32_v2i16:
150; CHECK:       // %bb.0: // %entry
151; CHECK-NEXT:    ret
152entry:
153  %arg1 = trunc <2 x i32> %a to <2 x i16>
154  ret <2 x i16> %arg1
155}
156
157define <2 x i16> @xtn_v2i64_v2i16(<2 x i64> %a) {
158; CHECK-LABEL: xtn_v2i64_v2i16:
159; CHECK:       // %bb.0: // %entry
160; CHECK-NEXT:    xtn v0.2s, v0.2d
161; CHECK-NEXT:    ret
162entry:
163  %arg1 = trunc <2 x i64> %a to <2 x i16>
164  ret <2 x i16> %arg1
165}
166
167define <2 x i16> @xtn_v2i128_v2i16(<2 x i128> %a) {
168; CHECK-SD-LABEL: xtn_v2i128_v2i16:
169; CHECK-SD:       // %bb.0: // %entry
170; CHECK-SD-NEXT:    fmov s0, w0
171; CHECK-SD-NEXT:    mov v0.s[1], w2
172; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
173; CHECK-SD-NEXT:    ret
174;
175; CHECK-GI-LABEL: xtn_v2i128_v2i16:
176; CHECK-GI:       // %bb.0: // %entry
177; CHECK-GI-NEXT:    mov v0.s[0], w0
178; CHECK-GI-NEXT:    mov v0.s[1], w2
179; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
180; CHECK-GI-NEXT:    ret
181entry:
182  %arg1 = trunc <2 x i128> %a to <2 x i16>
183  ret <2 x i16> %arg1
184}
185
186define <2 x i32> @xtn_v2i64_v2i32(<2 x i64> %a) {
187; CHECK-LABEL: xtn_v2i64_v2i32:
188; CHECK:       // %bb.0: // %entry
189; CHECK-NEXT:    xtn v0.2s, v0.2d
190; CHECK-NEXT:    ret
191entry:
192  %arg1 = trunc <2 x i64> %a to <2 x i32>
193  ret <2 x i32> %arg1
194}
195
196define <2 x i32> @xtn_v2i128_v2i32(<2 x i128> %a) {
197; CHECK-SD-LABEL: xtn_v2i128_v2i32:
198; CHECK-SD:       // %bb.0: // %entry
199; CHECK-SD-NEXT:    fmov s0, w0
200; CHECK-SD-NEXT:    mov v0.s[1], w2
201; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
202; CHECK-SD-NEXT:    ret
203;
204; CHECK-GI-LABEL: xtn_v2i128_v2i32:
205; CHECK-GI:       // %bb.0: // %entry
206; CHECK-GI-NEXT:    mov v0.s[0], w0
207; CHECK-GI-NEXT:    mov v0.s[1], w2
208; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
209; CHECK-GI-NEXT:    ret
210entry:
211  %arg1 = trunc <2 x i128> %a to <2 x i32>
212  ret <2 x i32> %arg1
213}
214
215define <2 x i64> @xtn_v2i128_v2i64(<2 x i128> %a) {
216; CHECK-SD-LABEL: xtn_v2i128_v2i64:
217; CHECK-SD:       // %bb.0: // %entry
218; CHECK-SD-NEXT:    fmov d0, x0
219; CHECK-SD-NEXT:    mov v0.d[1], x2
220; CHECK-SD-NEXT:    ret
221;
222; CHECK-GI-LABEL: xtn_v2i128_v2i64:
223; CHECK-GI:       // %bb.0: // %entry
224; CHECK-GI-NEXT:    mov v0.d[0], x0
225; CHECK-GI-NEXT:    mov v0.d[1], x2
226; CHECK-GI-NEXT:    ret
227entry:
228  %arg1 = trunc <2 x i128> %a to <2 x i64>
229  ret <2 x i64> %arg1
230}
231
232define <3 x i8> @xtn_v3i16_v3i8(<3 x i16> %a) {
233; CHECK-LABEL: xtn_v3i16_v3i8:
234; CHECK:       // %bb.0: // %entry
235; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
236; CHECK-NEXT:    umov w0, v0.h[0]
237; CHECK-NEXT:    umov w1, v0.h[1]
238; CHECK-NEXT:    umov w2, v0.h[2]
239; CHECK-NEXT:    ret
240entry:
241  %arg1 = trunc <3 x i16> %a to <3 x i8>
242  ret <3 x i8> %arg1
243}
244
245define <3 x i8> @xtn_v3i32_v3i8(<3 x i32> %a) {
246; CHECK-SD-LABEL: xtn_v3i32_v3i8:
247; CHECK-SD:       // %bb.0: // %entry
248; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
249; CHECK-SD-NEXT:    umov w0, v0.h[0]
250; CHECK-SD-NEXT:    umov w1, v0.h[1]
251; CHECK-SD-NEXT:    umov w2, v0.h[2]
252; CHECK-SD-NEXT:    ret
253;
254; CHECK-GI-LABEL: xtn_v3i32_v3i8:
255; CHECK-GI:       // %bb.0: // %entry
256; CHECK-GI-NEXT:    mov s1, v0.s[1]
257; CHECK-GI-NEXT:    mov s2, v0.s[2]
258; CHECK-GI-NEXT:    fmov w0, s0
259; CHECK-GI-NEXT:    fmov w1, s1
260; CHECK-GI-NEXT:    fmov w2, s2
261; CHECK-GI-NEXT:    ret
262entry:
263  %arg1 = trunc <3 x i32> %a to <3 x i8>
264  ret <3 x i8> %arg1
265}
266
267define <3 x i8> @xtn_v3i64_v3i8(<3 x i64> %a) {
268; CHECK-SD-LABEL: xtn_v3i64_v3i8:
269; CHECK-SD:       // %bb.0: // %entry
270; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
271; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
272; CHECK-SD-NEXT:    // kill: def $d2 killed $d2 def $q2
273; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
274; CHECK-SD-NEXT:    xtn v1.2s, v2.2d
275; CHECK-SD-NEXT:    xtn v0.2s, v0.2d
276; CHECK-SD-NEXT:    fmov w2, s1
277; CHECK-SD-NEXT:    mov w1, v0.s[1]
278; CHECK-SD-NEXT:    fmov w0, s0
279; CHECK-SD-NEXT:    ret
280;
281; CHECK-GI-LABEL: xtn_v3i64_v3i8:
282; CHECK-GI:       // %bb.0: // %entry
283; CHECK-GI-NEXT:    fmov x0, d0
284; CHECK-GI-NEXT:    fmov x1, d1
285; CHECK-GI-NEXT:    fmov x2, d2
286; CHECK-GI-NEXT:    // kill: def $w0 killed $w0 killed $x0
287; CHECK-GI-NEXT:    // kill: def $w1 killed $w1 killed $x1
288; CHECK-GI-NEXT:    // kill: def $w2 killed $w2 killed $x2
289; CHECK-GI-NEXT:    ret
290entry:
291  %arg1 = trunc <3 x i64> %a to <3 x i8>
292  ret <3 x i8> %arg1
293}
294
295define <3 x i16> @xtn_v3i32_v3i16(<3 x i32> %a) {
296; CHECK-LABEL: xtn_v3i32_v3i16:
297; CHECK:       // %bb.0: // %entry
298; CHECK-NEXT:    xtn v0.4h, v0.4s
299; CHECK-NEXT:    ret
300entry:
301  %arg1 = trunc <3 x i32> %a to <3 x i16>
302  ret <3 x i16> %arg1
303}
304
305define <3 x i16> @xtn_v3i64_v3i16(<3 x i64> %a) {
306; CHECK-SD-LABEL: xtn_v3i64_v3i16:
307; CHECK-SD:       // %bb.0: // %entry
308; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
309; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
310; CHECK-SD-NEXT:    // kill: def $d2 killed $d2 def $q2
311; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
312; CHECK-SD-NEXT:    uzp1 v0.4s, v0.4s, v2.4s
313; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
314; CHECK-SD-NEXT:    ret
315;
316; CHECK-GI-LABEL: xtn_v3i64_v3i16:
317; CHECK-GI:       // %bb.0: // %entry
318; CHECK-GI-NEXT:    fmov x8, d0
319; CHECK-GI-NEXT:    fmov x9, d1
320; CHECK-GI-NEXT:    fmov s0, w8
321; CHECK-GI-NEXT:    fmov x8, d2
322; CHECK-GI-NEXT:    mov v0.h[1], w9
323; CHECK-GI-NEXT:    mov v0.h[2], w8
324; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
325; CHECK-GI-NEXT:    ret
326entry:
327  %arg1 = trunc <3 x i64> %a to <3 x i16>
328  ret <3 x i16> %arg1
329}
330
331define <3 x i32> @xtn_v3i64_v3i32(<3 x i64> %a) {
332; CHECK-SD-LABEL: xtn_v3i64_v3i32:
333; CHECK-SD:       // %bb.0: // %entry
334; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
335; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
336; CHECK-SD-NEXT:    // kill: def $d2 killed $d2 def $q2
337; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
338; CHECK-SD-NEXT:    uzp1 v0.4s, v0.4s, v2.4s
339; CHECK-SD-NEXT:    ret
340;
341; CHECK-GI-LABEL: xtn_v3i64_v3i32:
342; CHECK-GI:       // %bb.0: // %entry
343; CHECK-GI-NEXT:    fmov x8, d0
344; CHECK-GI-NEXT:    mov v0.s[0], w8
345; CHECK-GI-NEXT:    fmov x8, d1
346; CHECK-GI-NEXT:    mov v0.s[1], w8
347; CHECK-GI-NEXT:    fmov x8, d2
348; CHECK-GI-NEXT:    mov v0.s[2], w8
349; CHECK-GI-NEXT:    ret
350entry:
351  %arg1 = trunc <3 x i64> %a to <3 x i32>
352  ret <3 x i32> %arg1
353}
354
355define <4 x i8> @xtn_v4i16_v4i8(<4 x i16> %a) {
356; CHECK-LABEL: xtn_v4i16_v4i8:
357; CHECK:       // %bb.0: // %entry
358; CHECK-NEXT:    ret
359entry:
360  %arg1 = trunc <4 x i16> %a to <4 x i8>
361  ret <4 x i8> %arg1
362}
363
364define <4 x i8> @xtn_v4i32_v4i8(<4 x i32> %a) {
365; CHECK-LABEL: xtn_v4i32_v4i8:
366; CHECK:       // %bb.0: // %entry
367; CHECK-NEXT:    xtn v0.4h, v0.4s
368; CHECK-NEXT:    ret
369entry:
370  %arg1 = trunc <4 x i32> %a to <4 x i8>
371  ret <4 x i8> %arg1
372}
373
374define <4 x i8> @xtn_v4i64_v4i8(<4 x i64> %a) {
375; CHECK-LABEL: xtn_v4i64_v4i8:
376; CHECK:       // %bb.0: // %entry
377; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
378; CHECK-NEXT:    xtn v0.4h, v0.4s
379; CHECK-NEXT:    ret
380entry:
381  %arg1 = trunc <4 x i64> %a to <4 x i8>
382  ret <4 x i8> %arg1
383}
384
385define <4 x i16> @xtn_v4i32_v4i16(<4 x i32> %a) {
386; CHECK-LABEL: xtn_v4i32_v4i16:
387; CHECK:       // %bb.0: // %entry
388; CHECK-NEXT:    xtn v0.4h, v0.4s
389; CHECK-NEXT:    ret
390entry:
391  %arg1 = trunc <4 x i32> %a to <4 x i16>
392  ret <4 x i16> %arg1
393}
394
395define <4 x i16> @xtn_v4i64_v4i16(<4 x i64> %a) {
396; CHECK-LABEL: xtn_v4i64_v4i16:
397; CHECK:       // %bb.0: // %entry
398; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
399; CHECK-NEXT:    xtn v0.4h, v0.4s
400; CHECK-NEXT:    ret
401entry:
402  %arg1 = trunc <4 x i64> %a to <4 x i16>
403  ret <4 x i16> %arg1
404}
405
406define <4 x i32> @xtn_v4i64_v4i32(<4 x i64> %a) {
407; CHECK-LABEL: xtn_v4i64_v4i32:
408; CHECK:       // %bb.0: // %entry
409; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
410; CHECK-NEXT:    ret
411entry:
412  %arg1 = trunc <4 x i64> %a to <4 x i32>
413  ret <4 x i32> %arg1
414}
415
416define <8 x i8> @xtn_v8i16_v8i8(<8 x i16> %a) {
417; CHECK-LABEL: xtn_v8i16_v8i8:
418; CHECK:       // %bb.0: // %entry
419; CHECK-NEXT:    xtn v0.8b, v0.8h
420; CHECK-NEXT:    ret
421entry:
422  %arg1 = trunc <8 x i16> %a to <8 x i8>
423  ret <8 x i8> %arg1
424}
425
426define <8 x i8> @xtn_v8i32_v8i8(<8 x i32> %a) {
427; CHECK-LABEL: xtn_v8i32_v8i8:
428; CHECK:       // %bb.0: // %entry
429; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
430; CHECK-NEXT:    xtn v0.8b, v0.8h
431; CHECK-NEXT:    ret
432entry:
433  %arg1 = trunc <8 x i32> %a to <8 x i8>
434  ret <8 x i8> %arg1
435}
436
437define <8 x i16> @xtn_v8i32_v8i16(<8 x i32> %a) {
438; CHECK-LABEL: xtn_v8i32_v8i16:
439; CHECK:       // %bb.0: // %entry
440; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
441; CHECK-NEXT:    ret
442entry:
443  %arg1 = trunc <8 x i32> %a to <8 x i16>
444  ret <8 x i16> %arg1
445}
446
447define <16 x i8> @xtn_v16i16_v16i8(<16 x i16> %a) {
448; CHECK-LABEL: xtn_v16i16_v16i8:
449; CHECK:       // %bb.0: // %entry
450; CHECK-NEXT:    uzp1 v0.16b, v0.16b, v1.16b
451; CHECK-NEXT:    ret
452entry:
453  %arg1 = trunc <16 x i16> %a to <16 x i8>
454  ret <16 x i8> %arg1
455}
456