1; Test vector insertion of memory values.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
4
5; Test v16i8 insertion into the first element.
6define <16 x i8> @f1(<16 x i8> %val, i8 *%ptr) {
7; CHECK-LABEL: f1:
8; CHECK: vleb %v24, 0(%r2), 0
9; CHECK: br %r14
10  %element = load i8, i8 *%ptr
11  %ret = insertelement <16 x i8> %val, i8 %element, i32 0
12  ret <16 x i8> %ret
13}
14
15; Test v16i8 insertion into the last element.
16define <16 x i8> @f2(<16 x i8> %val, i8 *%ptr) {
17; CHECK-LABEL: f2:
18; CHECK: vleb %v24, 0(%r2), 15
19; CHECK: br %r14
20  %element = load i8, i8 *%ptr
21  %ret = insertelement <16 x i8> %val, i8 %element, i32 15
22  ret <16 x i8> %ret
23}
24
25; Test v16i8 insertion with the highest in-range offset.
26define <16 x i8> @f3(<16 x i8> %val, i8 *%base) {
27; CHECK-LABEL: f3:
28; CHECK: vleb %v24, 4095(%r2), 10
29; CHECK: br %r14
30  %ptr = getelementptr i8, i8 *%base, i32 4095
31  %element = load i8, i8 *%ptr
32  %ret = insertelement <16 x i8> %val, i8 %element, i32 10
33  ret <16 x i8> %ret
34}
35
36; Test v16i8 insertion with the first ouf-of-range offset.
37define <16 x i8> @f4(<16 x i8> %val, i8 *%base) {
38; CHECK-LABEL: f4:
39; CHECK: aghi %r2, 4096
40; CHECK: vleb %v24, 0(%r2), 5
41; CHECK: br %r14
42  %ptr = getelementptr i8, i8 *%base, i32 4096
43  %element = load i8, i8 *%ptr
44  %ret = insertelement <16 x i8> %val, i8 %element, i32 5
45  ret <16 x i8> %ret
46}
47
48; Test v16i8 insertion into a variable element.
49define <16 x i8> @f5(<16 x i8> %val, i8 *%ptr, i32 %index) {
50; CHECK-LABEL: f5:
51; CHECK-NOT: vleb
52; CHECK: br %r14
53  %element = load i8, i8 *%ptr
54  %ret = insertelement <16 x i8> %val, i8 %element, i32 %index
55  ret <16 x i8> %ret
56}
57
58; Test v8i16 insertion into the first element.
59define <8 x i16> @f6(<8 x i16> %val, i16 *%ptr) {
60; CHECK-LABEL: f6:
61; CHECK: vleh %v24, 0(%r2), 0
62; CHECK: br %r14
63  %element = load i16, i16 *%ptr
64  %ret = insertelement <8 x i16> %val, i16 %element, i32 0
65  ret <8 x i16> %ret
66}
67
68; Test v8i16 insertion into the last element.
69define <8 x i16> @f7(<8 x i16> %val, i16 *%ptr) {
70; CHECK-LABEL: f7:
71; CHECK: vleh %v24, 0(%r2), 7
72; CHECK: br %r14
73  %element = load i16, i16 *%ptr
74  %ret = insertelement <8 x i16> %val, i16 %element, i32 7
75  ret <8 x i16> %ret
76}
77
78; Test v8i16 insertion with the highest in-range offset.
79define <8 x i16> @f8(<8 x i16> %val, i16 *%base) {
80; CHECK-LABEL: f8:
81; CHECK: vleh %v24, 4094(%r2), 5
82; CHECK: br %r14
83  %ptr = getelementptr i16, i16 *%base, i32 2047
84  %element = load i16, i16 *%ptr
85  %ret = insertelement <8 x i16> %val, i16 %element, i32 5
86  ret <8 x i16> %ret
87}
88
89; Test v8i16 insertion with the first ouf-of-range offset.
90define <8 x i16> @f9(<8 x i16> %val, i16 *%base) {
91; CHECK-LABEL: f9:
92; CHECK: aghi %r2, 4096
93; CHECK: vleh %v24, 0(%r2), 1
94; CHECK: br %r14
95  %ptr = getelementptr i16, i16 *%base, i32 2048
96  %element = load i16, i16 *%ptr
97  %ret = insertelement <8 x i16> %val, i16 %element, i32 1
98  ret <8 x i16> %ret
99}
100
101; Test v8i16 insertion into a variable element.
102define <8 x i16> @f10(<8 x i16> %val, i16 *%ptr, i32 %index) {
103; CHECK-LABEL: f10:
104; CHECK-NOT: vleh
105; CHECK: br %r14
106  %element = load i16, i16 *%ptr
107  %ret = insertelement <8 x i16> %val, i16 %element, i32 %index
108  ret <8 x i16> %ret
109}
110
111; Test v4i32 insertion into the first element.
112define <4 x i32> @f11(<4 x i32> %val, i32 *%ptr) {
113; CHECK-LABEL: f11:
114; CHECK: vlef %v24, 0(%r2), 0
115; CHECK: br %r14
116  %element = load i32, i32 *%ptr
117  %ret = insertelement <4 x i32> %val, i32 %element, i32 0
118  ret <4 x i32> %ret
119}
120
121; Test v4i32 insertion into the last element.
122define <4 x i32> @f12(<4 x i32> %val, i32 *%ptr) {
123; CHECK-LABEL: f12:
124; CHECK: vlef %v24, 0(%r2), 3
125; CHECK: br %r14
126  %element = load i32, i32 *%ptr
127  %ret = insertelement <4 x i32> %val, i32 %element, i32 3
128  ret <4 x i32> %ret
129}
130
131; Test v4i32 insertion with the highest in-range offset.
132define <4 x i32> @f13(<4 x i32> %val, i32 *%base) {
133; CHECK-LABEL: f13:
134; CHECK: vlef %v24, 4092(%r2), 2
135; CHECK: br %r14
136  %ptr = getelementptr i32, i32 *%base, i32 1023
137  %element = load i32, i32 *%ptr
138  %ret = insertelement <4 x i32> %val, i32 %element, i32 2
139  ret <4 x i32> %ret
140}
141
142; Test v4i32 insertion with the first ouf-of-range offset.
143define <4 x i32> @f14(<4 x i32> %val, i32 *%base) {
144; CHECK-LABEL: f14:
145; CHECK: aghi %r2, 4096
146; CHECK: vlef %v24, 0(%r2), 1
147; CHECK: br %r14
148  %ptr = getelementptr i32, i32 *%base, i32 1024
149  %element = load i32, i32 *%ptr
150  %ret = insertelement <4 x i32> %val, i32 %element, i32 1
151  ret <4 x i32> %ret
152}
153
154; Test v4i32 insertion into a variable element.
155define <4 x i32> @f15(<4 x i32> %val, i32 *%ptr, i32 %index) {
156; CHECK-LABEL: f15:
157; CHECK-NOT: vlef
158; CHECK: br %r14
159  %element = load i32, i32 *%ptr
160  %ret = insertelement <4 x i32> %val, i32 %element, i32 %index
161  ret <4 x i32> %ret
162}
163
164; Test v2i64 insertion into the first element.
165define <2 x i64> @f16(<2 x i64> %val, i64 *%ptr) {
166; CHECK-LABEL: f16:
167; CHECK: vleg %v24, 0(%r2), 0
168; CHECK: br %r14
169  %element = load i64, i64 *%ptr
170  %ret = insertelement <2 x i64> %val, i64 %element, i32 0
171  ret <2 x i64> %ret
172}
173
174; Test v2i64 insertion into the last element.
175define <2 x i64> @f17(<2 x i64> %val, i64 *%ptr) {
176; CHECK-LABEL: f17:
177; CHECK: vleg %v24, 0(%r2), 1
178; CHECK: br %r14
179  %element = load i64, i64 *%ptr
180  %ret = insertelement <2 x i64> %val, i64 %element, i32 1
181  ret <2 x i64> %ret
182}
183
184; Test v2i64 insertion with the highest in-range offset.
185define <2 x i64> @f18(<2 x i64> %val, i64 *%base) {
186; CHECK-LABEL: f18:
187; CHECK: vleg %v24, 4088(%r2), 1
188; CHECK: br %r14
189  %ptr = getelementptr i64, i64 *%base, i32 511
190  %element = load i64, i64 *%ptr
191  %ret = insertelement <2 x i64> %val, i64 %element, i32 1
192  ret <2 x i64> %ret
193}
194
195; Test v2i64 insertion with the first ouf-of-range offset.
196define <2 x i64> @f19(<2 x i64> %val, i64 *%base) {
197; CHECK-LABEL: f19:
198; CHECK: aghi %r2, 4096
199; CHECK: vleg %v24, 0(%r2), 0
200; CHECK: br %r14
201  %ptr = getelementptr i64, i64 *%base, i32 512
202  %element = load i64, i64 *%ptr
203  %ret = insertelement <2 x i64> %val, i64 %element, i32 0
204  ret <2 x i64> %ret
205}
206
207; Test v2i64 insertion into a variable element.
208define <2 x i64> @f20(<2 x i64> %val, i64 *%ptr, i32 %index) {
209; CHECK-LABEL: f20:
210; CHECK-NOT: vleg
211; CHECK: br %r14
212  %element = load i64, i64 *%ptr
213  %ret = insertelement <2 x i64> %val, i64 %element, i32 %index
214  ret <2 x i64> %ret
215}
216
217; Test v2f64 insertion into the first element.
218define <2 x double> @f26(<2 x double> %val, double *%ptr) {
219; CHECK-LABEL: f26:
220; CHECK: vleg %v24, 0(%r2), 0
221; CHECK: br %r14
222  %element = load double, double *%ptr
223  %ret = insertelement <2 x double> %val, double %element, i32 0
224  ret <2 x double> %ret
225}
226
227; Test v2f64 insertion into the last element.
228define <2 x double> @f27(<2 x double> %val, double *%ptr) {
229; CHECK-LABEL: f27:
230; CHECK: vleg %v24, 0(%r2), 1
231; CHECK: br %r14
232  %element = load double, double *%ptr
233  %ret = insertelement <2 x double> %val, double %element, i32 1
234  ret <2 x double> %ret
235}
236
237; Test v2f64 insertion with the highest in-range offset.
238define <2 x double> @f28(<2 x double> %val, double *%base) {
239; CHECK-LABEL: f28:
240; CHECK: vleg %v24, 4088(%r2), 1
241; CHECK: br %r14
242  %ptr = getelementptr double, double *%base, i32 511
243  %element = load double, double *%ptr
244  %ret = insertelement <2 x double> %val, double %element, i32 1
245  ret <2 x double> %ret
246}
247
248; Test v2f64 insertion with the first ouf-of-range offset.
249define <2 x double> @f29(<2 x double> %val, double *%base) {
250; CHECK-LABEL: f29:
251; CHECK: aghi %r2, 4096
252; CHECK: vleg %v24, 0(%r2), 0
253; CHECK: br %r14
254  %ptr = getelementptr double, double *%base, i32 512
255  %element = load double, double *%ptr
256  %ret = insertelement <2 x double> %val, double %element, i32 0
257  ret <2 x double> %ret
258}
259
260; Test v2f64 insertion into a variable element.
261define <2 x double> @f30(<2 x double> %val, double *%ptr, i32 %index) {
262; CHECK-LABEL: f30:
263; CHECK-NOT: vleg
264; CHECK: br %r14
265  %element = load double, double *%ptr
266  %ret = insertelement <2 x double> %val, double %element, i32 %index
267  ret <2 x double> %ret
268}
269
270; Test a v4i32 gather of the first element.
271define <4 x i32> @f31(<4 x i32> %val, <4 x i32> %index, i64 %base) {
272; CHECK-LABEL: f31:
273; CHECK: vgef %v24, 0(%v26,%r2), 0
274; CHECK: br %r14
275  %elem = extractelement <4 x i32> %index, i32 0
276  %ext = zext i32 %elem to i64
277  %add = add i64 %base, %ext
278  %ptr = inttoptr i64 %add to i32 *
279  %element = load i32, i32 *%ptr
280  %ret = insertelement <4 x i32> %val, i32 %element, i32 0
281  ret <4 x i32> %ret
282}
283
284; Test a v4i32 gather of the last element.
285define <4 x i32> @f32(<4 x i32> %val, <4 x i32> %index, i64 %base) {
286; CHECK-LABEL: f32:
287; CHECK: vgef %v24, 0(%v26,%r2), 3
288; CHECK: br %r14
289  %elem = extractelement <4 x i32> %index, i32 3
290  %ext = zext i32 %elem to i64
291  %add = add i64 %base, %ext
292  %ptr = inttoptr i64 %add to i32 *
293  %element = load i32, i32 *%ptr
294  %ret = insertelement <4 x i32> %val, i32 %element, i32 3
295  ret <4 x i32> %ret
296}
297
298; Test a v4i32 gather with the highest in-range offset.
299define <4 x i32> @f33(<4 x i32> %val, <4 x i32> %index, i64 %base) {
300; CHECK-LABEL: f33:
301; CHECK: vgef %v24, 4095(%v26,%r2), 1
302; CHECK: br %r14
303  %elem = extractelement <4 x i32> %index, i32 1
304  %ext = zext i32 %elem to i64
305  %add1 = add i64 %base, %ext
306  %add2 = add i64 %add1, 4095
307  %ptr = inttoptr i64 %add2 to i32 *
308  %element = load i32, i32 *%ptr
309  %ret = insertelement <4 x i32> %val, i32 %element, i32 1
310  ret <4 x i32> %ret
311}
312
313; Test a v2i64 gather of the first element.
314define <2 x i64> @f34(<2 x i64> %val, <2 x i64> %index, i64 %base) {
315; CHECK-LABEL: f34:
316; CHECK: vgeg %v24, 0(%v26,%r2), 0
317; CHECK: br %r14
318  %elem = extractelement <2 x i64> %index, i32 0
319  %add = add i64 %base, %elem
320  %ptr = inttoptr i64 %add to i64 *
321  %element = load i64, i64 *%ptr
322  %ret = insertelement <2 x i64> %val, i64 %element, i32 0
323  ret <2 x i64> %ret
324}
325
326; Test a v2i64 gather of the last element.
327define <2 x i64> @f35(<2 x i64> %val, <2 x i64> %index, i64 %base) {
328; CHECK-LABEL: f35:
329; CHECK: vgeg %v24, 0(%v26,%r2), 1
330; CHECK: br %r14
331  %elem = extractelement <2 x i64> %index, i32 1
332  %add = add i64 %base, %elem
333  %ptr = inttoptr i64 %add to i64 *
334  %element = load i64, i64 *%ptr
335  %ret = insertelement <2 x i64> %val, i64 %element, i32 1
336  ret <2 x i64> %ret
337}
338
339; Test a v2f64 gather of the first element.
340define <2 x double> @f38(<2 x double> %val, <2 x i64> %index, i64 %base) {
341; CHECK-LABEL: f38:
342; CHECK: vgeg %v24, 0(%v26,%r2), 0
343; CHECK: br %r14
344  %elem = extractelement <2 x i64> %index, i32 0
345  %add = add i64 %base, %elem
346  %ptr = inttoptr i64 %add to double *
347  %element = load double, double *%ptr
348  %ret = insertelement <2 x double> %val, double %element, i32 0
349  ret <2 x double> %ret
350}
351
352; Test a v2f64 gather of the last element.
353define <2 x double> @f39(<2 x double> %val, <2 x i64> %index, i64 %base) {
354; CHECK-LABEL: f39:
355; CHECK: vgeg %v24, 0(%v26,%r2), 1
356; CHECK: br %r14
357  %elem = extractelement <2 x i64> %index, i32 1
358  %add = add i64 %base, %elem
359  %ptr = inttoptr i64 %add to double *
360  %element = load double, double *%ptr
361  %ret = insertelement <2 x double> %val, double %element, i32 1
362  ret <2 x double> %ret
363}
364