1; Test vector extraction to memory.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
4
5; Test v16i8 extraction from the first element.
6define void @f1(<16 x i8> %val, i8 *%ptr) {
7; CHECK-LABEL: f1:
8; CHECK: vsteb %v24, 0(%r2), 0
9; CHECK: br %r14
10  %element = extractelement <16 x i8> %val, i32 0
11  store i8 %element, i8 *%ptr
12  ret void
13}
14
15; Test v16i8 extraction from the last element.
16define void @f2(<16 x i8> %val, i8 *%ptr) {
17; CHECK-LABEL: f2:
18; CHECK: vsteb %v24, 0(%r2), 15
19; CHECK: br %r14
20  %element = extractelement <16 x i8> %val, i32 15
21  store i8 %element, i8 *%ptr
22  ret void
23}
24
25; Test v16i8 extraction of an invalid element.  This must compile,
26; but we don't care what it does.
27define void @f3(<16 x i8> %val, i8 *%ptr) {
28; CHECK-LABEL: f3:
29; CHECK-NOT: vsteb %v24, 0(%r2), 16
30; CHECK: br %r14
31  %element = extractelement <16 x i8> %val, i32 16
32  store i8 %element, i8 *%ptr
33  ret void
34}
35
36; Test v16i8 extraction with the highest in-range offset.
37define void @f4(<16 x i8> %val, i8 *%base) {
38; CHECK-LABEL: f4:
39; CHECK: vsteb %v24, 4095(%r2), 10
40; CHECK: br %r14
41  %ptr = getelementptr i8, i8 *%base, i32 4095
42  %element = extractelement <16 x i8> %val, i32 10
43  store i8 %element, i8 *%ptr
44  ret void
45}
46
47; Test v16i8 extraction with the first ouf-of-range offset.
48define void @f5(<16 x i8> %val, i8 *%base) {
49; CHECK-LABEL: f5:
50; CHECK: aghi %r2, 4096
51; CHECK: vsteb %v24, 0(%r2), 5
52; CHECK: br %r14
53  %ptr = getelementptr i8, i8 *%base, i32 4096
54  %element = extractelement <16 x i8> %val, i32 5
55  store i8 %element, i8 *%ptr
56  ret void
57}
58
59; Test v16i8 extraction from a variable element.
60define void @f6(<16 x i8> %val, i8 *%ptr, i32 %index) {
61; CHECK-LABEL: f6:
62; CHECK-NOT: vsteb
63; CHECK: br %r14
64  %element = extractelement <16 x i8> %val, i32 %index
65  store i8 %element, i8 *%ptr
66  ret void
67}
68
69; Test v8i16 extraction from the first element.
70define void @f7(<8 x i16> %val, i16 *%ptr) {
71; CHECK-LABEL: f7:
72; CHECK: vsteh %v24, 0(%r2), 0
73; CHECK: br %r14
74  %element = extractelement <8 x i16> %val, i32 0
75  store i16 %element, i16 *%ptr
76  ret void
77}
78
79; Test v8i16 extraction from the last element.
80define void @f8(<8 x i16> %val, i16 *%ptr) {
81; CHECK-LABEL: f8:
82; CHECK: vsteh %v24, 0(%r2), 7
83; CHECK: br %r14
84  %element = extractelement <8 x i16> %val, i32 7
85  store i16 %element, i16 *%ptr
86  ret void
87}
88
89; Test v8i16 extraction of an invalid element.  This must compile,
90; but we don't care what it does.
91define void @f9(<8 x i16> %val, i16 *%ptr) {
92; CHECK-LABEL: f9:
93; CHECK-NOT: vsteh %v24, 0(%r2), 8
94; CHECK: br %r14
95  %element = extractelement <8 x i16> %val, i32 8
96  store i16 %element, i16 *%ptr
97  ret void
98}
99
100; Test v8i16 extraction with the highest in-range offset.
101define void @f10(<8 x i16> %val, i16 *%base) {
102; CHECK-LABEL: f10:
103; CHECK: vsteh %v24, 4094(%r2), 5
104; CHECK: br %r14
105  %ptr = getelementptr i16, i16 *%base, i32 2047
106  %element = extractelement <8 x i16> %val, i32 5
107  store i16 %element, i16 *%ptr
108  ret void
109}
110
111; Test v8i16 extraction with the first ouf-of-range offset.
112define void @f11(<8 x i16> %val, i16 *%base) {
113; CHECK-LABEL: f11:
114; CHECK: aghi %r2, 4096
115; CHECK: vsteh %v24, 0(%r2), 1
116; CHECK: br %r14
117  %ptr = getelementptr i16, i16 *%base, i32 2048
118  %element = extractelement <8 x i16> %val, i32 1
119  store i16 %element, i16 *%ptr
120  ret void
121}
122
123; Test v8i16 extraction from a variable element.
124define void @f12(<8 x i16> %val, i16 *%ptr, i32 %index) {
125; CHECK-LABEL: f12:
126; CHECK-NOT: vsteh
127; CHECK: br %r14
128  %element = extractelement <8 x i16> %val, i32 %index
129  store i16 %element, i16 *%ptr
130  ret void
131}
132
133; Test v4i32 extraction from the first element.
134define void @f13(<4 x i32> %val, i32 *%ptr) {
135; CHECK-LABEL: f13:
136; CHECK: vstef %v24, 0(%r2), 0
137; CHECK: br %r14
138  %element = extractelement <4 x i32> %val, i32 0
139  store i32 %element, i32 *%ptr
140  ret void
141}
142
143; Test v4i32 extraction from the last element.
144define void @f14(<4 x i32> %val, i32 *%ptr) {
145; CHECK-LABEL: f14:
146; CHECK: vstef %v24, 0(%r2), 3
147; CHECK: br %r14
148  %element = extractelement <4 x i32> %val, i32 3
149  store i32 %element, i32 *%ptr
150  ret void
151}
152
153; Test v4i32 extraction of an invalid element.  This must compile,
154; but we don't care what it does.
155define void @f15(<4 x i32> %val, i32 *%ptr) {
156; CHECK-LABEL: f15:
157; CHECK-NOT: vstef %v24, 0(%r2), 4
158; CHECK: br %r14
159  %element = extractelement <4 x i32> %val, i32 4
160  store i32 %element, i32 *%ptr
161  ret void
162}
163
164; Test v4i32 extraction with the highest in-range offset.
165define void @f16(<4 x i32> %val, i32 *%base) {
166; CHECK-LABEL: f16:
167; CHECK: vstef %v24, 4092(%r2), 2
168; CHECK: br %r14
169  %ptr = getelementptr i32, i32 *%base, i32 1023
170  %element = extractelement <4 x i32> %val, i32 2
171  store i32 %element, i32 *%ptr
172  ret void
173}
174
175; Test v4i32 extraction with the first ouf-of-range offset.
176define void @f17(<4 x i32> %val, i32 *%base) {
177; CHECK-LABEL: f17:
178; CHECK: aghi %r2, 4096
179; CHECK: vstef %v24, 0(%r2), 1
180; CHECK: br %r14
181  %ptr = getelementptr i32, i32 *%base, i32 1024
182  %element = extractelement <4 x i32> %val, i32 1
183  store i32 %element, i32 *%ptr
184  ret void
185}
186
187; Test v4i32 extraction from a variable element.
188define void @f18(<4 x i32> %val, i32 *%ptr, i32 %index) {
189; CHECK-LABEL: f18:
190; CHECK-NOT: vstef
191; CHECK: br %r14
192  %element = extractelement <4 x i32> %val, i32 %index
193  store i32 %element, i32 *%ptr
194  ret void
195}
196
197; Test v2i64 extraction from the first element.
198define void @f19(<2 x i64> %val, i64 *%ptr) {
199; CHECK-LABEL: f19:
200; CHECK: vsteg %v24, 0(%r2), 0
201; CHECK: br %r14
202  %element = extractelement <2 x i64> %val, i32 0
203  store i64 %element, i64 *%ptr
204  ret void
205}
206
207; Test v2i64 extraction from the last element.
208define void @f20(<2 x i64> %val, i64 *%ptr) {
209; CHECK-LABEL: f20:
210; CHECK: vsteg %v24, 0(%r2), 1
211; CHECK: br %r14
212  %element = extractelement <2 x i64> %val, i32 1
213  store i64 %element, i64 *%ptr
214  ret void
215}
216
217; Test v2i64 extraction of an invalid element.  This must compile,
218; but we don't care what it does.
219define void @f21(<2 x i64> %val, i64 *%ptr) {
220; CHECK-LABEL: f21:
221; CHECK-NOT: vsteg %v24, 0(%r2), 2
222; CHECK: br %r14
223  %element = extractelement <2 x i64> %val, i32 2
224  store i64 %element, i64 *%ptr
225  ret void
226}
227
228; Test v2i64 extraction with the highest in-range offset.
229define void @f22(<2 x i64> %val, i64 *%base) {
230; CHECK-LABEL: f22:
231; CHECK: vsteg %v24, 4088(%r2), 1
232; CHECK: br %r14
233  %ptr = getelementptr i64, i64 *%base, i32 511
234  %element = extractelement <2 x i64> %val, i32 1
235  store i64 %element, i64 *%ptr
236  ret void
237}
238
239; Test v2i64 extraction with the first ouf-of-range offset.
240define void @f23(<2 x i64> %val, i64 *%base) {
241; CHECK-LABEL: f23:
242; CHECK: aghi %r2, 4096
243; CHECK: vsteg %v24, 0(%r2), 0
244; CHECK: br %r14
245  %ptr = getelementptr i64, i64 *%base, i32 512
246  %element = extractelement <2 x i64> %val, i32 0
247  store i64 %element, i64 *%ptr
248  ret void
249}
250
251; Test v2i64 extraction from a variable element.
252define void @f24(<2 x i64> %val, i64 *%ptr, i32 %index) {
253; CHECK-LABEL: f24:
254; CHECK-NOT: vsteg
255; CHECK: br %r14
256  %element = extractelement <2 x i64> %val, i32 %index
257  store i64 %element, i64 *%ptr
258  ret void
259}
260
261; Test v4f32 extraction from the first element.
262define void @f25(<4 x float> %val, float *%ptr) {
263; CHECK-LABEL: f25:
264; CHECK: vstef %v24, 0(%r2), 0
265; CHECK: br %r14
266  %element = extractelement <4 x float> %val, i32 0
267  store float %element, float *%ptr
268  ret void
269}
270
271; Test v4f32 extraction from the last element.
272define void @f26(<4 x float> %val, float *%ptr) {
273; CHECK-LABEL: f26:
274; CHECK: vstef %v24, 0(%r2), 3
275; CHECK: br %r14
276  %element = extractelement <4 x float> %val, i32 3
277  store float %element, float *%ptr
278  ret void
279}
280
281; Test v4f32 extraction of an invalid element.  This must compile,
282; but we don't care what it does.
283define void @f27(<4 x float> %val, float *%ptr) {
284; CHECK-LABEL: f27:
285; CHECK-NOT: vstef %v24, 0(%r2), 4
286; CHECK: br %r14
287  %element = extractelement <4 x float> %val, i32 4
288  store float %element, float *%ptr
289  ret void
290}
291
292; Test v4f32 extraction with the highest in-range offset.
293define void @f28(<4 x float> %val, float *%base) {
294; CHECK-LABEL: f28:
295; CHECK: vstef %v24, 4092(%r2), 2
296; CHECK: br %r14
297  %ptr = getelementptr float, float *%base, i32 1023
298  %element = extractelement <4 x float> %val, i32 2
299  store float %element, float *%ptr
300  ret void
301}
302
303; Test v4f32 extraction with the first ouf-of-range offset.
304define void @f29(<4 x float> %val, float *%base) {
305; CHECK-LABEL: f29:
306; CHECK: aghi %r2, 4096
307; CHECK: vstef %v24, 0(%r2), 1
308; CHECK: br %r14
309  %ptr = getelementptr float, float *%base, i32 1024
310  %element = extractelement <4 x float> %val, i32 1
311  store float %element, float *%ptr
312  ret void
313}
314
315; Test v4f32 extraction from a variable element.
316define void @f30(<4 x float> %val, float *%ptr, i32 %index) {
317; CHECK-LABEL: f30:
318; CHECK-NOT: vstef
319; CHECK: br %r14
320  %element = extractelement <4 x float> %val, i32 %index
321  store float %element, float *%ptr
322  ret void
323}
324
325; Test v2f64 extraction from the first element.
326define void @f32(<2 x double> %val, double *%ptr) {
327; CHECK-LABEL: f32:
328; CHECK: vsteg %v24, 0(%r2), 0
329; CHECK: br %r14
330  %element = extractelement <2 x double> %val, i32 0
331  store double %element, double *%ptr
332  ret void
333}
334
335; Test v2f64 extraction from the last element.
336define void @f33(<2 x double> %val, double *%ptr) {
337; CHECK-LABEL: f33:
338; CHECK: vsteg %v24, 0(%r2), 1
339; CHECK: br %r14
340  %element = extractelement <2 x double> %val, i32 1
341  store double %element, double *%ptr
342  ret void
343}
344
345; Test v2f64 extraction with the highest in-range offset.
346define void @f34(<2 x double> %val, double *%base) {
347; CHECK-LABEL: f34:
348; CHECK: vsteg %v24, 4088(%r2), 1
349; CHECK: br %r14
350  %ptr = getelementptr double, double *%base, i32 511
351  %element = extractelement <2 x double> %val, i32 1
352  store double %element, double *%ptr
353  ret void
354}
355
356; Test v2f64 extraction with the first ouf-of-range offset.
357define void @f35(<2 x double> %val, double *%base) {
358; CHECK-LABEL: f35:
359; CHECK: aghi %r2, 4096
360; CHECK: vsteg %v24, 0(%r2), 0
361; CHECK: br %r14
362  %ptr = getelementptr double, double *%base, i32 512
363  %element = extractelement <2 x double> %val, i32 0
364  store double %element, double *%ptr
365  ret void
366}
367
368; Test v2f64 extraction from a variable element.
369define void @f36(<2 x double> %val, double *%ptr, i32 %index) {
370; CHECK-LABEL: f36:
371; CHECK-NOT: vsteg
372; CHECK: br %r14
373  %element = extractelement <2 x double> %val, i32 %index
374  store double %element, double *%ptr
375  ret void
376}
377
378; Test a v4i32 scatter of the first element.
379define void @f37(<4 x i32> %val, <4 x i32> %index, i64 %base) {
380; CHECK-LABEL: f37:
381; CHECK: vscef %v24, 0(%v26,%r2), 0
382; CHECK: br %r14
383  %elem = extractelement <4 x i32> %index, i32 0
384  %ext = zext i32 %elem to i64
385  %add = add i64 %base, %ext
386  %ptr = inttoptr i64 %add to i32 *
387  %element = extractelement <4 x i32> %val, i32 0
388  store i32 %element, i32 *%ptr
389  ret void
390}
391
392; Test a v4i32 scatter of the last element.
393define void @f38(<4 x i32> %val, <4 x i32> %index, i64 %base) {
394; CHECK-LABEL: f38:
395; CHECK: vscef %v24, 0(%v26,%r2), 3
396; CHECK: br %r14
397  %elem = extractelement <4 x i32> %index, i32 3
398  %ext = zext i32 %elem to i64
399  %add = add i64 %base, %ext
400  %ptr = inttoptr i64 %add to i32 *
401  %element = extractelement <4 x i32> %val, i32 3
402  store i32 %element, i32 *%ptr
403  ret void
404}
405
406; Test a v4i32 scatter with the highest in-range offset.
407define void @f39(<4 x i32> %val, <4 x i32> %index, i64 %base) {
408; CHECK-LABEL: f39:
409; CHECK: vscef %v24, 4095(%v26,%r2), 1
410; CHECK: br %r14
411  %elem = extractelement <4 x i32> %index, i32 1
412  %ext = zext i32 %elem to i64
413  %add1 = add i64 %base, %ext
414  %add2 = add i64 %add1, 4095
415  %ptr = inttoptr i64 %add2 to i32 *
416  %element = extractelement <4 x i32> %val, i32 1
417  store i32 %element, i32 *%ptr
418  ret void
419}
420
421; Test a v2i64 scatter of the first element.
422define void @f40(<2 x i64> %val, <2 x i64> %index, i64 %base) {
423; CHECK-LABEL: f40:
424; CHECK: vsceg %v24, 0(%v26,%r2), 0
425; CHECK: br %r14
426  %elem = extractelement <2 x i64> %index, i32 0
427  %add = add i64 %base, %elem
428  %ptr = inttoptr i64 %add to i64 *
429  %element = extractelement <2 x i64> %val, i32 0
430  store i64 %element, i64 *%ptr
431  ret void
432}
433
434; Test a v2i64 scatter of the last element.
435define void @f41(<2 x i64> %val, <2 x i64> %index, i64 %base) {
436; CHECK-LABEL: f41:
437; CHECK: vsceg %v24, 0(%v26,%r2), 1
438; CHECK: br %r14
439  %elem = extractelement <2 x i64> %index, i32 1
440  %add = add i64 %base, %elem
441  %ptr = inttoptr i64 %add to i64 *
442  %element = extractelement <2 x i64> %val, i32 1
443  store i64 %element, i64 *%ptr
444  ret void
445}
446
447; Test a v4f32 scatter of the first element.
448define void @f42(<4 x float> %val, <4 x i32> %index, i64 %base) {
449; CHECK-LABEL: f42:
450; CHECK: vscef %v24, 0(%v26,%r2), 0
451; CHECK: br %r14
452  %elem = extractelement <4 x i32> %index, i32 0
453  %ext = zext i32 %elem to i64
454  %add = add i64 %base, %ext
455  %ptr = inttoptr i64 %add to float *
456  %element = extractelement <4 x float> %val, i32 0
457  store float %element, float *%ptr
458  ret void
459}
460
461; Test a v4f32 scatter of the last element.
462define void @f43(<4 x float> %val, <4 x i32> %index, i64 %base) {
463; CHECK-LABEL: f43:
464; CHECK: vscef %v24, 0(%v26,%r2), 3
465; CHECK: br %r14
466  %elem = extractelement <4 x i32> %index, i32 3
467  %ext = zext i32 %elem to i64
468  %add = add i64 %base, %ext
469  %ptr = inttoptr i64 %add to float *
470  %element = extractelement <4 x float> %val, i32 3
471  store float %element, float *%ptr
472  ret void
473}
474
475; Test a v2f64 scatter of the first element.
476define void @f44(<2 x double> %val, <2 x i64> %index, i64 %base) {
477; CHECK-LABEL: f44:
478; CHECK: vsceg %v24, 0(%v26,%r2), 0
479; CHECK: br %r14
480  %elem = extractelement <2 x i64> %index, i32 0
481  %add = add i64 %base, %elem
482  %ptr = inttoptr i64 %add to double *
483  %element = extractelement <2 x double> %val, i32 0
484  store double %element, double *%ptr
485  ret void
486}
487
488; Test a v2f64 scatter of the last element.
489define void @f45(<2 x double> %val, <2 x i64> %index, i64 %base) {
490; CHECK-LABEL: f45:
491; CHECK: vsceg %v24, 0(%v26,%r2), 1
492; CHECK: br %r14
493  %elem = extractelement <2 x i64> %index, i32 1
494  %add = add i64 %base, %elem
495  %ptr = inttoptr i64 %add to double *
496  %element = extractelement <2 x double> %val, i32 1
497  store double %element, double *%ptr
498  ret void
499}
500