blob: 313fef5eb34d0af39d899ff92990e1434c8ed2bd [file] [log] [blame]
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +00001; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE --check-prefix=CHECK-ARMV7 %s
Manman Ren57518142016-04-11 21:08:06 +00002; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s
Brian Gesiak33329762017-08-30 20:03:54 +00003; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-linux-androideabi | FileCheck --check-prefix=CHECK-ANDROID %s
Manman Ren57518142016-04-11 21:08:06 +00004
5declare i8* @malloc(i64)
6declare void @free(i8*)
7%swift_error = type { i64, i8 }
8%struct.S = type { i32, i32, i32, i32, i32, i32 }
9
10; This tests the basic usage of a swifterror parameter. "foo" is the function
11; that takes a swifterror parameter and "caller" is the caller of "foo".
12define float @foo(%swift_error** swifterror %error_ptr_ref) {
13; CHECK-APPLE-LABEL: foo:
14; CHECK-APPLE: mov r0, #16
15; CHECK-APPLE: malloc
16; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], #1
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000017; CHECK-APPLE-DAG: mov r8, r{{.*}}
Manman Ren57518142016-04-11 21:08:06 +000018; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
19
20; CHECK-O0-LABEL: foo:
21; CHECK-O0: mov r{{.*}}, #16
22; CHECK-O0: malloc
23; CHECK-O0: mov [[ID2:r[0-9]+]], r0
24; CHECK-O0: mov [[ID:r[0-9]+]], #1
25; CHECK-O0: strb [[ID]], [r0, #8]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000026; CHECK-O0: mov r8, [[ID2]]
Manman Ren57518142016-04-11 21:08:06 +000027entry:
28 %call = call i8* @malloc(i64 16)
29 %call.0 = bitcast i8* %call to %swift_error*
30 store %swift_error* %call.0, %swift_error** %error_ptr_ref
31 %tmp = getelementptr inbounds i8, i8* %call, i64 8
32 store i8 1, i8* %tmp
33 ret float 1.0
34}
35
36; "caller" calls "foo" that takes a swifterror parameter.
37define float @caller(i8* %error_ref) {
38; CHECK-APPLE-LABEL: caller:
39; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000040; CHECK-APPLE-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +000041; CHECK-APPLE: bl {{.*}}foo
Jonas Paulsson995ba6e2018-02-16 09:51:01 +000042; CHECK-APPLE: mov r0, r8
Geoff Berrya2b90112018-02-27 16:59:10 +000043; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +000044; Access part of the error object and save it to error_ref
Jonas Paulsson995ba6e2018-02-16 09:51:01 +000045; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r0, #8]
Manman Ren57518142016-04-11 21:08:06 +000046; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000047; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +000048
49; CHECK-O0-LABEL: caller:
50; spill r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000051; CHECK-O0-DAG: mov r8, #0
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000052; CHECK-O0-DAG: str r0, [sp, [[SLOT:#[0-9]+]]
Manman Ren57518142016-04-11 21:08:06 +000053; CHECK-O0: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000054; CHECK-O0: mov [[TMP:r[0-9]+]], r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000055; CHECK-O0: str [[TMP]], [sp]
Manman Ren57518142016-04-11 21:08:06 +000056; CHECK-O0: bne
57; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000058; CHECK-O0: ldr [[ID:r[0-9]+]], [sp, [[SLOT]]]
Manman Ren57518142016-04-11 21:08:06 +000059; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000060; reload r0
61; CHECK-O0: ldr r0, [sp]
Manman Ren57518142016-04-11 21:08:06 +000062; CHECK-O0: free
63entry:
64 %error_ptr_ref = alloca swifterror %swift_error*
65 store %swift_error* null, %swift_error** %error_ptr_ref
66 %call = call float @foo(%swift_error** swifterror %error_ptr_ref)
67 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
68 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
69 %tmp = bitcast %swift_error* %error_from_foo to i8*
70 br i1 %had_error_from_foo, label %handler, label %cont
71cont:
72 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
73 %t = load i8, i8* %v1
74 store i8 %t, i8* %error_ref
75 br label %handler
76handler:
77 call void @free(i8* %tmp)
78 ret float 1.0
79}
80
81; "caller2" is the caller of "foo", it calls "foo" inside a loop.
82define float @caller2(i8* %error_ref) {
83; CHECK-APPLE-LABEL: caller2:
84; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000085; CHECK-APPLE-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +000086; CHECK-APPLE: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000087; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +000088; CHECK-APPLE: bne
89; Access part of the error object and save it to error_ref
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000090; CHECK-APPLE: ldrb [[CODE:r[0-9]+]], [r8, #8]
Manman Ren57518142016-04-11 21:08:06 +000091; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000092; CHECK-APPLE: mov r0, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000093; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +000094
95; CHECK-O0-LABEL: caller2:
96; spill r0
97; CHECK-O0-DAG: str r0,
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000098; CHECK-O0-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +000099; CHECK-O0: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000100; CHECK-O0: mov r{{.*}}, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000101; CHECK-O0: str r0, [sp]
Manman Ren57518142016-04-11 21:08:06 +0000102; CHECK-O0: bne
103; CHECK-O0: ble
104; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8]
105; reload r0
106; CHECK-O0: ldr [[ID:r[0-9]+]],
107; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000108; CHECK-O0: ldr r0, [sp]
Manman Ren57518142016-04-11 21:08:06 +0000109; CHECK-O0: free
110entry:
111 %error_ptr_ref = alloca swifterror %swift_error*
112 br label %bb_loop
113bb_loop:
114 store %swift_error* null, %swift_error** %error_ptr_ref
115 %call = call float @foo(%swift_error** swifterror %error_ptr_ref)
116 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
117 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
118 %tmp = bitcast %swift_error* %error_from_foo to i8*
119 br i1 %had_error_from_foo, label %handler, label %cont
120cont:
121 %cmp = fcmp ogt float %call, 1.000000e+00
122 br i1 %cmp, label %bb_end, label %bb_loop
123bb_end:
124 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
125 %t = load i8, i8* %v1
126 store i8 %t, i8* %error_ref
127 br label %handler
128handler:
129 call void @free(i8* %tmp)
130 ret float 1.0
131}
132
133; "foo_if" is a function that takes a swifterror parameter, it sets swifterror
134; under a certain condition.
135define float @foo_if(%swift_error** swifterror %error_ptr_ref, i32 %cc) {
136; CHECK-APPLE-LABEL: foo_if:
137; CHECK-APPLE: cmp r0, #0
138; CHECK-APPLE: eq
139; CHECK-APPLE: mov r0, #16
140; CHECK-APPLE: malloc
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000141; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], #1
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000142; CHECK-APPLE-DAG: mov r8, r{{.*}}
Manman Ren57518142016-04-11 21:08:06 +0000143; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
144
145; CHECK-O0-LABEL: foo_if:
146; CHECK-O0: cmp r0, #0
147; spill to stack
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000148; CHECK-O0: str r8
Manman Ren57518142016-04-11 21:08:06 +0000149; CHECK-O0: beq
150; CHECK-O0: mov r0, #16
151; CHECK-O0: malloc
152; CHECK-O0: mov [[ID:r[0-9]+]], r0
153; CHECK-O0: mov [[ID2:[a-z0-9]+]], #1
154; CHECK-O0: strb [[ID2]], [r0, #8]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000155; CHECK-O0: mov r8, [[ID]]
Manman Ren57518142016-04-11 21:08:06 +0000156; reload from stack
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000157; CHECK-O0: ldr r8
Manman Ren57518142016-04-11 21:08:06 +0000158entry:
159 %cond = icmp ne i32 %cc, 0
160 br i1 %cond, label %gen_error, label %normal
161
162gen_error:
163 %call = call i8* @malloc(i64 16)
164 %call.0 = bitcast i8* %call to %swift_error*
165 store %swift_error* %call.0, %swift_error** %error_ptr_ref
166 %tmp = getelementptr inbounds i8, i8* %call, i64 8
167 store i8 1, i8* %tmp
168 ret float 1.0
169
170normal:
171 ret float 0.0
172}
173
174; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror
175; under a certain condition inside a loop.
176define float @foo_loop(%swift_error** swifterror %error_ptr_ref, i32 %cc, float %cc2) {
177; CHECK-APPLE-LABEL: foo_loop:
178; CHECK-APPLE: mov [[CODE:r[0-9]+]], r0
179; swifterror is kept in a register
Manman Ren57518142016-04-11 21:08:06 +0000180; CHECK-APPLE: cmp [[CODE]], #0
181; CHECK-APPLE: beq
182; CHECK-APPLE: mov r0, #16
183; CHECK-APPLE: malloc
Geoff Berrya2b90112018-02-27 16:59:10 +0000184; CHECK-APPLE: strb r{{.*}}, [r0, #8]
Manman Ren57518142016-04-11 21:08:06 +0000185; CHECK-APPLE: ble
Manman Ren57518142016-04-11 21:08:06 +0000186
187; CHECK-O0-LABEL: foo_loop:
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000188; CHECK-O0: mov r{{.*}}, r8
Manman Ren57518142016-04-11 21:08:06 +0000189; CHECK-O0: cmp r{{.*}}, #0
190; CHECK-O0: beq
Reid Kleckner3a7a2e42018-03-14 21:54:21 +0000191; CHECK-O0: mov r0, #16
Manman Ren57518142016-04-11 21:08:06 +0000192; CHECK-O0: malloc
193; CHECK-O0-DAG: mov [[ID:r[0-9]+]], r0
Reid Kleckner3a7a2e42018-03-14 21:54:21 +0000194; CHECK-O0-DAG: movw [[ID2:.*]], #1
Manman Ren57518142016-04-11 21:08:06 +0000195; CHECK-O0: strb [[ID2]], [{{.*}}[[ID]], #8]
196; spill r0
197; CHECK-O0: str r0, [sp{{.*}}]
198; CHECK-O0: vcmpe
199; CHECK-O0: ble
200; reload from stack
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000201; CHECK-O0: ldr r8
Manman Ren57518142016-04-11 21:08:06 +0000202entry:
203 br label %bb_loop
204
205bb_loop:
206 %cond = icmp ne i32 %cc, 0
207 br i1 %cond, label %gen_error, label %bb_cont
208
209gen_error:
210 %call = call i8* @malloc(i64 16)
211 %call.0 = bitcast i8* %call to %swift_error*
212 store %swift_error* %call.0, %swift_error** %error_ptr_ref
213 %tmp = getelementptr inbounds i8, i8* %call, i64 8
214 store i8 1, i8* %tmp
215 br label %bb_cont
216
217bb_cont:
218 %cmp = fcmp ogt float %cc2, 1.000000e+00
219 br i1 %cmp, label %bb_end, label %bb_loop
220bb_end:
221 ret float 0.0
222}
223
224; "foo_sret" is a function that takes a swifterror parameter, it also has a sret
225; parameter.
226define void @foo_sret(%struct.S* sret %agg.result, i32 %val1, %swift_error** swifterror %error_ptr_ref) {
227; CHECK-APPLE-LABEL: foo_sret:
228; CHECK-APPLE: mov [[SRET:r[0-9]+]], r0
229; CHECK-APPLE: mov r0, #16
230; CHECK-APPLE: malloc
231; CHECK-APPLE: mov [[REG:r[0-9]+]], #1
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000232; CHECK-APPLE-DAG: mov r8, r0
Manman Ren57518142016-04-11 21:08:06 +0000233; CHECK-APPLE-DAG: strb [[REG]], [r0, #8]
234; CHECK-APPLE-DAG: str r{{.*}}, [{{.*}}[[SRET]], #4]
235
236; CHECK-O0-LABEL: foo_sret:
237; CHECK-O0: mov r{{.*}}, #16
238; spill to stack: sret and val1
239; CHECK-O0-DAG: str r0
240; CHECK-O0-DAG: str r1
241; CHECK-O0: malloc
242; CHECK-O0: mov [[ID:r[0-9]+]], #1
243; CHECK-O0: strb [[ID]], [r0, #8]
244; reload from stack: sret and val1
245; CHECK-O0: ldr
246; CHECK-O0: ldr
247; CHECK-O0: str r{{.*}}, [{{.*}}, #4]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000248; CHECK-O0: mov r8
Manman Ren57518142016-04-11 21:08:06 +0000249entry:
250 %call = call i8* @malloc(i64 16)
251 %call.0 = bitcast i8* %call to %swift_error*
252 store %swift_error* %call.0, %swift_error** %error_ptr_ref
253 %tmp = getelementptr inbounds i8, i8* %call, i64 8
254 store i8 1, i8* %tmp
255 %v2 = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1
256 store i32 %val1, i32* %v2
257 ret void
258}
259
260; "caller3" calls "foo_sret" that takes a swifterror parameter.
261define float @caller3(i8* %error_ref) {
262; CHECK-APPLE-LABEL: caller3:
263; CHECK-APPLE: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000264; CHECK-APPLE: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000265; CHECK-APPLE: bl {{.*}}foo_sret
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000266; CHECK-APPLE: mov r0, r8
Geoff Berrya2b90112018-02-27 16:59:10 +0000267; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000268; Access part of the error object and save it to error_ref
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000269; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r0, #8]
Manman Ren57518142016-04-11 21:08:06 +0000270; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000271; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +0000272
273; CHECK-O0-LABEL: caller3:
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000274; CHECK-O0-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000275; CHECK-O0-DAG: mov r0
276; CHECK-O0-DAG: mov r1
277; CHECK-O0: bl {{.*}}foo_sret
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000278; CHECK-O0: mov [[ID2:r[0-9]+]], r8
279; CHECK-O0: cmp r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000280; CHECK-O0: str [[ID2]], [sp[[SLOT:.*]]]
Manman Ren57518142016-04-11 21:08:06 +0000281; CHECK-O0: bne
282; Access part of the error object and save it to error_ref
283; CHECK-O0: ldrb [[CODE:r[0-9]+]]
284; CHECK-O0: ldr [[ID:r[0-9]+]]
285; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000286; CHECK-O0: ldr r0, [sp[[SLOT]]
287; CHECK-O0: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +0000288entry:
289 %s = alloca %struct.S, align 8
290 %error_ptr_ref = alloca swifterror %swift_error*
291 store %swift_error* null, %swift_error** %error_ptr_ref
292 call void @foo_sret(%struct.S* sret %s, i32 1, %swift_error** swifterror %error_ptr_ref)
293 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
294 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
295 %tmp = bitcast %swift_error* %error_from_foo to i8*
296 br i1 %had_error_from_foo, label %handler, label %cont
297cont:
298 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
299 %t = load i8, i8* %v1
300 store i8 %t, i8* %error_ref
301 br label %handler
302handler:
303 call void @free(i8* %tmp)
304 ret float 1.0
305}
306
307; "foo_vararg" is a function that takes a swifterror parameter, it also has
308; variable number of arguments.
309declare void @llvm.va_start(i8*) nounwind
310define float @foo_vararg(%swift_error** swifterror %error_ptr_ref, ...) {
311; CHECK-APPLE-LABEL: foo_vararg:
312; CHECK-APPLE: mov r0, #16
313; CHECK-APPLE: malloc
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000314; CHECK-APPLE: mov r8, r0
Manman Ren57518142016-04-11 21:08:06 +0000315; CHECK-APPLE: mov [[ID:r[0-9]+]], #1
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000316; CHECK-APPLE-DAG: strb [[ID]], [r8, #8]
Manman Ren57518142016-04-11 21:08:06 +0000317
318entry:
319 %call = call i8* @malloc(i64 16)
320 %call.0 = bitcast i8* %call to %swift_error*
321 store %swift_error* %call.0, %swift_error** %error_ptr_ref
322 %tmp = getelementptr inbounds i8, i8* %call, i64 8
323 store i8 1, i8* %tmp
324
325 %args = alloca i8*, align 8
326 %a10 = alloca i32, align 4
327 %a11 = alloca i32, align 4
328 %a12 = alloca i32, align 4
329 %v10 = bitcast i8** %args to i8*
330 call void @llvm.va_start(i8* %v10)
331 %v11 = va_arg i8** %args, i32
332 store i32 %v11, i32* %a10, align 4
333 %v12 = va_arg i8** %args, i32
334 store i32 %v12, i32* %a11, align 4
335 %v13 = va_arg i8** %args, i32
336 store i32 %v13, i32* %a12, align 4
337
338 ret float 1.0
339}
340
341; "caller4" calls "foo_vararg" that takes a swifterror parameter.
342define float @caller4(i8* %error_ref) {
343; CHECK-APPLE-LABEL: caller4:
344; CHECK-APPLE: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000345; CHECK-APPLE: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000346; CHECK-APPLE: bl {{.*}}foo_vararg
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000347; CHECK-APPLE: mov r0, r8
Geoff Berrya2b90112018-02-27 16:59:10 +0000348; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000349; Access part of the error object and save it to error_ref
Jonas Paulsson995ba6e2018-02-16 09:51:01 +0000350; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r0, #8]
Manman Ren57518142016-04-11 21:08:06 +0000351; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000352; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +0000353entry:
354 %error_ptr_ref = alloca swifterror %swift_error*
355 store %swift_error* null, %swift_error** %error_ptr_ref
356
357 %a10 = alloca i32, align 4
358 %a11 = alloca i32, align 4
359 %a12 = alloca i32, align 4
360 store i32 10, i32* %a10, align 4
361 store i32 11, i32* %a11, align 4
362 store i32 12, i32* %a12, align 4
363 %v10 = load i32, i32* %a10, align 4
364 %v11 = load i32, i32* %a11, align 4
365 %v12 = load i32, i32* %a12, align 4
366
367 %call = call float (%swift_error**, ...) @foo_vararg(%swift_error** swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12)
368 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
369 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
370 %tmp = bitcast %swift_error* %error_from_foo to i8*
371 br i1 %had_error_from_foo, label %handler, label %cont
372
373cont:
374 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
375 %t = load i8, i8* %v1
376 store i8 %t, i8* %error_ref
377 br label %handler
378handler:
379 call void @free(i8* %tmp)
380 ret float 1.0
381}
Arnold Schwaighoferde2490d2016-09-21 16:53:36 +0000382
383; Check that we don't blow up on tail calling swifterror argument functions.
384define float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref) {
385entry:
386 %0 = tail call float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref)
387 ret float %0
388}
389define swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref) {
390entry:
391 %0 = tail call swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref)
392 ret float %0
393}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000394
395; CHECK-APPLE-LABEL: swifterror_clobber
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000396; CHECK-APPLE: mov [[REG:r[0-9]+]], r8
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000397; CHECK-APPLE: nop
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000398; CHECK-APPLE: mov r8, [[REG]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000399define swiftcc void @swifterror_clobber(%swift_error** nocapture swifterror %err) {
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000400 call void asm sideeffect "nop", "~{r8}"()
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000401 ret void
402}
403
404; CHECK-APPLE-LABEL: swifterror_reg_clobber
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000405; CHECK-APPLE: push {{.*}}r8
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000406; CHECK-APPLE: nop
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000407; CHECK-APPLE: pop {{.*}}r8
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000408define swiftcc void @swifterror_reg_clobber(%swift_error** nocapture %err) {
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000409 call void asm sideeffect "nop", "~{r8}"()
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000410 ret void
411}
412
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000413; CHECK-ARMV7-LABEL: _params_in_reg
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000414; Store callee saved registers excluding swifterror.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000415; CHECK-ARMV7: push {r4, r5, r6, r7, r10, r11, lr}
416; Store swiftself (r10) and swifterror (r8).
417; CHECK-ARMV7-DAG: str r8, [s[[STK1:.*]]]
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000418; CHECK-ARMV7-DAG: str r10, [s[[STK2:.*]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000419; Store arguments.
Kristof Beylseecb3532017-06-28 07:07:03 +0000420; CHECK-ARMV7-DAG: mov r6, r3
421; CHECK-ARMV7-DAG: mov r4, r2
422; CHECK-ARMV7-DAG: mov r11, r1
423; CHECK-ARMV7-DAG: mov r5, r0
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000424; Setup call.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000425; CHECK-ARMV7: mov r0, #1
426; CHECK-ARMV7: mov r1, #2
427; CHECK-ARMV7: mov r2, #3
428; CHECK-ARMV7: mov r3, #4
429; CHECK-ARMV7: mov r10, #0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000430; CHECK-ARMV7: mov r8, #0
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000431; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000432; Restore original arguments.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000433; CHECK-ARMV7-DAG: ldr r10, [s[[STK2]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000434; CHECK-ARMV7-DAG: ldr r8, [s[[STK1]]]
Kristof Beylseecb3532017-06-28 07:07:03 +0000435; CHECK-ARMV7-DAG: mov r0, r5
436; CHECK-ARMV7-DAG: mov r1, r11
437; CHECK-ARMV7-DAG: mov r2, r4
438; CHECK-ARMV7-DAG: mov r3, r6
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000439; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000440; CHECK-ARMV7: pop {r4, r5, r6, r7, r10, r11, pc}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000441define swiftcc void @params_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) {
442 %error_ptr_ref = alloca swifterror %swift_error*, align 8
443 store %swift_error* null, %swift_error** %error_ptr_ref
444 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
445 call swiftcc void @params_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err)
446 ret void
447}
448declare swiftcc void @params_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err)
449
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000450; CHECK-ARMV7-LABEL: params_and_return_in_reg
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000451; CHECK-ARMV7: push {r4, r5, r6, r7, r10, r11, lr}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000452; Store swifterror and swiftself
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000453; CHECK-ARMV7: mov r6, r8
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000454; CHECK-ARMV7: str r10, [s[[STK1:.*]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000455; Store arguments.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000456; CHECK-ARMV7: str r3, [s[[STK2:.*]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000457; CHECK-ARMV7: mov r4, r2
458; CHECK-ARMV7: mov r11, r1
459; CHECK-ARMV7: mov r5, r0
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000460; Setup call.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000461; CHECK-ARMV7: mov r0, #1
462; CHECK-ARMV7: mov r1, #2
463; CHECK-ARMV7: mov r2, #3
464; CHECK-ARMV7: mov r3, #4
465; CHECK-ARMV7: mov r10, #0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000466; CHECK-ARMV7: mov r8, #0
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000467; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000468; Restore original arguments.
Kristof Beylseecb3532017-06-28 07:07:03 +0000469; CHECK-ARMV7-DAG: ldr r3, [s[[STK2]]]
470; CHECK-ARMV7-DAG: ldr r10, [s[[STK1]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000471; Store %error_ptr_ref;
Kristof Beylseecb3532017-06-28 07:07:03 +0000472; CHECK-ARMV7-DAG: str r8, [s[[STK3:.*]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000473; Restore original arguments.
Kristof Beylseecb3532017-06-28 07:07:03 +0000474; CHECK-ARMV7-DAG: mov r0, r5
475; CHECK-ARMV7-DAG: mov r1, r11
476; CHECK-ARMV7-DAG: mov r2, r4
477; CHECK-ARMV7-DAG: mov r8, r6
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000478; CHECK-ARMV7: bl _params_and_return_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000479; Store swifterror return %err;
Kristof Beylseecb3532017-06-28 07:07:03 +0000480; CHECK-ARMV7-DAG: str r8, [s[[STK1]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000481; Load swifterror value %error_ptr_ref.
Kristof Beylseecb3532017-06-28 07:07:03 +0000482; CHECK-ARMV7-DAG: ldr r8, [s[[STK3]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000483; Save return values.
Kristof Beylseecb3532017-06-28 07:07:03 +0000484; CHECK-ARMV7-DAG: mov r4, r0
485; CHECK-ARMV7-DAG: mov r5, r1
486; CHECK-ARMV7-DAG: mov r6, r2
487; CHECK-ARMV7-DAG: mov r11, r3
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000488; Setup call.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000489; CHECK-ARMV7: mov r0, #1
490; CHECK-ARMV7: mov r1, #2
491; CHECK-ARMV7: mov r2, #3
492; CHECK-ARMV7: mov r3, #4
493; CHECK-ARMV7: mov r10, #0
494; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000495; Load swifterror %err;
Kristof Beylseecb3532017-06-28 07:07:03 +0000496; CHECK-ARMV7-DAG: ldr r8, [s[[STK1]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000497; Restore return values for returning.
Kristof Beylseecb3532017-06-28 07:07:03 +0000498; CHECK-ARMV7-DAG: mov r0, r4
499; CHECK-ARMV7-DAG: mov r1, r5
500; CHECK-ARMV7-DAG: mov r2, r6
501; CHECK-ARMV7-DAG: mov r3, r11
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000502; CHECK-ARMV7: pop {r4, r5, r6, r7, r10, r11, pc}
Brian Gesiak33329762017-08-30 20:03:54 +0000503
504; CHECK-ANDROID-LABEL: params_and_return_in_reg
Arnold Schwaighoferae4de582017-09-25 17:19:50 +0000505; CHECK-ANDROID: push {r4, r5, r6, r7, r9, r10, r11, lr}
506; CHECK-ANDROID: sub sp, sp, #16
507; CHECK-ANDROID: str r8, [sp, #4] @ 4-byte Spill
508; CHECK-ANDROID: mov r11, r10
509; CHECK-ANDROID: mov r6, r3
510; CHECK-ANDROID: mov r7, r2
511; CHECK-ANDROID: mov r4, r1
512; CHECK-ANDROID: mov r5, r0
513; CHECK-ANDROID: mov r0, #1
514; CHECK-ANDROID: mov r1, #2
515; CHECK-ANDROID: mov r2, #3
516; CHECK-ANDROID: mov r3, #4
517; CHECK-ANDROID: mov r10, #0
518; CHECK-ANDROID: mov r8, #0
519; CHECK-ANDROID: bl params_in_reg2
520; CHECK-ANDROID: mov r9, r8
521; CHECK-ANDROID: ldr r8, [sp, #4] @ 4-byte Reload
522; CHECK-ANDROID: mov r0, r5
523; CHECK-ANDROID: mov r1, r4
524; CHECK-ANDROID: mov r2, r7
525; CHECK-ANDROID: mov r3, r6
526; CHECK-ANDROID: mov r10, r11
527; CHECK-ANDROID: bl params_and_return_in_reg2
528; CHECK-ANDROID: mov r4, r0
529; CHECK-ANDROID: mov r5, r1
530; CHECK-ANDROID: mov r6, r2
531; CHECK-ANDROID: mov r7, r3
532; CHECK-ANDROID: mov r11, r8
533; CHECK-ANDROID: mov r0, #1
534; CHECK-ANDROID: mov r1, #2
535; CHECK-ANDROID: mov r2, #3
536; CHECK-ANDROID: mov r3, #4
537; CHECK-ANDROID: mov r10, #0
538; CHECK-ANDROID: mov r8, r9
539; CHECK-ANDROID: bl params_in_reg2
540; CHECK-ANDROID: mov r0, r4
541; CHECK-ANDROID: mov r1, r5
542; CHECK-ANDROID: mov r2, r6
543; CHECK-ANDROID: mov r3, r7
544; CHECK-ANDROID: mov r8, r11
545; CHECK-ANDROID: add sp, sp, #16
546; CHECK-ANDROID: pop {r4, r5, r6, r7, r9, r10, r11, pc}
Brian Gesiak33329762017-08-30 20:03:54 +0000547
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000548define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) {
549 %error_ptr_ref = alloca swifterror %swift_error*, align 8
550 store %swift_error* null, %swift_error** %error_ptr_ref
551 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
552 %val = call swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err)
553 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
554 ret { i32, i32, i32, i32 }%val
555}
556
557declare swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err)
Arnold Schwaighofer8f3df732017-02-13 19:58:28 +0000558
559
560declare void @acallee(i8*)
561
562; Make sure we don't tail call if the caller returns a swifterror value. We
563; would have to move into the swifterror register before the tail call.
564; CHECK-APPLE: tailcall_from_swifterror:
565; CHECK-APPLE-NOT: b _acallee
566; CHECK-APPLE: bl _acallee
Brian Gesiak33329762017-08-30 20:03:54 +0000567; CHECK-ANDROID: tailcall_from_swifterror:
568; CHECK-ANDROID-NOT: b acallee
569; CHECK-ANDROID: bl acallee
Arnold Schwaighofer8f3df732017-02-13 19:58:28 +0000570
571define swiftcc void @tailcall_from_swifterror(%swift_error** swifterror %error_ptr_ref) {
572entry:
573 tail call void @acallee(i8* null)
574 ret void
575}
Arnold Schwaighoferae9312c2017-06-15 17:34:42 +0000576
577
578declare swiftcc void @foo2(%swift_error** swifterror)
579
580; Make sure we properly assign registers during fast-isel.
581; CHECK-O0-LABEL: testAssign
582; CHECK-O0: mov r8, #0
583; CHECK-O0: bl _foo2
584; CHECK-O0: str r8, [s[[STK:p.*]]]
585; CHECK-O0: ldr r0, [s[[STK]]]
586; CHECK-O0: pop
587
588; CHECK-APPLE-LABEL: testAssign
589; CHECK-APPLE: mov r8, #0
590; CHECK-APPLE: bl _foo2
591; CHECK-APPLE: mov r0, r8
592
Brian Gesiak33329762017-08-30 20:03:54 +0000593; CHECK-ANDROID-LABEL: testAssign
594; CHECK-ANDROID: mov r8, #0
595; CHECK-ANDROID: bl foo2
596; CHECK-ANDROID: mov r0, r8
597
Arnold Schwaighoferae9312c2017-06-15 17:34:42 +0000598define swiftcc %swift_error* @testAssign(i8* %error_ref) {
599entry:
600 %error_ptr = alloca swifterror %swift_error*
601 store %swift_error* null, %swift_error** %error_ptr
602 call swiftcc void @foo2(%swift_error** swifterror %error_ptr)
603 br label %a
604
605a:
606 %error = load %swift_error*, %swift_error** %error_ptr
607 ret %swift_error* %error
608}