Revert rGe6ccb57bb3f6b761f2310e97fd6ca99eff42f73e "[SLP] Add cost model for `llvm...
[llvm-project.git] / llvm / test / CodeGen / SystemZ / call-zos-vararg.ll
blob2af2c29c1d53fa9b6ec6cedafe36eb2e0527e220
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:       llihf 3, 1074118262
6 ; CHECK-NEXT:  oilf  3, 3367254360
7 ; CHECK:       lghi  1, 1
8 ; CHECK:       lghi  2, 2
9 define i64 @call_vararg_double0() {
10 entry:
11   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 2.718000e+00)
12   ret i64 %retval
15 ; CHECK-LABEL:  call_vararg_double1
16 ; CHECK:        llihf 0, 1074118262
17 ; CHECK-NEXT:   oilf  0, 3367254360
18 ; CHECK:        llihf 3, 1074340036
19 ; CHECK-NEXT:   oilf  3, 2611340116
20 ; CHECK:        lghi  1, 1
21 ; CHECK:        lghi  2, 2
22 ; CHECK:        stg 0, 2200(4)
23 define i64 @call_vararg_double1() {
24 entry:
25   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 3.141000e+00, double 2.718000e+00)
26   ret i64 %retval
29 ; CHECK-LABEL: call_vararg_double2
30 ; CHECK-NOT:   llihf 0
31 ; CHECK-NOT:   oilf 0
32 ; CHECK:       llihf 2, 1074118262
33 ; CHECK-NEXT:  oilf  2, 3367254360
34 ; CHECK:       lghi  1, 8200
35 define i64 @call_vararg_double2() {
36 entry:
37   %retval = call i64 (i64, ...) @pass_vararg2(i64 8200, double 2.718000e+00)
38   ret i64 %retval
41 ; CHECK-LABEL: call_vararg_double3
42 ; CHECK:       llihf   0, 1072703839
43 ; CHECK-NEXT:  oilf    0, 2861204133
44 ; CHECK:       llihf   1, 1074118262
45 ; CHECK-NEXT:  oilf    1, 3367254360
46 ; CHECK:       llihf   2, 1074340036
47 ; CHECK-NEXT:  oilf    2, 2611340116
48 ; CHECK:       llihf   3, 1073127358
49 ; CHECK-NEXT:  oilf    3, 1992864825
50 ; CHECK:       stg     0, 2200(4)
51 define i64 @call_vararg_double3() {
52 entry:
53   %retval = call i64 (...) @pass_vararg3(double 2.718000e+00, double 3.141000e+00, double 1.414000e+00, double 1.010101e+00)
54   ret i64 %retval
57 ; CHECK-LABEL: call_vararg_both0
58 ; CHECK:       lgr   2, 1
59 ; CHECK:       lgdr  1, 0
60 define i64 @call_vararg_both0(i64 %arg0, double %arg1) {
61   %retval  = call i64(...) @pass_vararg3(double %arg1, i64 %arg0)
62   ret i64 %retval
65 ; CHECK-LABEL: call_vararg_long_double0
66 ; CHECK:       larl  1, @CPI5_0
67 ; CHECK-NEXT:  ld    0, 0(1)
68 ; CHECK-NEXT:  ld    2, 8(1)
69 ; CHECK-NEXT:  lgdr  3, 0
70 ; CHECK:       lghi  1, 1
71 ; CHECK:       lghi  2, 2
72 ; CHECK:       std   0, 2192(4)
73 ; CHECK-NEXT:  std   2, 2200(4)
74 define i64 @call_vararg_long_double0() {
75 entry:
76   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 0xLE0FC1518450562CD4000921FB5444261)
77   ret i64 %retval
80 ; CHECK-LABEL: call_vararg_long_double1
81 ; CHECK:       lgdr  3, 0
82 ; CHECK:       lghi  1, 1
83 ; CHECK:       lghi  2, 2
84 ; CHECK:       std   0, 2192(4)
85 ; CHECK-NEXT:  std   2, 2200(4)
86 define i64 @call_vararg_long_double1(fp128 %arg0) {
87 entry:
88   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0)
89   ret i64 %retval
92 ; CHECK-LABEL: call_vararg_long_double2
93 ; CHECK:      std   4, 2208(4)
94 ; CHECK-NEXT: std   6, 2216(4)
95 ; CHECK:      lgdr  3, 0
96 ; CHECK:      lghi  1, 1
97 ; CHECK:      lghi  2, 2
98 ; CHECK:      std   0, 2192(4)
99 ; CHECK-NEXT: std   2, 2200(4)
100 define i64 @call_vararg_long_double2(fp128 %arg0, fp128 %arg1) {
101 entry:
102   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0, fp128 %arg1)
103   ret i64 %retval
106 ; CHECK-LABEL: call_vararg_long_double3
107 ; CHECK:       lgdr 3, 2
108 ; CHECK-NEXT:  lgdr 2, 0
109 define i64 @call_vararg_long_double3(fp128 %arg0) {
110 entry:
111   %retval = call i64 (...) @pass_vararg3(fp128 %arg0)
112   ret i64 %retval
115 ; ARCH12-LABEL: call_vec_vararg_test0
116 ; ARCH12: vlgvg 3, 24, 1
117 ; ARCH12: vlgvg 2, 24, 0
118 ; ARCH12: lghi  1, 1
119 define void @call_vec_vararg_test0(<2 x double> %v) {
120   %retval = call i64(i64, ...) @pass_vararg2(i64 1, <2 x double> %v)
121   ret void
124 ; ARCH12-LABEL: call_vec_vararg_test1
125 ; ARCH12: larl  1, @CPI10_0
126 ; ARCH12: vl    0, 0(1), 3
127 ; ARCH12: vlgvg 3, 24, 0
128 ; ARCH12: vrepg 2, 0, 1
129 ; ARCH12: vst   25, 2208(4), 3
130 ; ARCH12: vst   24, 2192(4), 3
131 define void @call_vec_vararg_test1(<4 x i32> %v, <2 x i64> %w) {
132   %retval = call i64(fp128, ...) @pass_vararg1(fp128 0xLE0FC1518450562CD4000921FB5444261, <4 x i32> %v, <2 x i64> %w)
133   ret void
136 ; ARCH12-LABEL: call_vec_char_vararg_straddle
137 ; ARCH12: vlgvg 3, 24, 0
138 ; ARCH12: lghi  1, 1
139 ; ARCH12: lghi  2, 2
140 ; ARCH12: vst   24, 2192(4), 3
141 define void @call_vec_char_vararg_straddle(<16 x i8> %v) {
142   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <16 x i8> %v)
143   ret void
146 ; ARCH12-LABEL: call_vec_short_vararg_straddle
147 ; ARCH12: vlgvg 3, 24, 0
148 ; ARCH12: lghi  1, 1
149 ; ARCH12: lghi  2, 2
150 ; ARCH12: vst   24, 2192(4), 3
151 define void @call_vec_short_vararg_straddle(<8 x i16> %v) {
152   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <8 x i16> %v)
153   ret void
156 ; ARCH12-LABEL: call_vec_int_vararg_straddle
157 ; ARCH12: vlgvg 3, 24, 0
158 ; ARCH12: lghi  1, 1
159 ; ARCH12: lghi  2, 2
160 ; ARCH12: vst 24, 2192(4), 3
161 define void @call_vec_int_vararg_straddle(<4 x i32> %v) {
162   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <4 x i32> %v)
163   ret void
166 ; ARCH12-LABEL: call_vec_double_vararg_straddle
167 ; ARCH12: vlgvg 3, 24, 0
168 ; ARCH12: lghi  1, 1
169 ; ARCH12: lghi  2, 2
170 ; ARCH12: vst 24, 2192(4), 3
171 define void @call_vec_double_vararg_straddle(<2 x double> %v) {
172   %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <2 x double> %v)
173   ret void
176 ; CHECK-LABEL: call_vararg_integral0
177 ; Since arguments 0, 1, and 2 are already in the correct
178 ; registers, we should have no loads of any sort into
179 ; GPRs 1, 2, and 3.
180 ; CHECK-NOT: lg  1
181 ; CHECK-NOT: lgr  1
182 ; CHECK-NOT: lg  2
183 ; CHECK-NOT: lgr  2
184 ; CHECK-NOT: lg  3
185 ; CHECK-NOT: lgr  3
186 define i64 @call_vararg_integral0(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3) {
187 entry:
188   %retval = call i64(...) @pass_vararg3(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3)
189   ret i64 %retval
192 ; Derived from C source:
193 ; #define _VARARG_EXT_
194 ; #include <stdarg.h>
196 ; long pass(long x, ...) {
197 ;   va_list va;
198 ;   va_start(va, x);
199 ;   long ret = va_arg(va, long);
200 ;   va_end(va);
201 ;   return ret;
202 ; }
204 ; CHECK-LABEL: pass_vararg:
205 ; CHECK: aghi    4, -160
206 ; CHECK: la      0, 2208(4)
207 ; CHECK: stg     0, 2200(4)
208 define hidden i64 @pass_vararg(i64 %x, ...) {
209 entry:
210   %va = alloca i8*, align 8
211   %va1 = bitcast i8** %va to i8*
212   call void @llvm.va_start(i8* %va1)
213   %argp.cur = load i8*, i8** %va, align 8
214   %argp.next = getelementptr inbounds i8, i8* %argp.cur, i64 8
215   store i8* %argp.next, i8** %va, align 8
216   %0 = bitcast i8* %argp.cur to i64*
217   %ret = load i64, i64* %0, align 8
218   %va2 = bitcast i8** %va to i8*
219   call void @llvm.va_end(i8* %va2)
220   ret i64 %ret
223 declare void @llvm.va_start(i8*)
224 declare void @llvm.va_end(i8*)
226 declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...)
227 declare i64 @pass_vararg1(fp128 %arg0, ...)
228 declare i64 @pass_vararg2(i64 %arg0, ...)
229 declare i64 @pass_vararg3(...)