1; RUN: llc -aarch64-sve-vector-bits-min=128  < %s | FileCheck %s -D#VBYTES=16  -check-prefix=NO_SVE
2; RUN: llc -aarch64-sve-vector-bits-min=256  < %s | FileCheck %s -check-prefixes=VBITS_GE_256
3; RUN: llc -aarch64-sve-vector-bits-min=384  < %s | FileCheck %s -check-prefixes=VBITS_GE_256
4; RUN: llc -aarch64-sve-vector-bits-min=512  < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512
5; RUN: llc -aarch64-sve-vector-bits-min=640  < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512
6; RUN: llc -aarch64-sve-vector-bits-min=768  < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512
7; RUN: llc -aarch64-sve-vector-bits-min=896  < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512
8; RUN: llc -aarch64-sve-vector-bits-min=1024 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
9; RUN: llc -aarch64-sve-vector-bits-min=1152 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
10; RUN: llc -aarch64-sve-vector-bits-min=1280 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
11; RUN: llc -aarch64-sve-vector-bits-min=1408 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
12; RUN: llc -aarch64-sve-vector-bits-min=1536 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
13; RUN: llc -aarch64-sve-vector-bits-min=1664 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
14; RUN: llc -aarch64-sve-vector-bits-min=1792 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
15; RUN: llc -aarch64-sve-vector-bits-min=1920 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024
16; RUN: llc -aarch64-sve-vector-bits-min=2048 < %s | FileCheck %s -check-prefixes=VBITS_GE_256,VBITS_GE_512,VBITS_GE_1024,VBITS_GE_2048
17
18target triple = "aarch64-unknown-linux-gnu"
19
20; Don't use SVE when its registers are no bigger than NEON.
21; NO_SVE-NOT: ptrue
22
23;
24; insertelement
25;
26
27; Don't use SVE for 64-bit vectors.
28define <4 x half> @insertelement_v4f16(<4 x half> %op1) #0 {
29; VBITS_GE_256-LABEL: insertelement_v4f16:
30; VBITS_GE_256:       // %bb.0:
31; VBITS_GE_256-NEXT:    fmov h1, #5.00000000
32; VBITS_GE_256-NEXT:    // kill: def $d0 killed $d0 def $q0
33; VBITS_GE_256-NEXT:    mov v0.h[3], v1.h[0]
34; VBITS_GE_256-NEXT:    // kill: def $d0 killed $d0 killed $q0
35; VBITS_GE_256-NEXT:    ret
36    %r = insertelement <4 x half> %op1, half 5.0, i64 3
37    ret <4 x half> %r
38}
39
40; Don't use SVE for 128-bit vectors.
41define <8 x half> @insertelement_v8f16(<8 x half> %op1) #0 {
42; VBITS_GE_256-LABEL: insertelement_v8f16:
43; VBITS_GE_256:       // %bb.0:
44; VBITS_GE_256-NEXT:    fmov h1, #5.00000000
45; VBITS_GE_256-NEXT:    mov v0.h[7], v1.h[0]
46; VBITS_GE_256-NEXT:    ret
47    %r = insertelement <8 x half> %op1, half 5.0, i64 7
48    ret <8 x half> %r
49}
50
51define <16 x half> @insertelement_v16f16(<16 x half>* %a) #0 {
52; VBITS_GE_256-LABEL: insertelement_v16f16:
53; VBITS_GE_256:       // %bb.0:
54; VBITS_GE_256-NEXT:    mov w9, #15
55; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
56; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0]
57; VBITS_GE_256-NEXT:    fmov h2, #5.00000000
58; VBITS_GE_256-NEXT:    index z3.h, #0, #1
59; VBITS_GE_256-NEXT:    ptrue p1.h
60; VBITS_GE_256-NEXT:    mov z1.h, w9
61; VBITS_GE_256-NEXT:    cmpeq p1.h, p1/z, z3.h, z1.h
62; VBITS_GE_256-NEXT:    mov z0.h, p1/m, h2
63; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x8]
64; VBITS_GE_256-NEXT:    ret
65    %op1 = load <16 x half>, <16 x half>* %a
66    %r = insertelement <16 x half> %op1, half 5.0, i64 15
67    ret <16 x half> %r
68}
69
70define <32 x half> @insertelement_v32f16(<32 x half>* %a) #0 {
71; VBITS_GE_512-LABEL: insertelement_v32f16:
72; VBITS_GE_512:       // %bb.0:
73; VBITS_GE_512-NEXT:    mov w9, #31
74; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
75; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
76; VBITS_GE_512-NEXT:    fmov h2, #5.00000000
77; VBITS_GE_512-NEXT:    index z3.h, #0, #1
78; VBITS_GE_512-NEXT:    ptrue p1.h
79; VBITS_GE_512-NEXT:    mov z1.h, w9
80; VBITS_GE_512-NEXT:    cmpeq p1.h, p1/z, z3.h, z1.h
81; VBITS_GE_512-NEXT:    mov z0.h, p1/m, h2
82; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x8]
83; VBITS_GE_512-NEXT:    ret
84    %op1 = load <32 x half>, <32 x half>* %a
85    %r = insertelement <32 x half> %op1, half 5.0, i64 31
86    ret <32 x half> %r
87}
88
89define <64 x half> @insertelement_v64f16(<64 x half>* %a) #0 {
90; VBITS_GE_1024-LABEL: insertelement_v64f16:
91; VBITS_GE_1024:       // %bb.0:
92; VBITS_GE_1024-NEXT:    mov w9, #63
93; VBITS_GE_1024-NEXT:    ptrue p0.h, vl64
94; VBITS_GE_1024-NEXT:    ld1h { z0.h }, p0/z, [x0]
95; VBITS_GE_1024-NEXT:    fmov h2, #5.00000000
96; VBITS_GE_1024-NEXT:    index z3.h, #0, #1
97; VBITS_GE_1024-NEXT:    ptrue p1.h
98; VBITS_GE_1024-NEXT:    mov z1.h, w9
99; VBITS_GE_1024-NEXT:    cmpeq p1.h, p1/z, z3.h, z1.h
100; VBITS_GE_1024-NEXT:    mov z0.h, p1/m, h2
101; VBITS_GE_1024-NEXT:    st1h { z0.h }, p0, [x8]
102; VBITS_GE_1024-NEXT:    ret
103    %op1 = load <64 x half>, <64 x half>* %a
104    %r = insertelement <64 x half> %op1, half 5.0, i64 63
105    ret <64 x half> %r
106}
107
108define <128 x half> @insertelement_v128f16(<128 x half>* %a) #0 {
109; VBITS_GE_2048-LABEL: insertelement_v128f16:
110; VBITS_GE_2048:       // %bb.0:
111; VBITS_GE_2048-NEXT:    mov w9, #127
112; VBITS_GE_2048-NEXT:    ptrue p0.h, vl128
113; VBITS_GE_2048-NEXT:    ld1h { z0.h }, p0/z, [x0]
114; VBITS_GE_2048-NEXT:    fmov h2, #5.00000000
115; VBITS_GE_2048-NEXT:    index z3.h, #0, #1
116; VBITS_GE_2048-NEXT:    ptrue p1.h
117; VBITS_GE_2048-NEXT:    mov z1.h, w9
118; VBITS_GE_2048-NEXT:    cmpeq p1.h, p1/z, z3.h, z1.h
119; VBITS_GE_2048-NEXT:    mov z0.h, p1/m, h2
120; VBITS_GE_2048-NEXT:    st1h { z0.h }, p0, [x8]
121; VBITS_GE_2048-NEXT:    ret
122    %op1 = load <128 x half>, <128 x half>* %a
123    %r = insertelement <128 x half> %op1, half 5.0, i64 127
124    ret <128 x half> %r
125}
126
127; Don't use SVE for 64-bit vectors.
128define <2 x float> @insertelement_v2f32(<2 x float> %op1) #0 {
129; VBITS_GE_256-LABEL: insertelement_v2f32:
130; VBITS_GE_256:       // %bb.0:
131; VBITS_GE_256-NEXT:    fmov s1, #5.00000000
132; VBITS_GE_256-NEXT:    // kill: def $d0 killed $d0 def $q0
133; VBITS_GE_256-NEXT:    mov v0.s[1], v1.s[0]
134; VBITS_GE_256-NEXT:    // kill: def $d0 killed $d0 killed $q0
135; VBITS_GE_256-NEXT:    ret
136    %r = insertelement <2 x float> %op1, float 5.0, i64 1
137    ret <2 x float> %r
138}
139
140; Don't use SVE for 128-bit vectors.
141define <4 x float> @insertelement_v4f32(<4 x float> %op1) #0 {
142; VBITS_GE_256-LABEL: insertelement_v4f32:
143; VBITS_GE_256:       // %bb.0:
144; VBITS_GE_256-NEXT:    fmov s1, #5.00000000
145; VBITS_GE_256-NEXT:    mov v0.s[3], v1.s[0]
146; VBITS_GE_256-NEXT:    ret
147    %r = insertelement <4 x float> %op1, float 5.0, i64 3
148    ret <4 x float> %r
149}
150
151define <8 x float> @insertelement_v8f32(<8 x float>* %a) #0 {
152; VBITS_GE_256-LABEL: insertelement_v8f32:
153; VBITS_GE_256:       // %bb.0:
154; VBITS_GE_256-NEXT:    mov w9, #7
155; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
156; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0]
157; VBITS_GE_256-NEXT:    fmov s2, #5.00000000
158; VBITS_GE_256-NEXT:    index z3.s, #0, #1
159; VBITS_GE_256-NEXT:    ptrue p1.s
160; VBITS_GE_256-NEXT:    mov z1.s, w9
161; VBITS_GE_256-NEXT:    cmpeq p1.s, p1/z, z3.s, z1.s
162; VBITS_GE_256-NEXT:    mov z0.s, p1/m, s2
163; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x8]
164; VBITS_GE_256-NEXT:    ret
165    %op1 = load <8 x float>, <8 x float>* %a
166    %r = insertelement <8 x float> %op1, float 5.0, i64 7
167    ret <8 x float> %r
168}
169
170define <16 x float> @insertelement_v16f32(<16 x float>* %a) #0 {
171; VBITS_GE_512-LABEL: insertelement_v16f32:
172; VBITS_GE_512:       // %bb.0:
173; VBITS_GE_512-NEXT:    mov w9, #15
174; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
175; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
176; VBITS_GE_512-NEXT:    fmov s2, #5.00000000
177; VBITS_GE_512-NEXT:    index z3.s, #0, #1
178; VBITS_GE_512-NEXT:    ptrue p1.s
179; VBITS_GE_512-NEXT:    mov z1.s, w9
180; VBITS_GE_512-NEXT:    cmpeq p1.s, p1/z, z3.s, z1.s
181; VBITS_GE_512-NEXT:    mov z0.s, p1/m, s2
182; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x8]
183; VBITS_GE_512-NEXT:    ret
184    %op1 = load <16 x float>, <16 x float>* %a
185    %r = insertelement <16 x float> %op1, float 5.0, i64 15
186    ret <16 x float> %r
187}
188
189define <32 x float> @insertelement_v32f32(<32 x float>* %a) #0 {
190; VBITS_GE_1024-LABEL: insertelement_v32f32:
191; VBITS_GE_1024:       // %bb.0:
192; VBITS_GE_1024-NEXT:    mov w9, #31
193; VBITS_GE_1024-NEXT:    ptrue p0.s, vl32
194; VBITS_GE_1024-NEXT:    ld1w { z0.s }, p0/z, [x0]
195; VBITS_GE_1024-NEXT:    fmov s2, #5.00000000
196; VBITS_GE_1024-NEXT:    index z3.s, #0, #1
197; VBITS_GE_1024-NEXT:    ptrue p1.s
198; VBITS_GE_1024-NEXT:    mov z1.s, w9
199; VBITS_GE_1024-NEXT:    cmpeq p1.s, p1/z, z3.s, z1.s
200; VBITS_GE_1024-NEXT:    mov z0.s, p1/m, s2
201; VBITS_GE_1024-NEXT:    st1w { z0.s }, p0, [x8]
202; VBITS_GE_1024-NEXT:    ret
203    %op1 = load <32 x float>, <32 x float>* %a
204    %r = insertelement <32 x float> %op1, float 5.0, i64 31
205    ret <32 x float> %r
206}
207
208define <64 x float> @insertelement_v64f32(<64 x float>* %a) #0 {
209; VBITS_GE_2048-LABEL: insertelement_v64f32:
210; VBITS_GE_2048:       // %bb.0:
211; VBITS_GE_2048-NEXT:    mov w9, #63
212; VBITS_GE_2048-NEXT:    ptrue p0.s, vl64
213; VBITS_GE_2048-NEXT:    ld1w { z0.s }, p0/z, [x0]
214; VBITS_GE_2048-NEXT:    fmov s2, #5.00000000
215; VBITS_GE_2048-NEXT:    index z3.s, #0, #1
216; VBITS_GE_2048-NEXT:    ptrue p1.s
217; VBITS_GE_2048-NEXT:    mov z1.s, w9
218; VBITS_GE_2048-NEXT:    cmpeq p1.s, p1/z, z3.s, z1.s
219; VBITS_GE_2048-NEXT:    mov z0.s, p1/m, s2
220; VBITS_GE_2048-NEXT:    st1w { z0.s }, p0, [x8]
221; VBITS_GE_2048-NEXT:    ret
222    %op1 = load <64 x float>, <64 x float>* %a
223    %r = insertelement <64 x float> %op1, float 5.0, i64 63
224    ret <64 x float> %r
225}
226
227; Don't use SVE for 64-bit vectors.
228define <1 x double> @insertelement_v1f64(<1 x double> %op1) #0 {
229; VBITS_GE_256-LABEL: insertelement_v1f64:
230; VBITS_GE_256:       // %bb.0:
231; VBITS_GE_256-NEXT:    mov x8, #4617315517961601024
232; VBITS_GE_256-NEXT:    fmov d0, x8
233; VBITS_GE_256-NEXT:    ret
234    %r = insertelement <1 x double> %op1, double 5.0, i64 0
235    ret <1 x double> %r
236}
237
238; Don't use SVE for 128-bit vectors.
239define <2 x double> @insertelement_v2f64(<2 x double> %op1) #0 {
240; VBITS_GE_256-LABEL: insertelement_v2f64:
241; VBITS_GE_256:       // %bb.0:
242; VBITS_GE_256-NEXT:    fmov d1, #5.00000000
243; VBITS_GE_256-NEXT:    mov v0.d[1], v1.d[0]
244; VBITS_GE_256-NEXT:    ret
245    %r = insertelement <2 x double> %op1, double 5.0, i64 1
246    ret <2 x double> %r
247}
248
249define <4 x double> @insertelement_v4f64(<4 x double>* %a) #0 {
250; VBITS_GE_256-LABEL: insertelement_v4f64:
251; VBITS_GE_256:       // %bb.0:
252; VBITS_GE_256-NEXT:    mov w9, #3
253; VBITS_GE_256-NEXT:    ptrue p0.d, vl4
254; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0]
255; VBITS_GE_256-NEXT:    fmov d2, #5.00000000
256; VBITS_GE_256-NEXT:    index z3.d, #0, #1
257; VBITS_GE_256-NEXT:    ptrue p1.d
258; VBITS_GE_256-NEXT:    mov z1.d, x9
259; VBITS_GE_256-NEXT:    cmpeq p1.d, p1/z, z3.d, z1.d
260; VBITS_GE_256-NEXT:    mov z0.d, p1/m, d2
261; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x8]
262; VBITS_GE_256-NEXT:    ret
263    %op1 = load <4 x double>, <4 x double>* %a
264    %r = insertelement <4 x double> %op1, double 5.0, i64 3
265    ret <4 x double> %r
266}
267
268define <8 x double> @insertelement_v8f64(<8 x double>* %a) #0 {
269; VBITS_GE_512-LABEL: insertelement_v8f64:
270; VBITS_GE_512:       // %bb.0:
271; VBITS_GE_512-NEXT:    mov w9, #7
272; VBITS_GE_512-NEXT:    ptrue p0.d, vl8
273; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0]
274; VBITS_GE_512-NEXT:    fmov d2, #5.00000000
275; VBITS_GE_512-NEXT:    index z3.d, #0, #1
276; VBITS_GE_512-NEXT:    ptrue p1.d
277; VBITS_GE_512-NEXT:    mov z1.d, x9
278; VBITS_GE_512-NEXT:    cmpeq p1.d, p1/z, z3.d, z1.d
279; VBITS_GE_512-NEXT:    mov z0.d, p1/m, d2
280; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x8]
281; VBITS_GE_512-NEXT:    ret
282    %op1 = load <8 x double>, <8 x double>* %a
283    %r = insertelement <8 x double> %op1, double 5.0, i64 7
284    ret <8 x double> %r
285}
286
287define <16 x double> @insertelement_v16f64(<16 x double>* %a) #0 {
288; VBITS_GE_1024-LABEL: insertelement_v16f64:
289; VBITS_GE_1024:       // %bb.0:
290; VBITS_GE_1024-NEXT:    mov w9, #15
291; VBITS_GE_1024-NEXT:    ptrue p0.d, vl16
292; VBITS_GE_1024-NEXT:    ld1d { z0.d }, p0/z, [x0]
293; VBITS_GE_1024-NEXT:    fmov d2, #5.00000000
294; VBITS_GE_1024-NEXT:    index z3.d, #0, #1
295; VBITS_GE_1024-NEXT:    ptrue p1.d
296; VBITS_GE_1024-NEXT:    mov z1.d, x9
297; VBITS_GE_1024-NEXT:    cmpeq p1.d, p1/z, z3.d, z1.d
298; VBITS_GE_1024-NEXT:    mov z0.d, p1/m, d2
299; VBITS_GE_1024-NEXT:    st1d { z0.d }, p0, [x8]
300; VBITS_GE_1024-NEXT:    ret
301    %op1 = load <16 x double>, <16 x double>* %a
302    %r = insertelement <16 x double> %op1, double 5.0, i64 15
303    ret <16 x double> %r
304}
305
306define <32 x double> @insertelement_v32f64(<32 x double>* %a) #0 {
307; VBITS_GE_2048-LABEL: insertelement_v32f64:
308; VBITS_GE_2048:       // %bb.0:
309; VBITS_GE_2048-NEXT:    mov w9, #31
310; VBITS_GE_2048-NEXT:    ptrue p0.d, vl32
311; VBITS_GE_2048-NEXT:    ld1d { z0.d }, p0/z, [x0]
312; VBITS_GE_2048-NEXT:    fmov d2, #5.00000000
313; VBITS_GE_2048-NEXT:    index z3.d, #0, #1
314; VBITS_GE_2048-NEXT:    ptrue p1.d
315; VBITS_GE_2048-NEXT:    mov z1.d, x9
316; VBITS_GE_2048-NEXT:    cmpeq p1.d, p1/z, z3.d, z1.d
317; VBITS_GE_2048-NEXT:    mov z0.d, p1/m, d2
318; VBITS_GE_2048-NEXT:    st1d { z0.d }, p0, [x8]
319; VBITS_GE_2048-NEXT:    ret
320    %op1 = load <32 x double>, <32 x double>* %a
321    %r = insertelement <32 x double> %op1, double 5.0, i64 31
322    ret <32 x double> %r
323}
324
325attributes #0 = { "target-features"="+sve" }
326