xref: /llvm-project/llvm/test/CodeGen/AArch64/swift-return.ll (revision db158c7c830807caeeb0691739c41f1d522029e9)
1; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s
2; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s --check-prefix=CHECK-O0
3; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s
4; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck %s --check-prefix=CHECK-O0
5
6; CHECK-LABEL: test1
7; CHECK: bl      _gen
8; CHECK: sxth    [[TMP:w.*]], w0
9; CHECK: add     w0, [[TMP]], w1, sxtb
10; CHECK-O0-LABEL: test1
11; CHECK-O0: bl      _gen
12; CHECK-O0: sxth    [[TMP:w.*]], w0
13; CHECK-O0: add     {{w[0-9]+}}, [[TMP]], w1, sxtb
14define i16 @test1(i32) {
15entry:
16  %call = call swiftcc { i16, i8 } @gen(i32 %0)
17  %v3 = extractvalue { i16, i8 } %call, 0
18  %v1 = sext i16 %v3 to i32
19  %v5 = extractvalue { i16, i8 } %call, 1
20  %v2 = sext i8 %v5 to i32
21  %add = add nsw i32 %v1, %v2
22  %conv = trunc i32 %add to i16
23  ret i16 %conv
24}
25
26declare swiftcc { i16, i8 } @gen(i32)
27
28; CHECK-LABEL: test2
29; CHECK:  bl      _gen2
30; CHECK:  add     [[TMP:x.*]], x0, x1
31; CHECK:  add     [[TMP2:x.*]], x2, x3
32; CHECK:  add     [[TMP]], [[TMP]], [[TMP2]]
33; CHECK:  add     x0, [[TMP]], x4
34; CHECK-O0-LABEL: test2
35; CHECK-O0:  bl      _gen2
36; CHECK-O0:  add     [[TMP:x.*]], x0, x1
37; CHECK-O0:  add     [[TMP]], [[TMP]], x2
38; CHECK-O0:  add     [[TMP]], [[TMP]], x3
39; CHECK-O0:  add     x0, [[TMP]], x4
40
41define i64 @test2(i64 %key) {
42entry:
43  %key.addr = alloca i64, align 4
44  store i64 %key, ptr %key.addr, align 4
45  %0 = load i64, ptr %key.addr, align 4
46  %call = call swiftcc { i64, i64, i64, i64, i64 } @gen2(i64 %0)
47
48  %v3 = extractvalue { i64, i64, i64, i64, i64 } %call, 0
49  %v5 = extractvalue { i64, i64, i64, i64, i64 } %call, 1
50  %v6 = extractvalue { i64, i64, i64, i64, i64 } %call, 2
51  %v7 = extractvalue { i64, i64, i64, i64, i64 } %call, 3
52  %v8 = extractvalue { i64, i64, i64, i64, i64 } %call, 4
53
54  %add = add nsw i64 %v3, %v5
55  %add1 = add nsw i64 %add, %v6
56  %add2 = add nsw i64 %add1, %v7
57  %add3 = add nsw i64 %add2, %v8
58  ret i64 %add3
59}
60; CHECK-LABEL: gen2:
61; CHECK:  mov      x1, x0
62; CHECK:  mov      x2, x0
63; CHECK:  mov      x3, x0
64; CHECK:  mov      x4, x0
65; CHECK:  ret
66define swiftcc { i64, i64, i64, i64, i64 } @gen2(i64 %key) {
67  %Y = insertvalue { i64, i64, i64, i64, i64 } undef, i64 %key, 0
68  %Z = insertvalue { i64, i64, i64, i64, i64 } %Y, i64 %key, 1
69  %Z2 = insertvalue { i64, i64, i64, i64, i64 } %Z, i64 %key, 2
70  %Z3 = insertvalue { i64, i64, i64, i64, i64 } %Z2, i64 %key, 3
71  %Z4 = insertvalue { i64, i64, i64, i64, i64 } %Z3, i64 %key, 4
72  ret { i64, i64, i64, i64, i64 } %Z4
73}
74
75; CHECK-LABEL: test3
76; CHECK: bl      _gen3
77; CHECK: add             [[TMP:w.*]], w0, w1
78; CHECK: add             [[TMP2:w.*]], w2, w3
79; CHECK: add             w0, [[TMP]], [[TMP2]]
80; CHECK-O0-LABEL: test3
81; CHECK-O0: bl      _gen3
82; CHECK-O0: add             [[TMP:w.*]], w0, w1
83; CHECK-O0: add             [[TMP]], [[TMP]], w2
84; CHECK-O0: add             w0, [[TMP]], w3
85define i32 @test3(i32) {
86entry:
87  %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
88
89  %v3 = extractvalue { i32, i32, i32, i32 } %call, 0
90  %v5 = extractvalue { i32, i32, i32, i32 } %call, 1
91  %v6 = extractvalue { i32, i32, i32, i32 } %call, 2
92  %v7 = extractvalue { i32, i32, i32, i32 } %call, 3
93
94  %add = add nsw i32 %v3, %v5
95  %add1 = add nsw i32 %add, %v6
96  %add2 = add nsw i32 %add1, %v7
97  ret i32 %add2
98}
99
100declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)
101
102; CHECK-LABEL: test4
103; CHECK: bl      _gen4
104; CHECK: fadd    s0, s0, s1
105; CHECK: fadd    s0, s0, s2
106; CHECK: fadd    s0, s0, s3
107; CHECK-O0-LABEL: test4
108; CHECK-O0: bl      _gen4
109; CHECK-O0: fadd    s0, s0, s1
110; CHECK-O0: fadd    s0, s0, s2
111; CHECK-O0: fadd    s0, s0, s3
112define float @test4(float) {
113entry:
114  %call = call swiftcc { float, float, float, float } @gen4(float %0)
115
116  %v3 = extractvalue { float, float, float, float } %call, 0
117  %v5 = extractvalue { float, float, float, float } %call, 1
118  %v6 = extractvalue { float, float, float, float } %call, 2
119  %v7 = extractvalue { float, float, float, float } %call, 3
120
121  %add = fadd float %v3, %v5
122  %add1 = fadd float %add, %v6
123  %add2 = fadd float %add1, %v7
124  ret float %add2
125}
126
127declare swiftcc { float, float, float, float } @gen4(float %key)
128
129; CHECK-LABEL: test5
130; CHECK:  bl      _gen5
131; CHECK:  fadd    d0, d0, d1
132; CHECK:  fadd    d0, d0, d2
133; CHECK:  fadd    d0, d0, d3
134; CHECK-O0-LABEL: test5
135; CHECK-O0:  bl      _gen5
136; CHECK-O0:  fadd    d0, d0, d1
137; CHECK-O0:  fadd    d0, d0, d2
138; CHECK-O0:  fadd    d0, d0, d3
139define swiftcc double @test5(){
140entry:
141  %call = call swiftcc { double, double, double, double } @gen5()
142
143  %v3 = extractvalue { double, double, double, double } %call, 0
144  %v5 = extractvalue { double, double, double, double } %call, 1
145  %v6 = extractvalue { double, double, double, double } %call, 2
146  %v7 = extractvalue { double, double, double, double } %call, 3
147
148  %add = fadd double %v3, %v5
149  %add1 = fadd double %add, %v6
150  %add2 = fadd double %add1, %v7
151  ret double %add2
152}
153
154declare swiftcc { double, double, double, double } @gen5()
155
156; CHECK-LABEL: test6
157; CHECK:   bl      _gen6
158; CHECK-DAG:   fadd    d0, d0, d1
159; CHECK-DAG:   fadd    d0, d0, d2
160; CHECK-DAG:   fadd    d0, d0, d3
161; CHECK-DAG:   add     [[TMP:w.*]], w0, w1
162; CHECK-DAG:   add     [[TMP2:w.*]], w2, w3
163; CHECK-DAG:   add     w0, [[TMP]], [[TMP2]]
164; CHECK-O0-LABEL: test6
165; CHECK-O0:   bl      _gen6
166; CHECK-O0-DAG:   fadd    d0, d0, d1
167; CHECK-O0-DAG:   fadd    d0, d0, d2
168; CHECK-O0-DAG:   fadd    d0, d0, d3
169; CHECK-O0-DAG:   add     [[TMP:w.*]], w0, w1
170; CHECK-O0-DAG:   add     [[TMP]], [[TMP]], w2
171; CHECK-O0-DAG:   add     w0, [[TMP]], w3
172define swiftcc { double, i32 } @test6() {
173entry:
174  %call = call swiftcc { double, double, double, double, i32, i32, i32, i32 } @gen6()
175
176  %v3 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 0
177  %v5 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 1
178  %v6 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 2
179  %v7 = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 3
180  %v3.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 4
181  %v5.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 5
182  %v6.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 6
183  %v7.i = extractvalue { double, double, double, double, i32, i32, i32, i32 } %call, 7
184
185  %add = fadd double %v3, %v5
186  %add1 = fadd double %add, %v6
187  %add2 = fadd double %add1, %v7
188
189  %add.i = add nsw i32 %v3.i, %v5.i
190  %add1.i = add nsw i32 %add.i, %v6.i
191  %add2.i = add nsw i32 %add1.i, %v7.i
192
193  %Y = insertvalue { double, i32 } undef, double %add2, 0
194  %Z = insertvalue { double, i32 } %Y, i32 %add2.i, 1
195  ret { double, i32} %Z
196}
197
198declare swiftcc { double, double, double, double, i32, i32, i32, i32 } @gen6()
199
200; CHECK-LABEL: _gen7
201; CHECK-DAG:   mov      w1, w0
202; CHECK-DAG:   mov      w2, w0
203; CHECK-DAG:   mov      w3, w0
204; CHECK:   ret
205; CHECK-O0-LABEL: _gen7
206; CHECK-O0:  mov w3, w0
207; CHECK-O0:  mov w0, w3
208; CHECK-O0:  mov w1, w3
209; CHECK-O0:  mov w2, w3
210define swiftcc { i32, i32, i32, i32 } @gen7(i32 %key) {
211  %v0 = insertvalue { i32, i32, i32, i32 } undef, i32 %key, 0
212  %v1 = insertvalue { i32, i32, i32, i32 } %v0, i32 %key, 1
213  %v2 = insertvalue { i32, i32, i32, i32 } %v1, i32 %key, 2
214  %v3 = insertvalue { i32, i32, i32, i32 } %v2, i32 %key, 3
215  ret { i32, i32, i32, i32 } %v3
216}
217
218; CHECK-LABEL: _gen9
219; CHECK:  mov      w1, w0
220; CHECK:  mov      w2, w0
221; CHECK:  mov      w3, w0
222; CHECK:  ret
223; CHECK-O0-LABEL: _gen9
224; CHECK-O0:  mov w3, w0
225; CHECK-O0:  mov w0, w3
226; CHECK-O0:  mov w1, w3
227; CHECK-O0:  mov w2, w3
228define swiftcc { i8, i8, i8, i8 } @gen9(i8 %key) {
229  %v0 = insertvalue { i8, i8, i8, i8 } undef, i8 %key, 0
230  %v1 = insertvalue { i8, i8, i8, i8 } %v0, i8 %key, 1
231  %v2 = insertvalue { i8, i8, i8, i8 } %v1, i8 %key, 2
232  %v3 = insertvalue { i8, i8, i8, i8 } %v2, i8 %key, 3
233  ret { i8, i8, i8, i8 } %v3
234}
235
236; CHECK-LABEL: _gen10
237; CHECK:  fmov         d1, d0
238; CHECK:  fmov         d2, d0
239; CHECK:  mov      w1, w0
240; CHECK:  fmov         d3, d0
241; CHECK:  mov      w2, w0
242; CHECK:  mov      w3, w0
243; CHECK:  ret
244define swiftcc { double, double, double, double, i32, i32, i32, i32 } @gen10(double %keyd, i32 %keyi) {
245  %v0 = insertvalue { double, double, double, double, i32, i32, i32, i32 } undef, double %keyd, 0
246  %v1 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v0, double %keyd, 1
247  %v2 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v1, double %keyd, 2
248  %v3 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v2, double %keyd, 3
249  %v4 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v3, i32 %keyi, 4
250  %v5 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v4, i32 %keyi, 5
251  %v6 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v5, i32 %keyi, 6
252  %v7 = insertvalue { double, double, double, double, i32, i32, i32, i32 } %v6, i32 %keyi, 7
253  ret { double, double, double, double, i32, i32, i32, i32 } %v7
254}
255
256; CHECK-LABEL: _test11
257; CHECK:  bl      _gen11
258; CHECK:  fadd.4s v0, v0, v1
259; CHECK:  fadd.4s v0, v0, v2
260; CHECK:  fadd.4s v0, v0, v3
261define swiftcc <4 x float> @test11() {
262entry:
263  %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
264
265  %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 0
266  %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 1
267  %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 2
268  %v7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 3
269
270  %add = fadd <4 x float> %v3, %v5
271  %add1 = fadd <4 x float> %add, %v6
272  %add2 = fadd <4 x float> %add1, %v7
273  ret <4 x float> %add2
274}
275
276declare swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
277
278; CHECK-LABEL: _test12
279; CHECK:  fadd.4s v0, v0, v1
280; CHECK:  fmov s1, s3
281; CHECK:  fadd.4s v0, v0, v2
282define swiftcc { <4 x float>, float } @test12() #0 {
283entry:
284  %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
285
286  %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 0
287  %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 1
288  %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 2
289  %v8 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 3
290
291  %add = fadd <4 x float> %v3, %v5
292  %add1 = fadd <4 x float> %add, %v6
293  %res.0 = insertvalue { <4 x float>, float } undef, <4 x float> %add1, 0
294  %res = insertvalue { <4 x float>, float } %res.0, float %v8, 1
295  ret { <4 x float>, float } %res
296}
297
298declare swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
299