Recommit r310809 with a fix for the spill problem
[llvm-core.git] / test / CodeGen / PowerPC / ppc64-sibcall.ll
blob3c08ecb5119fb05b7d427f967d51d92e19199ebc
1 ; RUN: llc < %s -relocation-model=static -O1 -disable-ppc-sco=false -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s -check-prefix=CHECK-SCO
2 ; RUN: llc < %s -relocation-model=static -O1 -disable-ppc-sco=false -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-SCO-HASQPX
3 ; RUN: llc < %s -relocation-model=static -O1 -disable-ppc-sco=false -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-SCO-HASQPX
4 ; RUN: llc < %s -relocation-model=static -O1 -disable-ppc-sco=false -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -code-model=small | FileCheck %s -check-prefix=SCM
6 ; No combination of "powerpc64le-unknown-linux-gnu" + "CHECK-SCO", because
7 ; only Power8 (and later) fully support LE.
9 %S_56 = type { [13 x i32], i32 }
10 %S_64 = type { [15 x i32], i32 }
11 %S_32 = type { [7 x i32], i32 }
13 ; Function Attrs: noinline nounwind
14 define void @callee_56_copy([7 x i64] %a, %S_56* %b) #0 { ret void }
15 define void @callee_64_copy([8 x i64] %a, %S_64* %b) #0 { ret void }
17 ; Function Attrs: nounwind
18 define void @caller_56_reorder_copy(%S_56* %b, [7 x i64] %a) #1 {
19   tail call void @callee_56_copy([7 x i64] %a, %S_56* %b)
20   ret void
22 ; CHECK-SCO-LABEL: caller_56_reorder_copy:
23 ; CHECK-SCO-NOT: stdu 1
24 ; CHECK-SCO: TC_RETURNd8 callee_56_copy
27 define void @caller_64_reorder_copy(%S_64* %b, [8 x i64] %a) #1 {
28   tail call void @callee_64_copy([8 x i64] %a, %S_64* %b)
29   ret void
31 ; CHECK-SCO-LABEL: caller_64_reorder_copy:
32 ; CHECK-SCO: bl callee_64_copy
35 define void @callee_64_64_copy([8 x i64] %a, [8 x i64] %b) #0 { ret void }
36 define void @caller_64_64_copy([8 x i64] %a, [8 x i64] %b) #1 {
37   tail call void @callee_64_64_copy([8 x i64] %a, [8 x i64] %b)
38   ret void
40 ; CHECK-SCO-LABEL: caller_64_64_copy:
41 ; CHECK-SCO: b callee_64_64_copy
44 define void @caller_64_64_reorder_copy([8 x i64] %a, [8 x i64] %b) #1 {
45   tail call void @callee_64_64_copy([8 x i64] %b, [8 x i64] %a)
46   ret void
48 ; CHECK-SCO-LABEL: caller_64_64_reorder_copy:
49 ; CHECK-SCO: bl callee_64_64_copy
52 define void @caller_64_64_undef_copy([8 x i64] %a, [8 x i64] %b) #1 {
53   tail call void @callee_64_64_copy([8 x i64] %a, [8 x i64] undef)
54   ret void
56 ; CHECK-SCO-LABEL: caller_64_64_undef_copy:
57 ; CHECK-SCO: b callee_64_64_copy
60 define void @arg8_callee(
61   float %a, i32 signext %b, float %c, i32* %d,
62   i8 zeroext %e, float %f, i32* %g, i32 signext %h)
64   ret void
67 define void @arg8_caller(float %a, i32 signext %b, i8 zeroext %c, i32* %d) {
68 entry:
69   tail call void @arg8_callee(float undef, i32 signext undef, float undef,
70                               i32* %d, i8 zeroext undef, float undef,
71                               i32* undef, i32 signext undef)
72   ret void
74 ; CHECK-SCO-LABEL: arg8_caller:
75 ; CHECK-SCO: b arg8_callee
78 ; Struct return test
80 ; Function Attrs: noinline nounwind
81 define void @callee_sret_56(%S_56* noalias sret %agg.result) #0 { ret void }
82 define void @callee_sret_32(%S_32* noalias sret %agg.result) #0 { ret void }
84 ; Function Attrs: nounwind
85 define void @caller_do_something_sret_32(%S_32* noalias sret %agg.result) #1 {
86   %1 = alloca %S_56, align 4
87   %2 = bitcast %S_56* %1 to i8*
88   call void @callee_sret_56(%S_56* nonnull sret %1)
89   tail call void @callee_sret_32(%S_32* sret %agg.result)
90   ret void
92 ; CHECK-SCO-LABEL: caller_do_something_sret_32:
93 ; CHECK-SCO: stdu 1
94 ; CHECK-SCO: bl callee_sret_56
95 ; CHECK-SCO: addi 1
96 ; CHECK-SCO: TC_RETURNd8 callee_sret_32
99 define void @caller_local_sret_32(%S_32* %a) #1 {
100   %tmp = alloca %S_32, align 4
101   tail call void @callee_sret_32(%S_32* nonnull sret %tmp)
102   ret void
104 ; CHECK-SCO-LABEL: caller_local_sret_32:
105 ; CHECK-SCO: bl callee_sret_32
108 attributes #0 = { noinline nounwind  }
109 attributes #1 = { nounwind }
111 ; vector <4 x i1> test
113 define void @callee_v4i1(i8 %a, <4 x i1> %b, <4 x i1> %c) { ret void }
114 define void @caller_v4i1_reorder(i8 %a, <4 x i1> %b, <4 x i1> %c) {
115   tail call void @callee_v4i1(i8 %a, <4 x i1> %c, <4 x i1> %b)
116   ret void
118 ; <4 x i1> is 32 bytes aligned, if subtarget doesn't support qpx, then we can't
119 ; place b, c to qpx register, so we can't do sco on caller_v4i1_reorder
121 ; CHECK-SCO-LABEL: caller_v4i1_reorder:
122 ; CHECK-SCO: bl callee_v4i1
124 ; CHECK-SCO-HASQPX-LABEL: caller_v4i1_reorder:
125 ; CHECK-SCO-HASQPX: b callee_v4i1
128 define void @f128_callee(i32* %ptr, ppc_fp128 %a, ppc_fp128 %b) { ret void }
129 define void @f128_caller(i32* %ptr, ppc_fp128 %a, ppc_fp128 %b) {
130   tail call void @f128_callee(i32* %ptr, ppc_fp128 %a, ppc_fp128 %b)
131   ret void
133 ; CHECK-SCO-LABEL: f128_caller:
134 ; CHECK-SCO: b f128_callee
137 ; weak linkage test
138 %class.T = type { [2 x i8] }
140 define weak_odr hidden void @wo_hcallee(%class.T* %this, i8* %c) { ret void }
141 define void @wo_hcaller(%class.T* %this, i8* %c) {
142   tail call void @wo_hcallee(%class.T* %this, i8* %c)
143   ret void
145 ; CHECK-SCO-LABEL: wo_hcaller:
146 ; CHECK-SCO: b wo_hcallee
148 ; SCM-LABEL: wo_hcaller:
149 ; SCM:       bl wo_hcallee
152 define weak_odr protected void @wo_pcallee(%class.T* %this, i8* %c) { ret void }
153 define void @wo_pcaller(%class.T* %this, i8* %c) {
154   tail call void @wo_pcallee(%class.T* %this, i8* %c)
155   ret void
157 ; CHECK-SCO-LABEL: wo_pcaller:
158 ; CHECK-SCO: b wo_pcallee
160 ; SCM-LABEL: wo_pcaller:
161 ; SCM:       bl wo_pcallee
164 define weak_odr void @wo_callee(%class.T* %this, i8* %c) { ret void }
165 define void @wo_caller(%class.T* %this, i8* %c) {
166   tail call void @wo_callee(%class.T* %this, i8* %c)
167   ret void
169 ; CHECK-SCO-LABEL: wo_caller:
170 ; CHECK-SCO: b wo_callee
172 ; SCM-LABEL: wo_caller:
173 ; SCM:       bl wo_callee
176 define weak protected void @w_pcallee(i8* %ptr) { ret void }
177 define void @w_pcaller(i8* %ptr) {
178   tail call void @w_pcallee(i8* %ptr)
179   ret void
181 ; CHECK-SCO-LABEL: w_pcaller:
182 ; CHECK-SCO: b w_pcallee
184 ; SCM-LABEL: w_pcaller:
185 ; SCM:       bl w_pcallee
188 define weak hidden void @w_hcallee(i8* %ptr) { ret void }
189 define void @w_hcaller(i8* %ptr) {
190   tail call void @w_hcallee(i8* %ptr)
191   ret void
193 ; CHECK-SCO-LABEL: w_hcaller:
194 ; CHECK-SCO: b w_hcallee
196 ; SCM-LABEL: w_hcaller:
197 ; SCM:       bl w_hcallee
200 define weak void @w_callee(i8* %ptr) { ret void }
201 define void @w_caller(i8* %ptr) {
202   tail call void @w_callee(i8* %ptr)
203   ret void
205 ; CHECK-SCO-LABEL: w_caller:
206 ; CHECK-SCO: b w_callee
208 ; SCM-LABEL: w_caller:
209 ; SCM:       bl w_callee
212 %struct.byvalTest = type { [8 x i8] }
213 @byval = common global %struct.byvalTest zeroinitializer
215 define void @byval_callee(%struct.byvalTest* byval %ptr) { ret void }
216 define void @byval_caller() {
217   tail call void @byval_callee(%struct.byvalTest* byval @byval)
218   ret void
220 ; CHECK-SCO-LABEL: bl byval_callee
221 ; CHECK-SCO: bl byval_callee