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