Add CodeGen support for functions that always return arguments via a new parameter...
[oota-llvm.git] / test / CodeGen / ARM / this-return.ll
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
3
4 %struct.A = type { i8 }
5 %struct.B = type { i32 }
6 %struct.C = type { %struct.B }
7 %struct.D = type { %struct.B }
8
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)
12
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)
16
17 define %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x) {
18 entry:
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)
33   ret %struct.C* %this
34 }
35
36 define %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) {
37 entry:
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)
52   ret %struct.C* %this
53 }
54
55 define %struct.C* @C_ctor_complete(%struct.C* %this, i32 %x) {
56 entry:
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)
62   ret %struct.C* %this
63 }
64
65 define %struct.C* @C_ctor_complete_nothisret(%struct.C* %this, i32 %x) {
66 entry:
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)
72   ret %struct.C* %this
73 }
74
75 define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
76 entry:
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)
90   ret %struct.D* %this
91 }