Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / SystemZ / call-zos-vararg.ll
blobbde59a6be782277b9292f14f8b923763371bebcf
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 ; CHECK-LABEL: call_vararg_both0:
92 ; CHECK:         stmg 6, 7, 1872(4)
93 ; CHECK-NEXT:    aghi 4, -192
94 ; CHECK-NEXT:    lg 6, 40(5)
95 ; CHECK-NEXT:    lg 5, 32(5)
96 ; CHECK-NEXT:    lgr 2, 1
97 ; CHECK-NEXT:    lgdr 1, 0
98 ; CHECK-NEXT:    basr 7, 6
99 ; CHECK-NEXT:    bcr 0, 0
100 ; CHECK-NEXT:    lg 7, 2072(4)
101 ; CHECK-NEXT:    aghi 4, 192
102 ; CHECK-NEXT:    b 2(7)
103 define i64 @call_vararg_both0(i64 %arg0, double %arg1) {
104   %retval  = call i64(...) @pass_vararg3(double %arg1, i64 %arg0)
105   ret i64 %retval
108 ; CHECK-LABEL: call_vararg_long_double0:
109 ; CHECK:         stmg 6, 7, 1872(4)
110 ; CHECK-NEXT:    aghi 4, -192
111 ; CHECK-NEXT:    larl 1, @CPI5_0
112 ; CHECK-NEXT:    ld 0, 0(1)
113 ; CHECK-NEXT:    ld 2, 8(1)
114 ; CHECK-NEXT:    lg 6, 8(5)
115 ; CHECK-NEXT:    lg 5, 0(5)
116 ; CHECK-NEXT:    lgdr 3, 0
117 ; CHECK-NEXT:    lghi 1, 1
118 ; CHECK-NEXT:    lghi 2, 2
119 ; CHECK-NEXT:    std 0, 2192(4)
120 ; CHECK-NEXT:    std 2, 2200(4)
121 ; CHECK-NEXT:    basr 7, 6
122 ; CHECK-NEXT:    bcr 0, 0
123 ; CHECK-NEXT:    lg 7, 2072(4)
124 ; CHECK-NEXT:    aghi 4, 192
125 ; CHECK-NEXT:    b 2(7)
126 define i64 @call_vararg_long_double0() {
127 entry:
128   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 0xLE0FC1518450562CD4000921FB5444261)
129   ret i64 %retval
132 ; CHECK-LABEL: call_vararg_long_double1:
133 ; CHECK:         stmg 6, 7, 1872(4)
134 ; CHECK-NEXT:    aghi 4, -192
135 ; CHECK-NEXT:    lg 6, 8(5)
136 ; CHECK-NEXT:    lg 5, 0(5)
137 ; CHECK-NEXT:    lgdr 3, 0
138 ; CHECK-NEXT:    lghi 1, 1
139 ; CHECK-NEXT:    lghi 2, 2
140 ; CHECK-NEXT:    std 0, 2192(4)
141 ; CHECK-NEXT:    std 2, 2200(4)
142 ; CHECK-NEXT:    basr 7, 6
143 ; CHECK-NEXT:    bcr 0, 0
144 ; CHECK-NEXT:    lg 7, 2072(4)
145 ; CHECK-NEXT:    aghi 4, 192
146 ; CHECK-NEXT:    b 2(7)
147 define i64 @call_vararg_long_double1(fp128 %arg0) {
148 entry:
149   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0)
150   ret i64 %retval
153 ; CHECK-LABEL: call_vararg_long_double2
154 ; CHECK-LABEL: call_vararg_long_double2:
155 ; CHECK:         stmg 6, 7, 1872(4)
156 ; CHECK-NEXT:    aghi 4, -192
157 ; CHECK-NEXT:    std 4, 2208(4)
158 ; CHECK-NEXT:    std 6, 2216(4)
159 ; CHECK-NEXT:    lg 6, 8(5)
160 ; CHECK-NEXT:    lg 5, 0(5)
161 ; CHECK-NEXT:    lgdr 3, 0
162 ; CHECK-NEXT:    lghi 1, 1
163 ; CHECK-NEXT:    lghi 2, 2
164 ; CHECK-NEXT:    std 0, 2192(4)
165 ; CHECK-NEXT:    std 2, 2200(4)
166 ; CHECK-NEXT:    basr 7, 6
167 ; CHECK-NEXT:    bcr 0, 0
168 ; CHECK-NEXT:    lg 7, 2072(4)
169 ; CHECK-NEXT:    aghi 4, 192
170 ; CHECK-NEXT:    b 2(7)
171 define i64 @call_vararg_long_double2(fp128 %arg0, fp128 %arg1) {
172 entry:
173   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0, fp128 %arg1)
174   ret i64 %retval
177 ; CHECK-LABEL: call_vararg_long_double3:
178 ; CHECK:         stmg 6, 7, 1872(4)
179 ; CHECK-NEXT:    aghi 4, -192
180 ; CHECK-NEXT:    lg 6, 40(5)
181 ; CHECK-NEXT:    lg 5, 32(5)
182 ; CHECK-NEXT:    lgdr 3, 2
183 ; CHECK-NEXT:    lgdr 2, 0
184 ; CHECK-NEXT:    basr 7, 6
185 ; CHECK-NEXT:    bcr 0, 0
186 ; CHECK-NEXT:    lg 7, 2072(4)
187 ; CHECK-NEXT:    aghi 4, 192
188 ; CHECK-NEXT:    b 2(7)
189 define i64 @call_vararg_long_double3(fp128 %arg0) {
190 entry:
191   %retval = call i64 (...) @pass_vararg3(fp128 %arg0)
192   ret i64 %retval
195 ; ARCH12-LABEL: call_vec_vararg_test0
196 ; ARCH12: vlgvg 3, 24, 1
197 ; ARCH12: vlgvg 2, 24, 0
198 ; ARCH12: lghi  1, 1
199 define void @call_vec_vararg_test0(<2 x double> %v) {
200   %retval = call i64(i64, ...) @pass_vararg2(i64 1, <2 x double> %v)
201   ret void
204 ; ARCH12-LABEL: call_vec_vararg_test1
205 ; ARCH12: larl  1, @CPI10_0
206 ; ARCH12: vl    0, 0(1), 3
207 ; ARCH12: vlgvg 3, 24, 0
208 ; ARCH12: vrepg 2, 0, 1
209 ; ARCH12: vst   25, 2208(4), 3
210 ; ARCH12: vst   24, 2192(4), 3
211 define void @call_vec_vararg_test1(<4 x i32> %v, <2 x i64> %w) {
212   %retval = call i64(fp128, ...) @pass_vararg1(fp128 0xLE0FC1518450562CD4000921FB5444261, <4 x i32> %v, <2 x i64> %w)
213   ret void
216 ; ARCH12-LABEL: call_vec_char_vararg_straddle
217 ; ARCH12: vlgvg 3, 24, 0
218 ; ARCH12: lghi  1, 1
219 ; ARCH12: lghi  2, 2
220 ; ARCH12: vst   24, 2192(4), 3
221 define void @call_vec_char_vararg_straddle(<16 x i8> %v) {
222   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <16 x i8> %v)
223   ret void
226 ; ARCH12-LABEL: call_vec_short_vararg_straddle
227 ; ARCH12: vlgvg 3, 24, 0
228 ; ARCH12: lghi  1, 1
229 ; ARCH12: lghi  2, 2
230 ; ARCH12: vst   24, 2192(4), 3
231 define void @call_vec_short_vararg_straddle(<8 x i16> %v) {
232   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <8 x i16> %v)
233   ret void
236 ; ARCH12-LABEL: call_vec_int_vararg_straddle
237 ; ARCH12: vlgvg 3, 24, 0
238 ; ARCH12: lghi  1, 1
239 ; ARCH12: lghi  2, 2
240 ; ARCH12: vst 24, 2192(4), 3
241 define void @call_vec_int_vararg_straddle(<4 x i32> %v) {
242   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <4 x i32> %v)
243   ret void
246 ; ARCH12-LABEL: call_vec_double_vararg_straddle
247 ; ARCH12: vlgvg 3, 24, 0
248 ; ARCH12: lghi  1, 1
249 ; ARCH12: lghi  2, 2
250 ; ARCH12: vst 24, 2192(4), 3
251 define void @call_vec_double_vararg_straddle(<2 x double> %v) {
252   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <2 x double> %v)
253   ret void
256 ; CHECK-LABEL: call_vararg_integral0:
257 ; CHECK:         stmg 6, 7, 1872(4)
258 ; CHECK-NEXT:    aghi 4, -192
259 ; CHECK-NEXT:    lg 0, 2392(4)
260 ; CHECK-NEXT:    lg 6, 40(5)
261 ; CHECK-NEXT:    lg 5, 32(5)
262 ; CHECK-NEXT:    stg 0, 2200(4)
263 ; CHECK-NEXT:    basr 7, 6
264 ; CHECK-NEXT:    bcr 0, 0
265 ; CHECK-NEXT:    lg 7, 2072(4)
266 ; CHECK-NEXT:    aghi 4, 192
267 ; CHECK-NEXT:    b 2(7)
268 define i64 @call_vararg_integral0(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3) {
269 entry:
270   %retval = call i64(...) @pass_vararg3(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3)
271   ret i64 %retval
274 ; CHECK-LABEL: call_vararg_float0:
275 ; CHECK:         stmg 6, 7, 1872(4)
276 ; CHECK-NEXT:    aghi 4, -192
277 ; CHECK-NEXT:    lg 6, 24(5)
278 ; CHECK-NEXT:    lg 5, 16(5)
279 ; CHECK-NEXT:    lghi 1, 1
280 ; CHECK-NEXT:    llihf 2, 1073692672
281 ; CHECK-NEXT:    basr 7, 6
282 ; CHECK-NEXT:    bcr 0, 0
283 ; CHECK-NEXT:    lg 7, 2072(4)
284 ; CHECK-NEXT:    aghi 4, 192
285 ; CHECK-NEXT:    b 2(7)
286 define i64 @call_vararg_float0() {
287 entry:
288   %retval = call i64 (i64, ...) @pass_vararg2(i64 1, float 1.953125)
289   ret i64 %retval
292 ; CHECK-LABEL: call_vararg_float1:
293 ; CHECK:         stmg 6, 7, 1872(4)
294 ; CHECK-NEXT:    aghi 4, -192
295 ; CHECK-NEXT:    lg 6, 72(5)
296 ; CHECK-NEXT:    lg 5, 64(5)
297 ; CHECK-NEXT:    larl 1, @CPI17_0
298 ; CHECK-NEXT:    le 0, 0(1)
299 ; CHECK-NEXT:    llihf 0, 1073692672
300 ; CHECK-NEXT:    llihh 2, 16384
301 ; CHECK-NEXT:    llihh 3, 16392
302 ; CHECK-NEXT:    stg 0, 2200(4)
303 ; CHECK-NEXT:    basr 7, 6
304 ; CHECK-NEXT:    bcr 0, 0
305 ; CHECK-NEXT:    lg 7, 2072(4)
306 ; CHECK-NEXT:    aghi 4, 192
307 ; CHECK-NEXT:    b 2(7)
308 define i64 @call_vararg_float1() {
309 entry:
310   %retval = call i64 (float, ...) @pass_vararg4(float 1.0, float 2.0, float 3.0, float 1.953125)
311   ret i64 %retval
314 ; Derived from C source:
315 ; #define _VARARG_EXT_
316 ; #include <stdarg.h>
318 ; long pass(long x, ...) {
319 ;   va_list va;
320 ;   va_start(va, x);
321 ;   long ret = va_arg(va, long);
322 ;   va_end(va);
323 ;   return ret;
324 ; }
326 ; CHECK-LABEL: pass_vararg:
327 ; CHECK:         stmg 6, 7, 1904(4)
328 ; CHECK-NEXT:    aghi 4, -160
329 ; CHECK-NEXT:    stg 2, 2344(4)
330 ; CHECK-NEXT:    stg 3, 2352(4)
331 ; CHECK-NEXT:    la 0, 2352(4)
332 ; CHECK-NEXT:    stg 0, 2200(4)
333 ; CHECK-NEXT:    lg 3, 2344(4)
334 ; CHECK-NEXT:    lg 7, 2072(4)
335 ; CHECK-NEXT:    aghi 4, 160
336 ; CHECK-NEXT:    b 2(7)
337 define hidden i64 @pass_vararg(i64 %x, ...) {
338 entry:
339   %va = alloca ptr, align 8
340   call void @llvm.va_start(ptr %va)
341   %argp.cur = load ptr, ptr %va, align 8
342   %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8
343   store ptr %argp.next, ptr %va, align 8
344   %ret = load i64, ptr %argp.cur, align 8
345   call void @llvm.va_end(ptr %va)
346   ret i64 %ret
349 declare void @llvm.va_start(ptr)
350 declare void @llvm.va_end(ptr)
352 declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...)
353 declare i64 @pass_vararg1(fp128 %arg0, ...)
354 declare i64 @pass_vararg2(i64 %arg0, ...)
355 declare i64 @pass_vararg3(...)
356 declare i64 @pass_vararg4(float, ...)