1 ; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s
3 ; Test that arguments and return values of fp/vector types are always handled
4 ; with gprs with soft-float.
6 define double @f1(double %arg) {
10 ; CHECK: llihh %r3, 16368
11 ; CHECK-NEXT: brasl %r14, __adddf3@PLT
12 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
14 %res = fadd double %arg, 1.0
18 define float @f2(float %arg) {
21 ; CHECK-NOT: %{{[fv]}}
22 ; CHECK: llgfr %r2, %r2
23 ; CHECK-NEXT: llilh %r3, 16256
24 ; CHECK-NEXT: brasl %r14, __addsf3@PLT
25 ; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d
26 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
28 %res = fadd float %arg, 1.0
32 define fp128 @f2_fp128(fp128 %arg) {
33 ; CHECK-LABEL: f2_fp128:
34 ; CHECK-NOT: %{{[fv]}}
35 ; CHECK: aghi %r15, -208
36 ; CHECK-NEXT: .cfi_def_cfa_offset 368
37 ; CHECK-NEXT: lg %r0, 0(%r2)
38 ; CHECK-NEXT: lg %r1, 8(%r2)
39 ; CHECK-NEXT: llihf %r2, 1073823744
40 ; CHECK-NEXT: stg %r2, 160(%r15)
41 ; CHECK-NEXT: la %r2, 192(%r15)
42 ; CHECK-NEXT: la %r3, 176(%r15)
43 ; CHECK-NEXT: la %r4, 160(%r15)
44 ; CHECK-NEXT: stg %r1, 184(%r15)
45 ; CHECK-NEXT: stg %r0, 176(%r15)
46 ; CHECK-NEXT: mvghi 168(%r15), 0
47 ; CHECK-NEXT: brasl %r14, __addtf3@PLT
48 ; CHECK-NEXT: lg %r2, 192(%r15)
49 ; CHECK-NEXT: lg %r3, 200(%r15)
50 ; CHECK-NEXT: lmg %r14, %r15, 320(%r15)
52 %res = fadd fp128 %arg, 0xL00000000000000004001400000000000
56 define <2 x double> @f3(<2 x double> %arg) {
58 ; CHECK-NOT: %{{[fv]}}
59 ; CHECK: lg %r13, 8(%r2)
60 ; CHECK-NEXT: lg %r2, 0(%r2)
61 ; CHECK-NEXT: llihh %r3, 16368
62 ; CHECK-NEXT: brasl %r14, __adddf3@PLT
63 ; CHECK-NEXT: lgr %r12, %r2
64 ; CHECK-NEXT: lgr %r2, %r13
65 ; CHECK-NEXT: llihh %r3, 16368
66 ; CHECK-NEXT: brasl %r14, __adddf3@PLT
67 ; CHECK-NEXT: lgr %r3, %r2
68 ; CHECK-NEXT: lgr %r2, %r12
69 ; CHECK-NEXT: lmg %r12, %r15, 256(%r15)
71 %res = fadd <2 x double> %arg, <double 1.000000e+00, double 1.000000e+00>
75 define <2 x float> @f4(<2 x float> %arg) {
77 ; CHECK-NOT: %{{[fv]}}
79 ; CHECK-NEXT: llgfr %r2, %r2
80 ; CHECK-NEXT: llilh %r3, 16256
81 ; CHECK-NEXT: brasl %r14, __addsf3@PLT
82 ; CHECK-NEXT: lgr %r12, %r2
83 ; CHECK-NEXT: llgfr %r2, %r13
84 ; CHECK-NEXT: llilh %r3, 16256
85 ; CHECK-NEXT: brasl %r14, __addsf3@PLT
86 ; CHECK-NEXT: lgr %r3, %r2
87 ; CHECK-NEXT: lr %r2, %r12
88 ; CHECK-NEXT: # kill: def $r3l killed $r3l killed $r3d
89 ; CHECK-NEXT: lmg %r12, %r15, 256(%r15)
91 %res = fadd <2 x float> %arg, <float 1.000000e+00, float 1.000000e+00>
95 define <2 x i64> @f5(<2 x i64> %arg) {
97 ; CHECK-NOT: %{{[fv]}}
99 ; CHECK-NEXT: ag %r0, 0(%r2)
100 ; CHECK-NEXT: lghi %r3, 1
101 ; CHECK-NEXT: ag %r3, 8(%r2)
102 ; CHECK-NEXT: lgr %r2, %r0
103 ; CHECK-NEXT: br %r14
104 %res = add <2 x i64> %arg, <i64 1, i64 1>
108 define <2 x i32> @f6(<2 x i32> %arg) {
110 ; CHECK-NOT: %{{[fv]}}
112 ; CHECK-NEXT: ahi %r3, 1
113 ; CHECK-NEXT: br %r14
114 %res = add <2 x i32> %arg, <i32 1, i32 1>
120 define double @f7(double %A, double %B, double %C, double %D, double %E,
123 ; CHECK-NOT: %{{[fv]}}
124 ; CHECK: aghi %r15, -160
125 ; CHECK-NEXT: .cfi_def_cfa_offset 320
126 ; CHECK-NEXT: lg %r3, 320(%r15)
127 ; CHECK-NEXT: brasl %r14, __adddf3@PLT
128 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
129 ; CHECK-NEXT: br %r14
131 %res = fadd double %A, %F
135 define float @f8(float %A, float %B, float %C, float %D, float %E,
138 ; CHECK-NOT: %{{[fv]}}
139 ; CHECK: aghi %r15, -160
140 ; CHECK-NEXT: .cfi_def_cfa_offset 320
141 ; CHECK-NEXT: llgf %r3, 324(%r15)
142 ; CHECK-NEXT: llgfr %r2, %r2
143 ; CHECK-NEXT: brasl %r14, __addsf3@PLT
144 ; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d
145 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
146 ; CHECK-NEXT: br %r14
147 %res = fadd float %A, %F
151 define <2 x double> @f9(<2 x double> %A, <2 x double> %B, <2 x double> %C,
152 <2 x double> %D, <2 x double> %E, <2 x double> %F,
153 <2 x double> %G, <2 x double> %H, <2 x double> %I) {
155 ; CHECK-NOT: %{{[fv]}}
156 ; CHECK: aghi %r15, -160
157 ; CHECK-NEXT: .cfi_def_cfa_offset 320
158 ; CHECK-NEXT: lg %r1, 344(%r15)
159 ; CHECK-NEXT: lg %r13, 8(%r2)
160 ; CHECK-NEXT: lg %r2, 0(%r2)
161 ; CHECK-NEXT: lg %r3, 0(%r1)
162 ; CHECK-NEXT: lg %r12, 8(%r1)
163 ; CHECK-NEXT: brasl %r14, __adddf3@PLT
164 ; CHECK-NEXT: lgr %r11, %r2
165 ; CHECK-NEXT: lgr %r2, %r13
166 ; CHECK-NEXT: lgr %r3, %r12
167 ; CHECK-NEXT: brasl %r14, __adddf3@PLT
168 ; CHECK-NEXT: lgr %r3, %r2
169 ; CHECK-NEXT: lgr %r2, %r11
170 ; CHECK-NEXT: lmg %r11, %r15, 248(%r15)
171 ; CHECK-NEXT: br %r14
172 %res = fadd <2 x double> %A, %I
173 ret <2 x double> %res
176 define <2 x float> @f10(<2 x float> %A, <2 x float> %B, <2 x float> %C,
177 <2 x float> %D, <2 x float> %E, <2 x float> %F,
178 <2 x float> %G, <2 x float> %H, <2 x float> %I) {
180 ; CHECK-NOT: %{{[fv]}}
181 ; CHECK: aghi %r15, -160
182 ; CHECK-NEXT: .cfi_def_cfa_offset 320
183 ; CHECK-NEXT: lr %r13, %r3
184 ; CHECK-NEXT: llgf %r3, 412(%r15)
185 ; CHECK-NEXT: llgf %r12, 420(%r15)
186 ; CHECK-NEXT: llgfr %r2, %r2
187 ; CHECK-NEXT: brasl %r14, __addsf3@PLT
188 ; CHECK-NEXT: lgr %r11, %r2
189 ; CHECK-NEXT: llgfr %r2, %r13
190 ; CHECK-NEXT: lgr %r3, %r12
191 ; CHECK-NEXT: brasl %r14, __addsf3@PLT
192 ; CHECK-NEXT: lgr %r3, %r2
193 ; CHECK-NEXT: lr %r2, %r11
194 ; CHECK-NEXT: # kill: def $r3l killed $r3l killed $r3d
195 ; CHECK-NEXT: lmg %r11, %r15, 248(%r15)
196 ; CHECK-NEXT: br %r14
198 %res = fadd <2 x float> %A, %I
202 define <2 x i64> @f11(<2 x i64> %A, <2 x i64> %B, <2 x i64> %C,
203 <2 x i64> %D, <2 x i64> %E, <2 x i64> %F,
204 <2 x i64> %G, <2 x i64> %H, <2 x i64> %I) {
206 ; CHECK-NOT: %{{[fv]}}
207 ; CHECK: lg %r1, 184(%r15)
208 ; CHECK-NEXT: lg %r3, 8(%r2)
209 ; CHECK-NEXT: lg %r2, 0(%r2)
210 ; CHECK-NEXT: ag %r2, 0(%r1)
211 ; CHECK-NEXT: ag %r3, 8(%r1)
212 ; CHECK-NEXT: br %r14
213 %res = add <2 x i64> %A, %I
219 declare double @bar_double(double %arg);
220 define double @f12(double %arg, double %arg2) {
222 ; CHECK-NOT: %{{[fv]}}
223 ; CHECK-NOT: %r{{[23]}}
224 ; CHECK: lgr %r2, %r3
225 ; CHECK-NEXT: brasl %r14, bar_double@PLT
226 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
227 ; CHECK-NEXT: br %r14
228 %res = call double @bar_double(double %arg2)
232 declare float @bar_float(float %arg);
233 define float @f13(float %arg, float %arg2) {
235 ; CHECK-NOT: %{{[fv]}}
236 ; CHECK-NOT: %r{{[23]}}
238 ; CHECK-NEXT: brasl %r14, bar_float@PLT
239 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
240 ; CHECK-NEXT: br %r14
241 %res = call float @bar_float(float %arg2)
245 declare fp128 @bar_fp128(fp128 %arg);
246 define fp128 @f14(fp128 %arg, fp128 %arg2) {
248 ; CHECK-NOT: %{{[fv]}}
250 ; CHECK: lg %r0, 0(%r3)
251 ; CHECK-NEXT: lg %r1, 8(%r3)
252 ; CHECK-NEXT: la %r2, 160(%r15)
253 ; CHECK-NEXT: stg %r1, 168(%r15)
254 ; CHECK-NEXT: stg %r0, 160(%r15)
255 ; CHECK-NEXT: brasl %r14, bar_fp128@PLT
256 ; CHECK-NEXT: lmg %r14, %r15, 288(%r15)
257 ; CHECK-NEXT: br %r14
258 %res = call fp128 @bar_fp128(fp128 %arg2)
262 declare <2 x double> @bar_v2f64(<2 x double> %arg);
263 define <2 x double> @f15(<2 x double> %arg, <2 x double> %arg2) {
265 ; CHECK-NOT: %{{[fv]}}
267 ; CHECK: lg %r0, 0(%r3)
268 ; CHECK-NEXT: lg %r1, 8(%r3)
269 ; CHECK-NEXT: la %r2, 160(%r15)
270 ; CHECK-NEXT: stg %r1, 168(%r15)
271 ; CHECK-NEXT: stg %r0, 160(%r15)
272 ; CHECK-NEXT: brasl %r14, bar_v2f64@PLT
273 ; CHECK-NEXT: lmg %r14, %r15, 288(%r15)
274 ; CHECK-NEXT: br %r14
275 %res = call <2 x double> @bar_v2f64(<2 x double> %arg2)
276 ret <2 x double> %res
279 declare <2 x float> @bar_v2f32(<2 x float> %arg);
280 define <2 x float> @f16(<2 x float> %arg, <2 x float> %arg2) {
282 ; CHECK-NOT: %{{[fv]}}
283 ; CHECK-NOT: %r{{[2345]}}
285 ; CHECK-NEXT: lr %r2, %r4
286 ; CHECK-NEXT: brasl %r14, bar_v2f32@PLT
287 ; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
288 ; CHECK-NEXT: br %r14
289 %res = call <2 x float> @bar_v2f32(<2 x float> %arg2)
293 declare <2 x i64> @bar_v2i64(<2 x i64> %arg);
294 define <2 x i64> @f17(<2 x i64> %arg, <2 x i64> %arg2) {
296 ; CHECK-NOT: %{{[fv]}}
298 ; CHECK: lg %r0, 0(%r3)
299 ; CHECK-NEXT: lg %r1, 8(%r3)
300 ; CHECK-NEXT: la %r2, 160(%r15)
301 ; CHECK-NEXT: stg %r1, 168(%r15)
302 ; CHECK-NEXT: stg %r0, 160(%r15)
303 ; CHECK-NEXT: brasl %r14, bar_v2i64@PLT
304 ; CHECK-NEXT: lmg %r14, %r15, 288(%r15)
305 ; CHECK-NEXT: br %r14
306 %res = call <2 x i64> @bar_v2i64(<2 x i64> %arg2)