xref: /llvm-project/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-splat-vector.ll (revision 3146911eb0eee821535444aa207a4ec5020c9c6a)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mattr=+sve -force-streaming-compatible < %s | FileCheck %s
3; RUN: llc -force-streaming-compatible < %s | FileCheck %s --check-prefix=NONEON-NOSVE
4; RUN: llc -force-streaming-compatible -use-constant-int-for-fixed-length-splat -use-constant-fp-for-fixed-length-splat < %s | FileCheck %s --check-prefix=NONEON-NOSVE
5
6target triple = "aarch64-unknown-linux-gnu"
7
8;
9; DUP (integer)
10;
11
12define <4 x i8> @splat_v4i8(i8 %a) {
13; CHECK-LABEL: splat_v4i8:
14; CHECK:       // %bb.0:
15; CHECK-NEXT:    mov z0.h, w0
16; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
17; CHECK-NEXT:    ret
18;
19; NONEON-NOSVE-LABEL: splat_v4i8:
20; NONEON-NOSVE:       // %bb.0:
21; NONEON-NOSVE-NEXT:    sub sp, sp, #16
22; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
23; NONEON-NOSVE-NEXT:    strh w0, [sp, #14]
24; NONEON-NOSVE-NEXT:    strh w0, [sp, #12]
25; NONEON-NOSVE-NEXT:    strh w0, [sp, #10]
26; NONEON-NOSVE-NEXT:    strh w0, [sp, #8]
27; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
28; NONEON-NOSVE-NEXT:    add sp, sp, #16
29; NONEON-NOSVE-NEXT:    ret
30  %insert = insertelement <4 x i8> undef, i8 %a, i64 0
31  %splat = shufflevector <4 x i8> %insert, <4 x i8> undef, <4 x i32> zeroinitializer
32  ret <4 x i8> %splat
33}
34
35define <8 x i8> @splat_v8i8(i8 %a) {
36; CHECK-LABEL: splat_v8i8:
37; CHECK:       // %bb.0:
38; CHECK-NEXT:    mov z0.b, w0
39; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
40; CHECK-NEXT:    ret
41;
42; NONEON-NOSVE-LABEL: splat_v8i8:
43; NONEON-NOSVE:       // %bb.0:
44; NONEON-NOSVE-NEXT:    sub sp, sp, #16
45; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
46; NONEON-NOSVE-NEXT:    strb w0, [sp, #15]
47; NONEON-NOSVE-NEXT:    strb w0, [sp, #14]
48; NONEON-NOSVE-NEXT:    strb w0, [sp, #13]
49; NONEON-NOSVE-NEXT:    strb w0, [sp, #12]
50; NONEON-NOSVE-NEXT:    strb w0, [sp, #11]
51; NONEON-NOSVE-NEXT:    strb w0, [sp, #10]
52; NONEON-NOSVE-NEXT:    strb w0, [sp, #9]
53; NONEON-NOSVE-NEXT:    strb w0, [sp, #8]
54; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
55; NONEON-NOSVE-NEXT:    add sp, sp, #16
56; NONEON-NOSVE-NEXT:    ret
57  %insert = insertelement <8 x i8> undef, i8 %a, i64 0
58  %splat = shufflevector <8 x i8> %insert, <8 x i8> undef, <8 x i32> zeroinitializer
59  ret <8 x i8> %splat
60}
61
62define <16 x i8> @splat_v16i8(i8 %a) {
63; CHECK-LABEL: splat_v16i8:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    mov z0.b, w0
66; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
67; CHECK-NEXT:    ret
68;
69; NONEON-NOSVE-LABEL: splat_v16i8:
70; NONEON-NOSVE:       // %bb.0:
71; NONEON-NOSVE-NEXT:    sub sp, sp, #16
72; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
73; NONEON-NOSVE-NEXT:    strb w0, [sp, #15]
74; NONEON-NOSVE-NEXT:    strb w0, [sp, #14]
75; NONEON-NOSVE-NEXT:    strb w0, [sp, #13]
76; NONEON-NOSVE-NEXT:    strb w0, [sp, #12]
77; NONEON-NOSVE-NEXT:    strb w0, [sp, #11]
78; NONEON-NOSVE-NEXT:    strb w0, [sp, #10]
79; NONEON-NOSVE-NEXT:    strb w0, [sp, #9]
80; NONEON-NOSVE-NEXT:    strb w0, [sp, #8]
81; NONEON-NOSVE-NEXT:    strb w0, [sp, #7]
82; NONEON-NOSVE-NEXT:    strb w0, [sp, #6]
83; NONEON-NOSVE-NEXT:    strb w0, [sp, #5]
84; NONEON-NOSVE-NEXT:    strb w0, [sp, #4]
85; NONEON-NOSVE-NEXT:    strb w0, [sp, #3]
86; NONEON-NOSVE-NEXT:    strb w0, [sp, #2]
87; NONEON-NOSVE-NEXT:    strb w0, [sp, #1]
88; NONEON-NOSVE-NEXT:    strb w0, [sp]
89; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
90; NONEON-NOSVE-NEXT:    ret
91  %insert = insertelement <16 x i8> undef, i8 %a, i64 0
92  %splat = shufflevector <16 x i8> %insert, <16 x i8> undef, <16 x i32> zeroinitializer
93  ret <16 x i8> %splat
94}
95
96define void @splat_v32i8(i8 %a, ptr %b) {
97; CHECK-LABEL: splat_v32i8:
98; CHECK:       // %bb.0:
99; CHECK-NEXT:    mov z0.b, w0
100; CHECK-NEXT:    stp q0, q0, [x1]
101; CHECK-NEXT:    ret
102;
103; NONEON-NOSVE-LABEL: splat_v32i8:
104; NONEON-NOSVE:       // %bb.0:
105; NONEON-NOSVE-NEXT:    sub sp, sp, #16
106; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
107; NONEON-NOSVE-NEXT:    strb w0, [sp, #15]
108; NONEON-NOSVE-NEXT:    strb w0, [sp, #14]
109; NONEON-NOSVE-NEXT:    strb w0, [sp, #13]
110; NONEON-NOSVE-NEXT:    strb w0, [sp, #12]
111; NONEON-NOSVE-NEXT:    strb w0, [sp, #11]
112; NONEON-NOSVE-NEXT:    strb w0, [sp, #10]
113; NONEON-NOSVE-NEXT:    strb w0, [sp, #9]
114; NONEON-NOSVE-NEXT:    strb w0, [sp, #8]
115; NONEON-NOSVE-NEXT:    strb w0, [sp, #7]
116; NONEON-NOSVE-NEXT:    strb w0, [sp, #6]
117; NONEON-NOSVE-NEXT:    strb w0, [sp, #5]
118; NONEON-NOSVE-NEXT:    strb w0, [sp, #4]
119; NONEON-NOSVE-NEXT:    strb w0, [sp, #3]
120; NONEON-NOSVE-NEXT:    strb w0, [sp, #2]
121; NONEON-NOSVE-NEXT:    strb w0, [sp, #1]
122; NONEON-NOSVE-NEXT:    strb w0, [sp]
123; NONEON-NOSVE-NEXT:    ldr q0, [sp]
124; NONEON-NOSVE-NEXT:    stp q0, q0, [x1]
125; NONEON-NOSVE-NEXT:    add sp, sp, #16
126; NONEON-NOSVE-NEXT:    ret
127  %insert = insertelement <32 x i8> undef, i8 %a, i64 0
128  %splat = shufflevector <32 x i8> %insert, <32 x i8> undef, <32 x i32> zeroinitializer
129  store <32 x i8> %splat, ptr %b
130  ret void
131}
132
133define <2 x i16> @splat_v2i16(i16 %a) {
134; CHECK-LABEL: splat_v2i16:
135; CHECK:       // %bb.0:
136; CHECK-NEXT:    mov z0.s, w0
137; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
138; CHECK-NEXT:    ret
139;
140; NONEON-NOSVE-LABEL: splat_v2i16:
141; NONEON-NOSVE:       // %bb.0:
142; NONEON-NOSVE-NEXT:    sub sp, sp, #16
143; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
144; NONEON-NOSVE-NEXT:    stp w0, w0, [sp, #8]
145; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
146; NONEON-NOSVE-NEXT:    add sp, sp, #16
147; NONEON-NOSVE-NEXT:    ret
148  %insert = insertelement <2 x i16> undef, i16 %a, i64 0
149  %splat = shufflevector <2 x i16> %insert, <2 x i16> undef, <2 x i32> zeroinitializer
150  ret <2 x i16> %splat
151}
152
153define <4 x i16> @splat_v4i16(i16 %a) {
154; CHECK-LABEL: splat_v4i16:
155; CHECK:       // %bb.0:
156; CHECK-NEXT:    mov z0.h, w0
157; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
158; CHECK-NEXT:    ret
159;
160; NONEON-NOSVE-LABEL: splat_v4i16:
161; NONEON-NOSVE:       // %bb.0:
162; NONEON-NOSVE-NEXT:    sub sp, sp, #16
163; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
164; NONEON-NOSVE-NEXT:    strh w0, [sp, #14]
165; NONEON-NOSVE-NEXT:    strh w0, [sp, #12]
166; NONEON-NOSVE-NEXT:    strh w0, [sp, #10]
167; NONEON-NOSVE-NEXT:    strh w0, [sp, #8]
168; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
169; NONEON-NOSVE-NEXT:    add sp, sp, #16
170; NONEON-NOSVE-NEXT:    ret
171  %insert = insertelement <4 x i16> undef, i16 %a, i64 0
172  %splat = shufflevector <4 x i16> %insert, <4 x i16> undef, <4 x i32> zeroinitializer
173  ret <4 x i16> %splat
174}
175
176define <8 x i16> @splat_v8i16(i16 %a) {
177; CHECK-LABEL: splat_v8i16:
178; CHECK:       // %bb.0:
179; CHECK-NEXT:    mov z0.h, w0
180; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
181; CHECK-NEXT:    ret
182;
183; NONEON-NOSVE-LABEL: splat_v8i16:
184; NONEON-NOSVE:       // %bb.0:
185; NONEON-NOSVE-NEXT:    sub sp, sp, #16
186; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
187; NONEON-NOSVE-NEXT:    strh w0, [sp, #14]
188; NONEON-NOSVE-NEXT:    strh w0, [sp, #12]
189; NONEON-NOSVE-NEXT:    strh w0, [sp, #10]
190; NONEON-NOSVE-NEXT:    strh w0, [sp, #8]
191; NONEON-NOSVE-NEXT:    strh w0, [sp, #6]
192; NONEON-NOSVE-NEXT:    strh w0, [sp, #4]
193; NONEON-NOSVE-NEXT:    strh w0, [sp, #2]
194; NONEON-NOSVE-NEXT:    strh w0, [sp]
195; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
196; NONEON-NOSVE-NEXT:    ret
197  %insert = insertelement <8 x i16> undef, i16 %a, i64 0
198  %splat = shufflevector <8 x i16> %insert, <8 x i16> undef, <8 x i32> zeroinitializer
199  ret <8 x i16> %splat
200}
201
202define void @splat_v16i16(i16 %a, ptr %b) {
203; CHECK-LABEL: splat_v16i16:
204; CHECK:       // %bb.0:
205; CHECK-NEXT:    mov z0.h, w0
206; CHECK-NEXT:    stp q0, q0, [x1]
207; CHECK-NEXT:    ret
208;
209; NONEON-NOSVE-LABEL: splat_v16i16:
210; NONEON-NOSVE:       // %bb.0:
211; NONEON-NOSVE-NEXT:    sub sp, sp, #16
212; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
213; NONEON-NOSVE-NEXT:    strh w0, [sp, #14]
214; NONEON-NOSVE-NEXT:    strh w0, [sp, #12]
215; NONEON-NOSVE-NEXT:    strh w0, [sp, #10]
216; NONEON-NOSVE-NEXT:    strh w0, [sp, #8]
217; NONEON-NOSVE-NEXT:    strh w0, [sp, #6]
218; NONEON-NOSVE-NEXT:    strh w0, [sp, #4]
219; NONEON-NOSVE-NEXT:    strh w0, [sp, #2]
220; NONEON-NOSVE-NEXT:    strh w0, [sp]
221; NONEON-NOSVE-NEXT:    ldr q0, [sp]
222; NONEON-NOSVE-NEXT:    stp q0, q0, [x1]
223; NONEON-NOSVE-NEXT:    add sp, sp, #16
224; NONEON-NOSVE-NEXT:    ret
225  %insert = insertelement <16 x i16> undef, i16 %a, i64 0
226  %splat = shufflevector <16 x i16> %insert, <16 x i16> undef, <16 x i32> zeroinitializer
227  store <16 x i16> %splat, ptr %b
228  ret void
229}
230
231define <2 x i32> @splat_v2i32(i32 %a) {
232; CHECK-LABEL: splat_v2i32:
233; CHECK:       // %bb.0:
234; CHECK-NEXT:    mov z0.s, w0
235; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
236; CHECK-NEXT:    ret
237;
238; NONEON-NOSVE-LABEL: splat_v2i32:
239; NONEON-NOSVE:       // %bb.0:
240; NONEON-NOSVE-NEXT:    sub sp, sp, #16
241; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
242; NONEON-NOSVE-NEXT:    stp w0, w0, [sp, #8]
243; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
244; NONEON-NOSVE-NEXT:    add sp, sp, #16
245; NONEON-NOSVE-NEXT:    ret
246  %insert = insertelement <2 x i32> undef, i32 %a, i64 0
247  %splat = shufflevector <2 x i32> %insert, <2 x i32> undef, <2 x i32> zeroinitializer
248  ret <2 x i32> %splat
249}
250
251define <4 x i32> @splat_v4i32(i32 %a) {
252; CHECK-LABEL: splat_v4i32:
253; CHECK:       // %bb.0:
254; CHECK-NEXT:    mov z0.s, w0
255; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
256; CHECK-NEXT:    ret
257;
258; NONEON-NOSVE-LABEL: splat_v4i32:
259; NONEON-NOSVE:       // %bb.0:
260; NONEON-NOSVE-NEXT:    sub sp, sp, #16
261; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
262; NONEON-NOSVE-NEXT:    stp w0, w0, [sp, #8]
263; NONEON-NOSVE-NEXT:    stp w0, w0, [sp]
264; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
265; NONEON-NOSVE-NEXT:    ret
266  %insert = insertelement <4 x i32> undef, i32 %a, i64 0
267  %splat = shufflevector <4 x i32> %insert, <4 x i32> undef, <4 x i32> zeroinitializer
268  ret <4 x i32> %splat
269}
270
271define void @splat_v8i32(i32 %a, ptr %b) {
272; CHECK-LABEL: splat_v8i32:
273; CHECK:       // %bb.0:
274; CHECK-NEXT:    mov z0.s, w0
275; CHECK-NEXT:    stp q0, q0, [x1]
276; CHECK-NEXT:    ret
277;
278; NONEON-NOSVE-LABEL: splat_v8i32:
279; NONEON-NOSVE:       // %bb.0:
280; NONEON-NOSVE-NEXT:    sub sp, sp, #16
281; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
282; NONEON-NOSVE-NEXT:    stp w0, w0, [sp, #8]
283; NONEON-NOSVE-NEXT:    stp w0, w0, [sp]
284; NONEON-NOSVE-NEXT:    ldr q0, [sp]
285; NONEON-NOSVE-NEXT:    stp q0, q0, [x1]
286; NONEON-NOSVE-NEXT:    add sp, sp, #16
287; NONEON-NOSVE-NEXT:    ret
288  %insert = insertelement <8 x i32> undef, i32 %a, i64 0
289  %splat = shufflevector <8 x i32> %insert, <8 x i32> undef, <8 x i32> zeroinitializer
290  store <8 x i32> %splat, ptr %b
291  ret void
292}
293
294define <1 x i64> @splat_v1i64(i64 %a) {
295; CHECK-LABEL: splat_v1i64:
296; CHECK:       // %bb.0:
297; CHECK-NEXT:    mov z0.d, x0
298; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
299; CHECK-NEXT:    ret
300;
301; NONEON-NOSVE-LABEL: splat_v1i64:
302; NONEON-NOSVE:       // %bb.0:
303; NONEON-NOSVE-NEXT:    sub sp, sp, #16
304; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
305; NONEON-NOSVE-NEXT:    str x0, [sp, #8]
306; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
307; NONEON-NOSVE-NEXT:    add sp, sp, #16
308; NONEON-NOSVE-NEXT:    ret
309  %insert = insertelement <1 x i64> undef, i64 %a, i64 0
310  %splat = shufflevector <1 x i64> %insert, <1 x i64> undef, <1 x i32> zeroinitializer
311  ret <1 x i64> %splat
312}
313
314define <2 x i64> @splat_v2i64(i64 %a) {
315; CHECK-LABEL: splat_v2i64:
316; CHECK:       // %bb.0:
317; CHECK-NEXT:    mov z0.d, x0
318; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
319; CHECK-NEXT:    ret
320;
321; NONEON-NOSVE-LABEL: splat_v2i64:
322; NONEON-NOSVE:       // %bb.0:
323; NONEON-NOSVE-NEXT:    stp x0, x0, [sp, #-16]!
324; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
325; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
326; NONEON-NOSVE-NEXT:    ret
327  %insert = insertelement <2 x i64> undef, i64 %a, i64 0
328  %splat = shufflevector <2 x i64> %insert, <2 x i64> undef, <2 x i32> zeroinitializer
329  ret <2 x i64> %splat
330}
331
332define void @splat_v4i64(i64 %a, ptr %b) {
333; CHECK-LABEL: splat_v4i64:
334; CHECK:       // %bb.0:
335; CHECK-NEXT:    mov z0.d, x0
336; CHECK-NEXT:    stp q0, q0, [x1]
337; CHECK-NEXT:    ret
338;
339; NONEON-NOSVE-LABEL: splat_v4i64:
340; NONEON-NOSVE:       // %bb.0:
341; NONEON-NOSVE-NEXT:    stp x0, x0, [sp, #-16]!
342; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
343; NONEON-NOSVE-NEXT:    ldr q0, [sp]
344; NONEON-NOSVE-NEXT:    stp q0, q0, [x1]
345; NONEON-NOSVE-NEXT:    add sp, sp, #16
346; NONEON-NOSVE-NEXT:    ret
347  %insert = insertelement <4 x i64> undef, i64 %a, i64 0
348  %splat = shufflevector <4 x i64> %insert, <4 x i64> undef, <4 x i32> zeroinitializer
349  store <4 x i64> %splat, ptr %b
350  ret void
351}
352
353;
354; DUP (floating-point)
355;
356
357define <2 x half> @splat_v2f16(half %a) {
358; CHECK-LABEL: splat_v2f16:
359; CHECK:       // %bb.0:
360; CHECK-NEXT:    // kill: def $h0 killed $h0 def $z0
361; CHECK-NEXT:    mov z0.h, h0
362; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
363; CHECK-NEXT:    ret
364;
365; NONEON-NOSVE-LABEL: splat_v2f16:
366; NONEON-NOSVE:       // %bb.0:
367; NONEON-NOSVE-NEXT:    sub sp, sp, #16
368; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
369; NONEON-NOSVE-NEXT:    str h0, [sp, #10]
370; NONEON-NOSVE-NEXT:    str h0, [sp, #8]
371; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
372; NONEON-NOSVE-NEXT:    add sp, sp, #16
373; NONEON-NOSVE-NEXT:    ret
374  %insert = insertelement <2 x half> undef, half %a, i64 0
375  %splat = shufflevector <2 x half> %insert, <2 x half> undef, <2 x i32> zeroinitializer
376  ret <2 x half> %splat
377}
378
379define <4 x half> @splat_v4f16(half %a) {
380; CHECK-LABEL: splat_v4f16:
381; CHECK:       // %bb.0:
382; CHECK-NEXT:    // kill: def $h0 killed $h0 def $z0
383; CHECK-NEXT:    mov z0.h, h0
384; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
385; CHECK-NEXT:    ret
386;
387; NONEON-NOSVE-LABEL: splat_v4f16:
388; NONEON-NOSVE:       // %bb.0:
389; NONEON-NOSVE-NEXT:    sub sp, sp, #16
390; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
391; NONEON-NOSVE-NEXT:    str h0, [sp, #14]
392; NONEON-NOSVE-NEXT:    str h0, [sp, #12]
393; NONEON-NOSVE-NEXT:    str h0, [sp, #10]
394; NONEON-NOSVE-NEXT:    str h0, [sp, #8]
395; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
396; NONEON-NOSVE-NEXT:    add sp, sp, #16
397; NONEON-NOSVE-NEXT:    ret
398  %insert = insertelement <4 x half> undef, half %a, i64 0
399  %splat = shufflevector <4 x half> %insert, <4 x half> undef, <4 x i32> zeroinitializer
400  ret <4 x half> %splat
401}
402
403define <8 x half> @splat_v8f16(half %a) {
404; CHECK-LABEL: splat_v8f16:
405; CHECK:       // %bb.0:
406; CHECK-NEXT:    // kill: def $h0 killed $h0 def $z0
407; CHECK-NEXT:    mov z0.h, h0
408; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
409; CHECK-NEXT:    ret
410;
411; NONEON-NOSVE-LABEL: splat_v8f16:
412; NONEON-NOSVE:       // %bb.0:
413; NONEON-NOSVE-NEXT:    sub sp, sp, #16
414; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
415; NONEON-NOSVE-NEXT:    str h0, [sp, #14]
416; NONEON-NOSVE-NEXT:    str h0, [sp, #12]
417; NONEON-NOSVE-NEXT:    str h0, [sp, #10]
418; NONEON-NOSVE-NEXT:    str h0, [sp, #8]
419; NONEON-NOSVE-NEXT:    str h0, [sp, #6]
420; NONEON-NOSVE-NEXT:    str h0, [sp, #4]
421; NONEON-NOSVE-NEXT:    str h0, [sp, #2]
422; NONEON-NOSVE-NEXT:    str h0, [sp]
423; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
424; NONEON-NOSVE-NEXT:    ret
425  %insert = insertelement <8 x half> undef, half %a, i64 0
426  %splat = shufflevector <8 x half> %insert, <8 x half> undef, <8 x i32> zeroinitializer
427  ret <8 x half> %splat
428}
429
430define void @splat_v16f16(half %a, ptr %b) {
431; CHECK-LABEL: splat_v16f16:
432; CHECK:       // %bb.0:
433; CHECK-NEXT:    // kill: def $h0 killed $h0 def $z0
434; CHECK-NEXT:    mov z0.h, h0
435; CHECK-NEXT:    stp q0, q0, [x0]
436; CHECK-NEXT:    ret
437;
438; NONEON-NOSVE-LABEL: splat_v16f16:
439; NONEON-NOSVE:       // %bb.0:
440; NONEON-NOSVE-NEXT:    sub sp, sp, #16
441; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
442; NONEON-NOSVE-NEXT:    str h0, [sp, #14]
443; NONEON-NOSVE-NEXT:    str h0, [sp, #12]
444; NONEON-NOSVE-NEXT:    str h0, [sp, #10]
445; NONEON-NOSVE-NEXT:    str h0, [sp, #8]
446; NONEON-NOSVE-NEXT:    str h0, [sp, #6]
447; NONEON-NOSVE-NEXT:    str h0, [sp, #4]
448; NONEON-NOSVE-NEXT:    str h0, [sp, #2]
449; NONEON-NOSVE-NEXT:    str h0, [sp]
450; NONEON-NOSVE-NEXT:    ldr q0, [sp]
451; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
452; NONEON-NOSVE-NEXT:    add sp, sp, #16
453; NONEON-NOSVE-NEXT:    ret
454  %insert = insertelement <16 x half> undef, half %a, i64 0
455  %splat = shufflevector <16 x half> %insert, <16 x half> undef, <16 x i32> zeroinitializer
456  store <16 x half> %splat, ptr %b
457  ret void
458}
459
460define <2 x float> @splat_v2f32(float %a, <2 x float> %op2) {
461; CHECK-LABEL: splat_v2f32:
462; CHECK:       // %bb.0:
463; CHECK-NEXT:    // kill: def $s0 killed $s0 def $z0
464; CHECK-NEXT:    mov z0.s, s0
465; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
466; CHECK-NEXT:    ret
467;
468; NONEON-NOSVE-LABEL: splat_v2f32:
469; NONEON-NOSVE:       // %bb.0:
470; NONEON-NOSVE-NEXT:    sub sp, sp, #16
471; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
472; NONEON-NOSVE-NEXT:    stp s0, s0, [sp, #8]
473; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
474; NONEON-NOSVE-NEXT:    add sp, sp, #16
475; NONEON-NOSVE-NEXT:    ret
476  %insert = insertelement <2 x float> undef, float %a, i64 0
477  %splat = shufflevector <2 x float> %insert, <2 x float> undef, <2 x i32> zeroinitializer
478  ret <2 x float> %splat
479}
480
481define <4 x float> @splat_v4f32(float %a, <4 x float> %op2) {
482; CHECK-LABEL: splat_v4f32:
483; CHECK:       // %bb.0:
484; CHECK-NEXT:    // kill: def $s0 killed $s0 def $z0
485; CHECK-NEXT:    mov z0.s, s0
486; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
487; CHECK-NEXT:    ret
488;
489; NONEON-NOSVE-LABEL: splat_v4f32:
490; NONEON-NOSVE:       // %bb.0:
491; NONEON-NOSVE-NEXT:    sub sp, sp, #16
492; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
493; NONEON-NOSVE-NEXT:    stp s0, s0, [sp, #8]
494; NONEON-NOSVE-NEXT:    stp s0, s0, [sp]
495; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
496; NONEON-NOSVE-NEXT:    ret
497  %insert = insertelement <4 x float> undef, float %a, i64 0
498  %splat = shufflevector <4 x float> %insert, <4 x float> undef, <4 x i32> zeroinitializer
499  ret <4 x float> %splat
500}
501
502define void @splat_v8f32(float %a, ptr %b) {
503; CHECK-LABEL: splat_v8f32:
504; CHECK:       // %bb.0:
505; CHECK-NEXT:    // kill: def $s0 killed $s0 def $z0
506; CHECK-NEXT:    mov z0.s, s0
507; CHECK-NEXT:    stp q0, q0, [x0]
508; CHECK-NEXT:    ret
509;
510; NONEON-NOSVE-LABEL: splat_v8f32:
511; NONEON-NOSVE:       // %bb.0:
512; NONEON-NOSVE-NEXT:    sub sp, sp, #16
513; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
514; NONEON-NOSVE-NEXT:    stp s0, s0, [sp, #8]
515; NONEON-NOSVE-NEXT:    stp s0, s0, [sp]
516; NONEON-NOSVE-NEXT:    ldr q0, [sp]
517; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
518; NONEON-NOSVE-NEXT:    add sp, sp, #16
519; NONEON-NOSVE-NEXT:    ret
520  %insert = insertelement <8 x float> undef, float %a, i64 0
521  %splat = shufflevector <8 x float> %insert, <8 x float> undef, <8 x i32> zeroinitializer
522  store <8 x float> %splat, ptr %b
523  ret void
524}
525
526define <1 x double> @splat_v1f64(double %a, <1 x double> %op2) {
527; CHECK-LABEL: splat_v1f64:
528; CHECK:       // %bb.0:
529; CHECK-NEXT:    ret
530;
531; NONEON-NOSVE-LABEL: splat_v1f64:
532; NONEON-NOSVE:       // %bb.0:
533; NONEON-NOSVE-NEXT:    sub sp, sp, #16
534; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
535; NONEON-NOSVE-NEXT:    str d0, [sp, #8]
536; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
537; NONEON-NOSVE-NEXT:    add sp, sp, #16
538; NONEON-NOSVE-NEXT:    ret
539  %insert = insertelement <1 x double> undef, double %a, i64 0
540  %splat = shufflevector <1 x double> %insert, <1 x double> undef, <1 x i32> zeroinitializer
541  ret <1 x double> %splat
542}
543
544define <2 x double> @splat_v2f64(double %a, <2 x double> %op2) {
545; CHECK-LABEL: splat_v2f64:
546; CHECK:       // %bb.0:
547; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
548; CHECK-NEXT:    mov z0.d, d0
549; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
550; CHECK-NEXT:    ret
551;
552; NONEON-NOSVE-LABEL: splat_v2f64:
553; NONEON-NOSVE:       // %bb.0:
554; NONEON-NOSVE-NEXT:    stp d0, d0, [sp, #-16]!
555; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
556; NONEON-NOSVE-NEXT:    ldr q0, [sp], #16
557; NONEON-NOSVE-NEXT:    ret
558  %insert = insertelement <2 x double> undef, double %a, i64 0
559  %splat = shufflevector <2 x double> %insert, <2 x double> undef, <2 x i32> zeroinitializer
560  ret <2 x double> %splat
561}
562
563define void @splat_v4f64(double %a, ptr %b) {
564; CHECK-LABEL: splat_v4f64:
565; CHECK:       // %bb.0:
566; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
567; CHECK-NEXT:    mov z0.d, d0
568; CHECK-NEXT:    stp q0, q0, [x0]
569; CHECK-NEXT:    ret
570;
571; NONEON-NOSVE-LABEL: splat_v4f64:
572; NONEON-NOSVE:       // %bb.0:
573; NONEON-NOSVE-NEXT:    stp d0, d0, [sp, #-16]!
574; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
575; NONEON-NOSVE-NEXT:    ldr q0, [sp]
576; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
577; NONEON-NOSVE-NEXT:    add sp, sp, #16
578; NONEON-NOSVE-NEXT:    ret
579  %insert = insertelement <4 x double> undef, double %a, i64 0
580  %splat = shufflevector <4 x double> %insert, <4 x double> undef, <4 x i32> zeroinitializer
581  store <4 x double> %splat, ptr %b
582  ret void
583}
584
585;
586; DUP (integer immediate)
587;
588
589define void @splat_imm_v32i8(ptr %a) {
590; CHECK-LABEL: splat_imm_v32i8:
591; CHECK:       // %bb.0:
592; CHECK-NEXT:    mov z0.b, #1 // =0x1
593; CHECK-NEXT:    stp q0, q0, [x0]
594; CHECK-NEXT:    ret
595;
596; NONEON-NOSVE-LABEL: splat_imm_v32i8:
597; NONEON-NOSVE:       // %bb.0:
598; NONEON-NOSVE-NEXT:    adrp x8, .LCPI24_0
599; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI24_0]
600; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
601; NONEON-NOSVE-NEXT:    ret
602  %insert = insertelement <32 x i8> undef, i8 1, i64 0
603  %splat = shufflevector <32 x i8> %insert, <32 x i8> undef, <32 x i32> zeroinitializer
604  store <32 x i8> %splat, ptr %a
605  ret void
606}
607
608define void @splat_imm_v16i16(ptr %a) {
609; CHECK-LABEL: splat_imm_v16i16:
610; CHECK:       // %bb.0:
611; CHECK-NEXT:    mov z0.h, #2 // =0x2
612; CHECK-NEXT:    stp q0, q0, [x0]
613; CHECK-NEXT:    ret
614;
615; NONEON-NOSVE-LABEL: splat_imm_v16i16:
616; NONEON-NOSVE:       // %bb.0:
617; NONEON-NOSVE-NEXT:    adrp x8, .LCPI25_0
618; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI25_0]
619; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
620; NONEON-NOSVE-NEXT:    ret
621  %insert = insertelement <16 x i16> undef, i16 2, i64 0
622  %splat = shufflevector <16 x i16> %insert, <16 x i16> undef, <16 x i32> zeroinitializer
623  store <16 x i16> %splat, ptr %a
624  ret void
625}
626
627define void @splat_imm_v8i32(ptr %a) {
628; CHECK-LABEL: splat_imm_v8i32:
629; CHECK:       // %bb.0:
630; CHECK-NEXT:    mov z0.s, #3 // =0x3
631; CHECK-NEXT:    stp q0, q0, [x0]
632; CHECK-NEXT:    ret
633;
634; NONEON-NOSVE-LABEL: splat_imm_v8i32:
635; NONEON-NOSVE:       // %bb.0:
636; NONEON-NOSVE-NEXT:    adrp x8, .LCPI26_0
637; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI26_0]
638; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
639; NONEON-NOSVE-NEXT:    ret
640  %insert = insertelement <8 x i32> undef, i32 3, i64 0
641  %splat = shufflevector <8 x i32> %insert, <8 x i32> undef, <8 x i32> zeroinitializer
642  store <8 x i32> %splat, ptr %a
643  ret void
644}
645
646define void @splat_imm_v4i64(ptr %a) {
647; CHECK-LABEL: splat_imm_v4i64:
648; CHECK:       // %bb.0:
649; CHECK-NEXT:    mov z0.d, #4 // =0x4
650; CHECK-NEXT:    stp q0, q0, [x0]
651; CHECK-NEXT:    ret
652;
653; NONEON-NOSVE-LABEL: splat_imm_v4i64:
654; NONEON-NOSVE:       // %bb.0:
655; NONEON-NOSVE-NEXT:    adrp x8, .LCPI27_0
656; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI27_0]
657; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
658; NONEON-NOSVE-NEXT:    ret
659  %insert = insertelement <4 x i64> undef, i64 4, i64 0
660  %splat = shufflevector <4 x i64> %insert, <4 x i64> undef, <4 x i32> zeroinitializer
661  store <4 x i64> %splat, ptr %a
662  ret void
663}
664
665;
666; DUP (floating-point immediate)
667;
668
669define void @splat_imm_v16f16(ptr %a) {
670; CHECK-LABEL: splat_imm_v16f16:
671; CHECK:       // %bb.0:
672; CHECK-NEXT:    fmov z0.h, #5.00000000
673; CHECK-NEXT:    stp q0, q0, [x0]
674; CHECK-NEXT:    ret
675;
676; NONEON-NOSVE-LABEL: splat_imm_v16f16:
677; NONEON-NOSVE:       // %bb.0:
678; NONEON-NOSVE-NEXT:    adrp x8, .LCPI28_0
679; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI28_0]
680; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
681; NONEON-NOSVE-NEXT:    ret
682  %insert = insertelement <16 x half> undef, half 5.0, i64 0
683  %splat = shufflevector <16 x half> %insert, <16 x half> undef, <16 x i32> zeroinitializer
684  store <16 x half> %splat, ptr %a
685  ret void
686}
687
688define void @splat_imm_v8f32(ptr %a) {
689; CHECK-LABEL: splat_imm_v8f32:
690; CHECK:       // %bb.0:
691; CHECK-NEXT:    fmov z0.s, #6.00000000
692; CHECK-NEXT:    stp q0, q0, [x0]
693; CHECK-NEXT:    ret
694;
695; NONEON-NOSVE-LABEL: splat_imm_v8f32:
696; NONEON-NOSVE:       // %bb.0:
697; NONEON-NOSVE-NEXT:    adrp x8, .LCPI29_0
698; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI29_0]
699; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
700; NONEON-NOSVE-NEXT:    ret
701  %insert = insertelement <8 x float> undef, float 6.0, i64 0
702  %splat = shufflevector <8 x float> %insert, <8 x float> undef, <8 x i32> zeroinitializer
703  store <8 x float> %splat, ptr %a
704  ret void
705}
706
707define void @splat_imm_v4f64(ptr %a) {
708; CHECK-LABEL: splat_imm_v4f64:
709; CHECK:       // %bb.0:
710; CHECK-NEXT:    fmov z0.d, #7.00000000
711; CHECK-NEXT:    stp q0, q0, [x0]
712; CHECK-NEXT:    ret
713;
714; NONEON-NOSVE-LABEL: splat_imm_v4f64:
715; NONEON-NOSVE:       // %bb.0:
716; NONEON-NOSVE-NEXT:    adrp x8, .LCPI30_0
717; NONEON-NOSVE-NEXT:    ldr q0, [x8, :lo12:.LCPI30_0]
718; NONEON-NOSVE-NEXT:    stp q0, q0, [x0]
719; NONEON-NOSVE-NEXT:    ret
720  %insert = insertelement <4 x double> undef, double 7.0, i64 0
721  %splat = shufflevector <4 x double> %insert, <4 x double> undef, <4 x i32> zeroinitializer
722  store <4 x double> %splat, ptr %a
723  ret void
724}
725