1 ; RUN: llc < %s -mtriple=armv6-linux-gnueabi -arm-tail-calls | FileCheck %s -check-prefix=CHECKELF
2 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-tail-calls | FileCheck %s -check-prefix=CHECKT2D
4 %struct.A = type { i8 }
5 %struct.B = type { i32 }
6 %struct.C = type { %struct.B }
7 %struct.D = type { %struct.B }
9 declare %struct.A* @A_ctor_base(%struct.A* returned)
10 declare %struct.B* @B_ctor_base(%struct.B* returned, i32)
11 declare %struct.B* @B_ctor_complete(%struct.B* returned, i32)
13 declare %struct.A* @A_ctor_base_nothisret(%struct.A*)
14 declare %struct.B* @B_ctor_base_nothisret(%struct.B*, i32)
15 declare %struct.B* @B_ctor_complete_nothisret(%struct.B*, i32)
17 define %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x) {
19 ; CHECKELF: C_ctor_base:
20 ; CHECKELF-NOT: mov {{r[0-9]+}}, r0
21 ; CHECKELF: bl A_ctor_base
22 ; CHECKELF-NOT: mov r0, {{r[0-9]+}}
23 ; CHECKELF: b B_ctor_base
24 ; CHECKT2D: C_ctor_base:
25 ; CHECKT2D-NOT: mov {{r[0-9]+}}, r0
26 ; CHECKT2D: blx _A_ctor_base
27 ; CHECKT2D-NOT: mov r0, {{r[0-9]+}}
28 ; CHECKT2D: b.w _B_ctor_base
29 %0 = bitcast %struct.C* %this to %struct.A*
30 %call = tail call %struct.A* @A_ctor_base(%struct.A* %0)
31 %1 = getelementptr inbounds %struct.C* %this, i32 0, i32 0
32 %call2 = tail call %struct.B* @B_ctor_base(%struct.B* %1, i32 %x)
36 define %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) {
38 ; CHECKELF: C_ctor_base_nothisret:
39 ; CHECKELF: mov [[SAVETHIS:r[0-9]+]], r0
40 ; CHECKELF: bl A_ctor_base_nothisret
41 ; CHECKELF: mov r0, [[SAVETHIS]]
42 ; CHECKELF-NOT: b B_ctor_base_nothisret
43 ; CHECKT2D: C_ctor_base_nothisret:
44 ; CHECKT2D: mov [[SAVETHIS:r[0-9]+]], r0
45 ; CHECKT2D: blx _A_ctor_base_nothisret
46 ; CHECKT2D: mov r0, [[SAVETHIS]]
47 ; CHECKT2D-NOT: b.w _B_ctor_base_nothisret
48 %0 = bitcast %struct.C* %this to %struct.A*
49 %call = tail call %struct.A* @A_ctor_base_nothisret(%struct.A* %0)
50 %1 = getelementptr inbounds %struct.C* %this, i32 0, i32 0
51 %call2 = tail call %struct.B* @B_ctor_base_nothisret(%struct.B* %1, i32 %x)
55 define %struct.C* @C_ctor_complete(%struct.C* %this, i32 %x) {
57 ; CHECKELF: C_ctor_complete:
58 ; CHECKELF: b C_ctor_base
59 ; CHECKT2D: C_ctor_complete:
60 ; CHECKT2D: b.w _C_ctor_base
61 %call = tail call %struct.C* @C_ctor_base(%struct.C* %this, i32 %x)
65 define %struct.C* @C_ctor_complete_nothisret(%struct.C* %this, i32 %x) {
67 ; CHECKELF: C_ctor_complete_nothisret:
68 ; CHECKELF-NOT: b C_ctor_base_nothisret
69 ; CHECKT2D: C_ctor_complete_nothisret:
70 ; CHECKT2D-NOT: b.w _C_ctor_base_nothisret
71 %call = tail call %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x)
75 define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
77 ; CHECKELF: D_ctor_base:
78 ; CHECKELF-NOT: mov {{r[0-9]+}}, r0
79 ; CHECKELF: bl B_ctor_complete
80 ; CHECKELF-NOT: mov r0, {{r[0-9]+}}
81 ; CHECKELF: b B_ctor_complete
82 ; CHECKT2D: D_ctor_base:
83 ; CHECKT2D-NOT: mov {{r[0-9]+}}, r0
84 ; CHECKT2D: blx _B_ctor_complete
85 ; CHECKT2D-NOT: mov r0, {{r[0-9]+}}
86 ; CHECKT2D: b.w _B_ctor_complete
87 %b = getelementptr inbounds %struct.D* %this, i32 0, i32 0
88 %call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
89 %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)