1; RUN: llc -march=mipsel -relocation-model=pic  \
2; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC32
3; RUN: llc -march=mipsel -relocation-model=static  \
4; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32
5; RUN: llc -march=mips64el -mcpu=mips64r2  -relocation-model=pic \
6; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC64
7; RUN: llc -march=mips64el -mcpu=mips64r2  -relocation-model=static \
8; RUN:     -verify-machineinstrs -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC64
9; RUN: llc -march=mipsel -mattr=mips16 -relocation-model=pic \
10; RUN:      -verify-machineinstrs -mips-tail-calls=1 < %s | \
11; RUN:     FileCheck %s -check-prefixes=ALL,PIC16
12
13; RUN: llc -march=mipsel -relocation-model=pic -mattr=+micromips -verify-machineinstrs \
14; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC32MM
15; RUN: llc -march=mipsel -relocation-model=static -mattr=+micromips -verify-machineinstrs \
16; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32
17
18; RUN: llc -march=mipsel -relocation-model=pic -mcpu=mips32r6 -verify-machineinstrs \
19; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC32R6
20; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r2 -verify-machineinstrs \
21; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32
22; RUN: llc -march=mips64el -relocation-model=pic -mcpu=mips64r2 -verify-machineinstrs \
23; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=PIC64
24; RUN: llc -march=mips64el -relocation-model=pic -mcpu=mips64r6 -verify-machineinstrs \
25; RUN:     -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=STATIC64
26
27; RUN: llc -march=mipsel -relocation-model=pic -mcpu=mips32r6 -mattr=+micromips -verify-machineinstrs \
28; RUN:      -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,PIC32MM
29; RUN: llc -march=mipsel -relocation-model=static -mcpu=mips32r6 -verify-machineinstrs \
30; RUN:     -mattr=+micromips -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,STATIC32MMR6
31
32@g0 = common global i32 0, align 4
33@g1 = common global i32 0, align 4
34@g2 = common global i32 0, align 4
35@g3 = common global i32 0, align 4
36@g4 = common global i32 0, align 4
37@g5 = common global i32 0, align 4
38@g6 = common global i32 0, align 4
39@g7 = common global i32 0, align 4
40@g8 = common global i32 0, align 4
41@g9 = common global i32 0, align 4
42
43define i32 @caller1(i32 %a0) nounwind {
44entry:
45; ALL-LABEL: caller1:
46; PIC32: jalr $25
47; PIC32MM: jalr $25
48; PIC32R6: jalr $25
49; STATIC32: jal
50; STATIC32MMR6: balc
51; N64: jalr $25
52; N64R6: jalr $25
53; PIC16: jalrc
54
55  %call = tail call i32 @callee1(i32 1, i32 1, i32 1, i32 %a0) nounwind
56  ret i32 %call
57}
58
59declare i32 @callee1(i32, i32, i32, i32)
60
61define i32 @caller2(i32 %a0, i32 %a1, i32 %a2, i32 %a3) nounwind {
62entry:
63; ALL-LABEL: caller2
64; PIC32: jalr $25
65; PIC32MM: jalr $25
66; PIC32R6: jalr $25
67; STATIC32: jal
68; STATIC32MMR6: balc
69; N64: jalr $25
70; N64R6: jalr $25
71; PIC16: jalrc
72
73  %call = tail call i32 @callee2(i32 1, i32 %a0, i32 %a1, i32 %a2, i32 %a3) nounwind
74  ret i32 %call
75}
76
77declare i32 @callee2(i32, i32, i32, i32, i32)
78
79define i32 @caller3(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4) nounwind {
80entry:
81; ALL-LABEL: caller3:
82; PIC32: jalr $25
83; PIC32R6: jalr $25
84; PIC32MM: jalr $25
85; STATIC32: jal
86; STATIC32MMR6: balc
87; N64: jalr $25
88; N64R6: jalr $25
89; PIC16: jalrc
90
91  %call = tail call i32 @callee3(i32 1, i32 1, i32 1, i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4) nounwind
92  ret i32 %call
93}
94
95declare i32 @callee3(i32, i32, i32, i32, i32, i32, i32, i32)
96
97define i32 @caller4(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) nounwind {
98entry:
99; ALL-LABEL: caller4:
100; PIC32: jalr $25
101; PIC32R6: jalr $25
102; PIC32MM: jalr $25
103; STATIC32: jal
104; SATATIC32MMR6: jal
105; PIC64: jalr $25
106; STATIC64: jal
107; N64R6: jalr $25
108; PIC16: jalrc
109
110  %call = tail call i32 @callee4(i32 1, i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) nounwind
111  ret i32 %call
112}
113
114declare i32 @callee4(i32, i32, i32, i32, i32, i32, i32, i32, i32)
115
116define i32 @caller5() nounwind readonly {
117entry:
118; ALL-LABEL: caller5:
119; PIC32: jr $25
120; PIC32R6: jr $25
121; PIC32MM: jr
122; STATIC32: j
123; STATIC32MMR6: bc
124; PIC64: jr $25
125; STATIC64: j
126; PIC16: jalrc
127
128  %0 = load i32, i32* @g0, align 4
129  %1 = load i32, i32* @g1, align 4
130  %2 = load i32, i32* @g2, align 4
131  %3 = load i32, i32* @g3, align 4
132  %4 = load i32, i32* @g4, align 4
133  %5 = load i32, i32* @g5, align 4
134  %6 = load i32, i32* @g6, align 4
135  %7 = load i32, i32* @g7, align 4
136  %8 = load i32, i32* @g8, align 4
137  %9 = load i32, i32* @g9, align 4
138  %call = tail call fastcc i32 @callee5(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, i32 %8, i32 %9)
139  ret i32 %call
140}
141
142define internal fastcc i32 @callee5(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8, i32 %a9) nounwind readnone noinline {
143entry:
144  %add = add nsw i32 %a1, %a0
145  %add1 = add nsw i32 %add, %a2
146  %add2 = add nsw i32 %add1, %a3
147  %add3 = add nsw i32 %add2, %a4
148  %add4 = add nsw i32 %add3, %a5
149  %add5 = add nsw i32 %add4, %a6
150  %add6 = add nsw i32 %add5, %a7
151  %add7 = add nsw i32 %add6, %a8
152  %add8 = add nsw i32 %add7, %a9
153  ret i32 %add8
154}
155
156declare i32 @callee8(i32, ...)
157
158define i32 @caller8_0() nounwind {
159entry:
160; ALL-LABEL: caller8_0:
161; PIC32: jr $25
162; PIC32R6: jrc $25
163; PIC32MM: jrc
164; STATIC32: j
165; STATIC32MMR6: bc
166; PIC64: jr $25
167; PIC64R6: jrc $25
168; STATIC64: j
169; PIC16: jalrc
170
171  %call = tail call fastcc i32 @caller8_1()
172  ret i32 %call
173}
174
175define internal fastcc i32 @caller8_1() nounwind noinline {
176entry:
177; ALL-LABEL: caller8_1:
178; PIC32: jalr $25
179; PIC32R6: jalr $25
180; PIC32MM: jalr $25
181; STATIC32: jal
182; STATIC32MMR6: balc
183; PIC64: jalr $25
184; STATIC64: jal
185; PIC16: jalrc
186
187  %call = tail call i32 (i32, ...) @callee8(i32 2, i32 1) nounwind
188  ret i32 %call
189}
190
191%struct.S = type { [2 x i32] }
192
193@gs1 = external global %struct.S
194
195declare i32 @callee9(%struct.S* byval(%struct.S))
196
197define i32 @caller9_0() nounwind {
198entry:
199; ALL-LABEL: caller9_0:
200; PIC32: jr $25
201; PIC32R6: jrc $25
202; PIC32MM: jrc
203; STATIC32: j
204; STATIC32MMR6: bc
205; PIC64: jr $25
206; STATIC64: j
207; PIC64R6: jrc $25
208; PIC16: jalrc
209  %call = tail call fastcc i32 @caller9_1()
210  ret i32 %call
211}
212
213define internal fastcc i32 @caller9_1() nounwind noinline {
214entry:
215; ALL-LABEL: caller9_1:
216; PIC32: jalr $25
217; PIC32R6: jalrc $25
218; PIC32MM: jalr $25
219; STATIC32: jal
220; STATIC32MMR6: balc
221; STATIC64: jal
222; PIC64: jalr $25
223; PIC64R6: jalrc $25
224; PIC16: jalrc
225
226  %call = tail call i32 @callee9(%struct.S* byval(%struct.S) @gs1) nounwind
227  ret i32 %call
228}
229
230declare i32 @callee10(i32, i32, i32, i32, i32, i32, i32, i32, i32)
231
232define i32 @caller10(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8) nounwind {
233entry:
234; ALL-LABEL: caller10:
235; PIC32: jalr $25
236; PIC32R6: jalr $25
237; PIC32MM: jalr $25
238; STATIC32: jal
239; STATIC32MMR6: balc
240; STATIC64: jal
241; PIC64: jalr $25
242; PIC64R6: jalr $25
243; PIC16: jalrc
244
245  %call = tail call i32 @callee10(i32 %a8, i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) nounwind
246  ret i32 %call
247}
248
249declare i32 @callee11(%struct.S* byval(%struct.S))
250
251define i32 @caller11() nounwind noinline {
252entry:
253; ALL-LABEL: caller11:
254; PIC32: jalr $25
255; PIC32R6: jalrc $25
256; PIC32MM: jalr $25
257; STATIC32: jal
258; STATIC32MMR6: balc
259; STATIC64: jal
260; PIC64: jalr $25
261; PIC64R6: jalrc $25
262; PIC16: jalrc
263
264  %call = tail call i32 @callee11(%struct.S* byval(%struct.S) @gs1) nounwind
265  ret i32 %call
266}
267
268declare i32 @callee12()
269
270declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
271
272define i32 @caller12(%struct.S* nocapture byval(%struct.S) %a0) nounwind {
273entry:
274; ALL-LABEL: caller12:
275; PIC32: jalr $25
276; PIC32R6: jalrc $25
277; PIC32MM: jalr $25
278; STATIC32: jal
279; STATIC32MMR6: balc
280; STATIC64: jal
281; PIC64: jalr $25
282; PIC64R6: jalrc $25
283; PIC16: jalrc
284
285  %0 = bitcast %struct.S* %a0 to i8*
286  tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 bitcast (%struct.S* @gs1 to i8*), i8* align 4 %0, i32 8, i1 false)
287  %call = tail call i32 @callee12() nounwind
288  ret i32 %call
289}
290
291declare i32 @callee13(i32, ...)
292
293define i32 @caller13() nounwind {
294entry:
295; ALL-LABEL: caller13:
296; PIC32: jalr $25
297; PIC32R6: jalr $25
298; PIC32MM: jalr $25
299; STATIC32: jal
300; STATIC32MMR6: balc
301; STATIC64: jal
302; PIC64R6: jalr $25
303; PIC64: jalr $25
304; PIC16: jalrc
305
306  %call = tail call i32 (i32, ...) @callee13(i32 1, i32 2) nounwind
307  ret i32 %call
308}
309
310; Check that there is a chain edge between the load and store nodes.
311;
312; ALL-LABEL: caller14:
313; PIC32: lw ${{[0-9]+}}, 48($sp)
314; PIC32: sw $4, 16($sp)
315
316; PIC32MM: lw ${{[0-9]+}}, 48($sp)
317; PIC32MM: sw16 $4, 16(${{[0-9]+}})
318
319define void @caller14(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
320entry:
321  tail call void @callee14(i32 %e, i32 %b, i32 %c, i32 %d, i32 %a)
322  ret void
323}
324
325declare void @callee14(i32, i32, i32, i32, i32)
326