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 }
8
%struct.E = type { %struct.B, %struct.B }
10
declare %struct.A* @A_ctor_base(%struct.A* returned)
11
declare %struct.B* @B_ctor_base(%struct.B* returned, i32)
12
declare %struct.B* @B_ctor_complete(%struct.B* returned, i32)
14
declare %struct.A* @A_ctor_base_nothisret(%struct.A*)
15
declare %struct.B* @B_ctor_base_nothisret(%struct.B*, i32)
16
declare %struct.B* @B_ctor_complete_nothisret(%struct.B*, i32)
18
define %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x) {
20
; CHECKELF: C_ctor_base:
21
; CHECKELF-NOT: mov {{r[0-9]+}}, r0
22
; CHECKELF: bl A_ctor_base
23
; CHECKELF-NOT: mov r0, {{r[0-9]+}}
24
; CHECKELF: b B_ctor_base
25
; CHECKT2D: C_ctor_base:
26
; CHECKT2D-NOT: mov {{r[0-9]+}}, r0
27
; CHECKT2D: blx _A_ctor_base
28
; CHECKT2D-NOT: mov r0, {{r[0-9]+}}
29
; CHECKT2D: b.w _B_ctor_base
30
%0 = bitcast %struct.C* %this to %struct.A*
31
%call = tail call %struct.A* @A_ctor_base(%struct.A* %0)
32
%1 = getelementptr inbounds %struct.C* %this, i32 0, i32 0
33
%call2 = tail call %struct.B* @B_ctor_base(%struct.B* %1, i32 %x)
37
define %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) {
39
; CHECKELF: C_ctor_base_nothisret:
40
; CHECKELF: mov [[SAVETHIS:r[0-9]+]], r0
41
; CHECKELF: bl A_ctor_base_nothisret
42
; CHECKELF: mov r0, [[SAVETHIS]]
43
; CHECKELF-NOT: b B_ctor_base_nothisret
44
; CHECKT2D: C_ctor_base_nothisret:
45
; CHECKT2D: mov [[SAVETHIS:r[0-9]+]], r0
46
; CHECKT2D: blx _A_ctor_base_nothisret
47
; CHECKT2D: mov r0, [[SAVETHIS]]
48
; CHECKT2D-NOT: b.w _B_ctor_base_nothisret
49
%0 = bitcast %struct.C* %this to %struct.A*
50
%call = tail call %struct.A* @A_ctor_base_nothisret(%struct.A* %0)
51
%1 = getelementptr inbounds %struct.C* %this, i32 0, i32 0
52
%call2 = tail call %struct.B* @B_ctor_base_nothisret(%struct.B* %1, i32 %x)
56
define %struct.C* @C_ctor_complete(%struct.C* %this, i32 %x) {
58
; CHECKELF: C_ctor_complete:
59
; CHECKELF: b C_ctor_base
60
; CHECKT2D: C_ctor_complete:
61
; CHECKT2D: b.w _C_ctor_base
62
%call = tail call %struct.C* @C_ctor_base(%struct.C* %this, i32 %x)
66
define %struct.C* @C_ctor_complete_nothisret(%struct.C* %this, i32 %x) {
68
; CHECKELF: C_ctor_complete_nothisret:
69
; CHECKELF-NOT: b C_ctor_base_nothisret
70
; CHECKT2D: C_ctor_complete_nothisret:
71
; CHECKT2D-NOT: b.w _C_ctor_base_nothisret
72
%call = tail call %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x)
76
define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
78
; CHECKELF: D_ctor_base:
79
; CHECKELF-NOT: mov {{r[0-9]+}}, r0
80
; CHECKELF: bl B_ctor_complete
81
; CHECKELF-NOT: mov r0, {{r[0-9]+}}
82
; CHECKELF: b B_ctor_complete
83
; CHECKT2D: D_ctor_base:
84
; CHECKT2D-NOT: mov {{r[0-9]+}}, r0
85
; CHECKT2D: blx _B_ctor_complete
86
; CHECKT2D-NOT: mov r0, {{r[0-9]+}}
87
; CHECKT2D: b.w _B_ctor_complete
88
%b = getelementptr inbounds %struct.D* %this, i32 0, i32 0
89
%call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
90
%call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
94
define %struct.E* @E_ctor_base(%struct.E* %this, i32 %x) {
96
; CHECKELF: E_ctor_base:
97
; CHECKELF-NOT: b B_ctor_complete
98
; CHECKT2D: E_ctor_base:
99
; CHECKT2D-NOT: b.w _B_ctor_complete
100
%b = getelementptr inbounds %struct.E* %this, i32 0, i32 0
101
%call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
102
%b2 = getelementptr inbounds %struct.E* %this, i32 0, i32 1
103
%call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b2, i32 %x)