[X86] combineTargetShuffle - commute VPERMV3 shuffles so any load is on the RHS
[llvm-project.git] / llvm / test / CodeGen / SystemZ / call-zos-vararg.ll
blob72f4d79610e0e43205930d48e3e1af4f95a1fff1
1 ; Test passing variable argument lists in 64-bit calls on z/OS.
2 ; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z10 | FileCheck %s
3 ; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z14 | FileCheck %s -check-prefix=ARCH12
4 ; CHECK-LABEL: call_vararg_double0:
5 ; CHECK:         stmg 6,7,1872(4)
6 ; CHECK-NEXT:    aghi 4,-192
7 ; CHECK-NEXT:    lg 6,8(5)
8 ; CHECK-NEXT:    lg 5,0(5)
9 ; CHECK-NEXT:    llihf 3,1074118262
10 ; CHECK-NEXT:    oilf 3,3367254360
11 ; CHECK-NEXT:    lghi 1,1
12 ; CHECK-NEXT:    lghi 2,2
13 ; CHECK-NEXT:    basr 7,6
14 ; CHECK-NEXT:    bcr 0,0
15 ; CHECK-NEXT:    lg 7,2072(4)
16 ; CHECK-NEXT:    aghi 4,192
17 ; CHECK-NEXT:    b 2(7)
18 define i64 @call_vararg_double0() {
19 entry:
20   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 2.718000e+00)
21   ret i64 %retval
24 ; CHECK-LABEL: call_vararg_double1:
25 ; CHECK:         stmg 6,7,1872(4)
26 ; CHECK-NEXT:    aghi 4,-192
27 ; CHECK-NEXT:    llihf 0,1074118262
28 ; CHECK-NEXT:    oilf 0,3367254360
29 ; CHECK-NEXT:    lg 6,8(5)
30 ; CHECK-NEXT:    lg 5,0(5)
31 ; CHECK-NEXT:    llihf 3,1074340036
32 ; CHECK-NEXT:    oilf 3,2611340116
33 ; CHECK-NEXT:    lghi 1,1
34 ; CHECK-NEXT:    lghi 2,2
35 ; CHECK-NEXT:    stg 0,2200(4)
36 ; CHECK-NEXT:    basr 7,6
37 ; CHECK-NEXT:    bcr 0,0
38 ; CHECK-NEXT:    lg 7,2072(4)
39 ; CHECK-NEXT:    aghi 4,192
40 ; CHECK-NEXT:    b 2(7)
41 define i64 @call_vararg_double1() {
42 entry:
43   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 3.141000e+00, double 2.718000e+00)
44   ret i64 %retval
47 ; CHECK-LABEL: call_vararg_double2:
48 ; CHECK:         stmg 6,7,1872(4)
49 ; CHECK-NEXT:    aghi 4,-192
50 ; CHECK-NEXT:    lg 6,24(5)
51 ; CHECK-NEXT:    lg 5,16(5)
52 ; CHECK-NEXT:    llihf 2,1074118262
53 ; CHECK-NEXT:    oilf 2,3367254360
54 ; CHECK-NEXT:    lghi 1,8200
55 ; CHECK-NEXT:    basr 7,6
56 ; CHECK-NEXT:    bcr 0,0
57 ; CHECK-NEXT:    lg 7,2072(4)
58 ; CHECK-NEXT:    aghi 4,192
59 ; CHECK-NEXT:    b 2(7)
60 define i64 @call_vararg_double2() {
61 entry:
62   %retval = call i64 (i64, ...) @pass_vararg2(i64 8200, double 2.718000e+00)
63   ret i64 %retval
66 ; CHECK-LABEL: call_vararg_double3:
67 ; CHECK:         stmg 6,7,1872(4)
68 ; CHECK-NEXT:    aghi 4,-192
69 ; CHECK-NEXT:    llihf 0,1072703839
70 ; CHECK-NEXT:    oilf 0,2861204133
71 ; CHECK-NEXT:    lg 6,40(5)
72 ; CHECK-NEXT:    lg 5,32(5)
73 ; CHECK-NEXT:    llihf 1,1074118262
74 ; CHECK-NEXT:    oilf 1,3367254360
75 ; CHECK-NEXT:    llihf 2,1074340036
76 ; CHECK-NEXT:    oilf 2,2611340116
77 ; CHECK-NEXT:    llihf 3,1073127358
78 ; CHECK-NEXT:    oilf 3,1992864825
79 ; CHECK-NEXT:    stg 0,2200(4)
80 ; CHECK-NEXT:    basr 7,6
81 ; CHECK-NEXT:    bcr 0,0
82 ; CHECK-NEXT:    lg 7,2072(4)
83 ; CHECK-NEXT:    aghi 4,192
84 ; CHECK-NEXT:    b 2(7)
85 define i64 @call_vararg_double3() {
86 entry:
87   %retval = call i64 (...) @pass_vararg3(double 2.718000e+00, double 3.141000e+00, double 1.414000e+00, double 1.010101e+00)
88   ret i64 %retval
91 ;; TODO: The extra COPY after LGDR is unnecessary (machine-scheduler introduces the overlap).
92 ; CHECK-LABEL: call_vararg_both0:
93 ; CHECK:         stmg 6,7,1872(4)
94 ; CHECK-NEXT:    aghi 4,-192
95 ; CHECK-NEXT:    lg 6,40(5)
96 ; CHECK-NEXT:    lg 5,32(5)
97 ; CHECK-NEXT:    lgdr 0,0
98 ; CHECK-NEXT:    lgr 2,1
99 ; CHECK-NEXT:    lgr 1,0
100 ; CHECK-NEXT:    basr 7,6
101 ; CHECK-NEXT:    bcr 0,0
102 ; CHECK-NEXT:    lg 7,2072(4)
103 ; CHECK-NEXT:    aghi 4,192
104 ; CHECK-NEXT:    b 2(7)
105 define i64 @call_vararg_both0(i64 %arg0, double %arg1) {
106   %retval  = call i64(...) @pass_vararg3(double %arg1, i64 %arg0)
107   ret i64 %retval
110 ; CHECK-LABEL: call_vararg_long_double0:
111 ; CHECK:         stmg 6,7,1872(4)
112 ; CHECK-NEXT:    aghi 4,-192
113 ; CHECK-NEXT:    larl 1,L#CPI5_0
114 ; CHECK-NEXT:    ld 0,0(1)
115 ; CHECK-NEXT:    ld 2,8(1)
116 ; CHECK-NEXT:    lg 6,8(5)
117 ; CHECK-NEXT:    lg 5,0(5)
118 ; CHECK-NEXT:    lgdr 3,0
119 ; CHECK-NEXT:    lghi 1,1
120 ; CHECK-NEXT:    lghi 2,2
121 ; CHECK-NEXT:    std 0,2192(4)
122 ; CHECK-NEXT:    std 2,2200(4)
123 ; CHECK-NEXT:    basr 7,6
124 ; CHECK-NEXT:    bcr 0,0
125 ; CHECK-NEXT:    lg 7,2072(4)
126 ; CHECK-NEXT:    aghi 4,192
127 ; CHECK-NEXT:    b 2(7)
128 define i64 @call_vararg_long_double0() {
129 entry:
130   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 0xLE0FC1518450562CD4000921FB5444261)
131   ret i64 %retval
134 ; CHECK-LABEL: call_vararg_long_double1:
135 ; CHECK:         stmg 6,7,1872(4)
136 ; CHECK-NEXT:    aghi 4,-192
137 ; CHECK-NEXT:    lg 6,8(5)
138 ; CHECK-NEXT:    lg 5,0(5)
139 ; CHECK-NEXT:    lgdr 3,0
140 ; CHECK-NEXT:    lghi 1,1
141 ; CHECK-NEXT:    lghi 2,2
142 ; CHECK-NEXT:    std 0,2192(4)
143 ; CHECK-NEXT:    std 2,2200(4)
144 ; CHECK-NEXT:    basr 7,6
145 ; CHECK-NEXT:    bcr 0,0
146 ; CHECK-NEXT:    lg 7,2072(4)
147 ; CHECK-NEXT:    aghi 4,192
148 ; CHECK-NEXT:    b 2(7)
149 define i64 @call_vararg_long_double1(fp128 %arg0) {
150 entry:
151   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0)
152   ret i64 %retval
155 ; CHECK-LABEL: call_vararg_long_double2
156 ; CHECK-LABEL: call_vararg_long_double2:
157 ; CHECK:         stmg 6,7,1872(4)
158 ; CHECK-NEXT:    aghi 4,-192
159 ; CHECK-NEXT:    std 4,2208(4)
160 ; CHECK-NEXT:    std 6,2216(4)
161 ; CHECK-NEXT:    lg 6,8(5)
162 ; CHECK-NEXT:    lg 5,0(5)
163 ; CHECK-NEXT:    lgdr 3,0
164 ; CHECK-NEXT:    lghi 1,1
165 ; CHECK-NEXT:    lghi 2,2
166 ; CHECK-NEXT:    std 0,2192(4)
167 ; CHECK-NEXT:    std 2,2200(4)
168 ; CHECK-NEXT:    basr 7,6
169 ; CHECK-NEXT:    bcr 0,0
170 ; CHECK-NEXT:    lg 7,2072(4)
171 ; CHECK-NEXT:    aghi 4,192
172 ; CHECK-NEXT:    b 2(7)
173 define i64 @call_vararg_long_double2(fp128 %arg0, fp128 %arg1) {
174 entry:
175   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0, fp128 %arg1)
176   ret i64 %retval
179 ; CHECK-LABEL: call_vararg_long_double3:
180 ; CHECK:         stmg 6,7,1872(4)
181 ; CHECK-NEXT:    aghi 4,-192
182 ; CHECK-NEXT:    lg 6,40(5)
183 ; CHECK-NEXT:    lg 5,32(5)
184 ; CHECK-NEXT:    lgdr 3,2
185 ; CHECK-NEXT:    lgdr 2,0
186 ; CHECK-NEXT:    basr 7,6
187 ; CHECK-NEXT:    bcr 0,0
188 ; CHECK-NEXT:    lg 7,2072(4)
189 ; CHECK-NEXT:    aghi 4,192
190 ; CHECK-NEXT:    b 2(7)
191 define i64 @call_vararg_long_double3(fp128 %arg0) {
192 entry:
193   %retval = call i64 (...) @pass_vararg3(fp128 %arg0)
194   ret i64 %retval
197 ; ARCH12-LABEL: call_vec_vararg_test0
198 ; ARCH12: vlgvg 3,24,1
199 ; ARCH12: vlgvg 2,24,0
200 ; ARCH12: lghi  1,1
201 define void @call_vec_vararg_test0(<2 x double> %v) {
202   %retval = call i64(i64, ...) @pass_vararg2(i64 1, <2 x double> %v)
203   ret void
206 ; ARCH12-LABEL: call_vec_vararg_test1
207 ; ARCH12: larl  1,L#CPI10_0
208 ; ARCH12: vl    0,0(1),3
209 ; ARCH12: vlgvg 3,24,0
210 ; ARCH12: vrepg 2,0,1
211 ; ARCH12: vst   25,2208(4),3
212 ; ARCH12: vst   24,2192(4),3
213 define void @call_vec_vararg_test1(<4 x i32> %v, <2 x i64> %w) {
214   %retval = call i64(fp128, ...) @pass_vararg1(fp128 0xLE0FC1518450562CD4000921FB5444261, <4 x i32> %v, <2 x i64> %w)
215   ret void
218 ; ARCH12-LABEL: call_vec_char_vararg_straddle
219 ; ARCH12: vlgvg 3,24,0
220 ; ARCH12: lghi  1,1
221 ; ARCH12: lghi  2,2
222 ; ARCH12: vst   24,2192(4),3
223 define void @call_vec_char_vararg_straddle(<16 x i8> %v) {
224   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <16 x i8> %v)
225   ret void
228 ; ARCH12-LABEL: call_vec_short_vararg_straddle
229 ; ARCH12: vlgvg 3,24,0
230 ; ARCH12: lghi  1,1
231 ; ARCH12: lghi  2,2
232 ; ARCH12: vst   24,2192(4),3
233 define void @call_vec_short_vararg_straddle(<8 x i16> %v) {
234   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <8 x i16> %v)
235   ret void
238 ; ARCH12-LABEL: call_vec_int_vararg_straddle
239 ; ARCH12: vlgvg 3,24,0
240 ; ARCH12: lghi  1,1
241 ; ARCH12: lghi  2,2
242 ; ARCH12: vst 24,2192(4),3
243 define void @call_vec_int_vararg_straddle(<4 x i32> %v) {
244   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <4 x i32> %v)
245   ret void
248 ; ARCH12-LABEL: call_vec_double_vararg_straddle
249 ; ARCH12: vlgvg 3,24,0
250 ; ARCH12: lghi  1,1
251 ; ARCH12: lghi  2,2
252 ; ARCH12: vst 24,2192(4),3
253 define void @call_vec_double_vararg_straddle(<2 x double> %v) {
254   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <2 x double> %v)
255   ret void
258 ; CHECK-LABEL: call_vararg_integral0:
259 ; CHECK:         stmg 6,7,1872(4)
260 ; CHECK-NEXT:    aghi 4,-192
261 ; CHECK-NEXT:    lg 0,2392(4)
262 ; CHECK-NEXT:    lg 6,40(5)
263 ; CHECK-NEXT:    lg 5,32(5)
264 ; CHECK-NEXT:    stg 0,2200(4)
265 ; CHECK-NEXT:    basr 7,6
266 ; CHECK-NEXT:    bcr 0,0
267 ; CHECK-NEXT:    lg 7,2072(4)
268 ; CHECK-NEXT:    aghi 4,192
269 ; CHECK-NEXT:    b 2(7)
270 define i64 @call_vararg_integral0(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3) {
271 entry:
272   %retval = call i64(...) @pass_vararg3(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3)
273   ret i64 %retval
276 ; CHECK-LABEL: call_vararg_float0:
277 ; CHECK:         stmg 6,7,1872(4)
278 ; CHECK-NEXT:    aghi 4,-192
279 ; CHECK-NEXT:    lg 6,24(5)
280 ; CHECK-NEXT:    lg 5,16(5)
281 ; CHECK-NEXT:    lghi 1,1
282 ; CHECK-NEXT:    llihf 2,1073692672
283 ; CHECK-NEXT:    basr 7,6
284 ; CHECK-NEXT:    bcr 0,0
285 ; CHECK-NEXT:    lg 7,2072(4)
286 ; CHECK-NEXT:    aghi 4,192
287 ; CHECK-NEXT:    b 2(7)
288 define i64 @call_vararg_float0() {
289 entry:
290   %retval = call i64 (i64, ...) @pass_vararg2(i64 1, float 1.953125)
291   ret i64 %retval
294 ; CHECK-LABEL: call_vararg_float1:
295 ; CHECK:         stmg 6,7,1872(4)
296 ; CHECK-NEXT:    aghi 4,-192
297 ; CHECK-NEXT:    lg 6,72(5)
298 ; CHECK-NEXT:    lg 5,64(5)
299 ; CHECK-NEXT:    larl 1,L#CPI17_0
300 ; CHECK-NEXT:    le 0,0(1)
301 ; CHECK-NEXT:    llihf 0,1073692672
302 ; CHECK-NEXT:    llihh 2,16384
303 ; CHECK-NEXT:    llihh 3,16392
304 ; CHECK-NEXT:    stg 0,2200(4)
305 ; CHECK-NEXT:    basr 7,6
306 ; CHECK-NEXT:    bcr 0,0
307 ; CHECK-NEXT:    lg 7,2072(4)
308 ; CHECK-NEXT:    aghi 4,192
309 ; CHECK-NEXT:    b 2(7)
310 define i64 @call_vararg_float1() {
311 entry:
312   %retval = call i64 (float, ...) @pass_vararg4(float 1.0, float 2.0, float 3.0, float 1.953125)
313   ret i64 %retval
316 ; Derived from C source:
317 ; #define _VARARG_EXT_
318 ; #include <stdarg.h>
320 ; long pass(long x, ...) {
321 ;   va_list va;
322 ;   va_start(va, x);
323 ;   long ret = va_arg(va, long);
324 ;   va_end(va);
325 ;   return ret;
326 ; }
328 ; CHECK-LABEL: pass_vararg:
329 ; CHECK:         stmg 6,7,1904(4)
330 ; CHECK-NEXT:    aghi 4,-160
331 ; CHECK-NEXT:    stg 2,2344(4)
332 ; CHECK-NEXT:    stg 3,2352(4)
333 ; CHECK-NEXT:    la 0,2352(4)
334 ; CHECK-NEXT:    stg 0,2200(4)
335 ; CHECK-NEXT:    lg 3,2344(4)
336 ; CHECK-NEXT:    lg 7,2072(4)
337 ; CHECK-NEXT:    aghi 4,160
338 ; CHECK-NEXT:    b 2(7)
339 define hidden i64 @pass_vararg(i64 %x, ...) {
340 entry:
341   %va = alloca ptr, align 8
342   call void @llvm.va_start(ptr %va)
343   %argp.cur = load ptr, ptr %va, align 8
344   %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8
345   store ptr %argp.next, ptr %va, align 8
346   %ret = load i64, ptr %argp.cur, align 8
347   call void @llvm.va_end(ptr %va)
348   ret i64 %ret
351 declare void @llvm.va_start(ptr)
352 declare void @llvm.va_end(ptr)
354 declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...)
355 declare i64 @pass_vararg1(fp128 %arg0, ...)
356 declare i64 @pass_vararg2(i64 %arg0, ...)
357 declare i64 @pass_vararg3(...)
358 declare i64 @pass_vararg4(float, ...)