1; RUN: llc -mtriple riscv32-unknown-linux-gnu -o - %s | FileCheck %s
2; RUN: llc -mtriple riscv32-unknown-elf       -o - %s | FileCheck %s
3
4; Perform tail call optimization for global address.
5declare i32 @callee_tail(i32 %i)
6define i32 @caller_tail(i32 %i) nounwind {
7; CHECK-LABEL: caller_tail
8; CHECK: tail callee_tail
9entry:
10  %r = tail call i32 @callee_tail(i32 %i)
11  ret i32 %r
12}
13
14; Perform tail call optimization for external symbol.
15@dest = global [2 x i8] zeroinitializer
16declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
17define void @caller_extern(i8* %src) optsize {
18entry:
19; CHECK: caller_extern
20; CHECK-NOT: call memcpy
21; CHECK: tail memcpy
22  tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @dest, i32 0, i32 0), i8* %src, i32 7, i1 false)
23  ret void
24}
25
26; Perform tail call optimization for external symbol.
27@dest_pgso = global [2 x i8] zeroinitializer
28define void @caller_extern_pgso(i8* %src) !prof !14 {
29entry:
30; CHECK: caller_extern_pgso
31; CHECK-NOT: call memcpy
32; CHECK: tail memcpy
33  tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @dest_pgso, i32 0, i32 0), i8* %src, i32 7, i1 false)
34  ret void
35}
36
37; Perform indirect tail call optimization (for function pointer call).
38declare void @callee_indirect1()
39declare void @callee_indirect2()
40define void @caller_indirect_tail(i32 %a) nounwind {
41; CHECK-LABEL: caller_indirect_tail
42; CHECK-NOT: call callee_indirect1
43; CHECK-NOT: call callee_indirect2
44; CHECK-NOT: tail callee_indirect1
45; CHECK-NOT: tail callee_indirect2
46
47; CHECK: lui a0, %hi(callee_indirect2)
48; CHECK-NEXT: addi a5, a0, %lo(callee_indirect2)
49; CHECK-NEXT: jr a5
50
51; CHECK: lui a0, %hi(callee_indirect1)
52; CHECK-NEXT: addi a5, a0, %lo(callee_indirect1)
53; CHECK-NEXT: jr a5
54entry:
55  %tobool = icmp eq i32 %a, 0
56  %callee = select i1 %tobool, void ()* @callee_indirect1, void ()* @callee_indirect2
57  tail call void %callee()
58  ret void
59}
60
61; Do not tail call optimize functions with varargs passed by stack.
62declare i32 @callee_varargs(i32, ...)
63define void @caller_varargs(i32 %a, i32 %b) nounwind {
64; CHECK-LABEL: caller_varargs
65; CHECK-NOT: tail callee_varargs
66; CHECK: call callee_varargs
67entry:
68  %call = tail call i32 (i32, ...) @callee_varargs(i32 %a, i32 %b, i32 %b, i32 %a, i32 %a, i32 %b, i32 %b, i32 %a, i32 %a)
69  ret void
70}
71
72; Do not tail call optimize if stack is used to pass parameters.
73declare i32 @callee_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n)
74define i32 @caller_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n) nounwind {
75; CHECK-LABEL: caller_args
76; CHECK-NOT: tail callee_args
77; CHECK: call callee_args
78entry:
79  %r = tail call i32 @callee_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n)
80  ret i32 %r
81}
82
83; Do not tail call optimize if parameters need to be passed indirectly.
84declare i32 @callee_indirect_args(fp128 %a)
85define void @caller_indirect_args() nounwind {
86; CHECK-LABEL: caller_indirect_args
87; CHECK-NOT: tail callee_indirect_args
88; CHECK: call callee_indirect_args
89entry:
90  %call = tail call i32 @callee_indirect_args(fp128 0xL00000000000000003FFF000000000000)
91  ret void
92}
93
94; Externally-defined functions with weak linkage should not be tail-called.
95; The behaviour of branch instructions in this situation (as used for tail
96; calls) is implementation-defined, so we cannot rely on the linker replacing
97; the tail call with a return.
98declare extern_weak void @callee_weak()
99define void @caller_weak() nounwind {
100; CHECK-LABEL: caller_weak
101; CHECK-NOT: tail callee_weak
102; CHECK: call callee_weak
103entry:
104  tail call void @callee_weak()
105  ret void
106}
107
108; Exception-handling functions need a special set of instructions to indicate a
109; return to the hardware. Tail-calling another function would probably break
110; this.
111declare void @callee_irq()
112define void @caller_irq() #0 {
113; CHECK-LABEL: caller_irq
114; CHECK-NOT: tail callee_irq
115; CHECK: call callee_irq
116entry:
117  tail call void @callee_irq()
118  ret void
119}
120attributes #0 = { "interrupt"="machine" }
121
122; Byval parameters hand the function a pointer directly into the stack area
123; we want to reuse during a tail call. Do not tail call optimize functions with
124; byval parameters.
125declare i32 @callee_byval(i32** byval %a)
126define i32 @caller_byval() nounwind {
127; CHECK-LABEL: caller_byval
128; CHECK-NOT: tail callee_byval
129; CHECK: call callee_byval
130entry:
131  %a = alloca i32*
132  %r = tail call i32 @callee_byval(i32** byval %a)
133  ret i32 %r
134}
135
136; Do not tail call optimize if callee uses structret semantics.
137%struct.A = type { i32 }
138@a = global %struct.A zeroinitializer
139
140declare void @callee_struct(%struct.A* sret %a)
141define void @caller_nostruct() nounwind {
142; CHECK-LABEL: caller_nostruct
143; CHECK-NOT: tail callee_struct
144; CHECK: call callee_struct
145entry:
146  tail call void @callee_struct(%struct.A* sret @a)
147  ret void
148}
149
150; Do not tail call optimize if caller uses structret semantics.
151declare void @callee_nostruct()
152define void @caller_struct(%struct.A* sret %a) nounwind {
153; CHECK-LABEL: caller_struct
154; CHECK-NOT: tail callee_nostruct
155; CHECK: call callee_nostruct
156entry:
157  tail call void @callee_nostruct()
158  ret void
159}
160
161; Do not tail call optimize if disabled.
162define i32 @disable_tail_calls(i32 %i) nounwind "disable-tail-calls"="true" {
163; CHECK-LABEL: disable_tail_calls:
164; CHECK-NOT: tail callee_nostruct
165; CHECK: call callee_tail
166entry:
167  %rv = tail call i32 @callee_tail(i32 %i)
168  ret i32 %rv
169}
170
171; Duplicate returns to enable tail call optimizations.
172declare i32 @test()
173declare i32 @test1()
174declare i32 @test2()
175declare i32 @test3()
176define i32 @duplicate_returns(i32 %a, i32 %b) nounwind {
177; CHECK-LABEL: duplicate_returns:
178; CHECK:    tail test2
179; CHECK:    tail test
180; CHECK:    tail test1
181; CHECK:    tail test3
182entry:
183  %cmp = icmp eq i32 %a, 0
184  br i1 %cmp, label %if.then, label %if.else
185
186if.then:                                          ; preds = %entry
187  %call = tail call i32 @test()
188  br label %return
189
190if.else:                                          ; preds = %entry
191  %cmp1 = icmp eq i32 %b, 0
192  br i1 %cmp1, label %if.then2, label %if.else4
193
194if.then2:                                         ; preds = %if.else
195  %call3 = tail call i32 @test1()
196  br label %return
197
198if.else4:                                         ; preds = %if.else
199  %cmp5 = icmp sgt i32 %a, %b
200  br i1 %cmp5, label %if.then6, label %if.else8
201
202if.then6:                                         ; preds = %if.else4
203  %call7 = tail call i32 @test2()
204  br label %return
205
206if.else8:                                         ; preds = %if.else4
207  %call9 = tail call i32 @test3()
208  br label %return
209
210return:                                           ; preds = %if.else8, %if.then6, %if.then2, %if.then
211  %retval = phi i32 [ %call, %if.then ], [ %call3, %if.then2 ], [ %call7, %if.then6 ], [ %call9, %if.else8 ]
212  ret i32 %retval
213}
214
215!llvm.module.flags = !{!0}
216!0 = !{i32 1, !"ProfileSummary", !1}
217!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
218!2 = !{!"ProfileFormat", !"InstrProf"}
219!3 = !{!"TotalCount", i64 10000}
220!4 = !{!"MaxCount", i64 10}
221!5 = !{!"MaxInternalCount", i64 1}
222!6 = !{!"MaxFunctionCount", i64 1000}
223!7 = !{!"NumCounts", i64 3}
224!8 = !{!"NumFunctions", i64 3}
225!9 = !{!"DetailedSummary", !10}
226!10 = !{!11, !12, !13}
227!11 = !{i32 10000, i64 100, i32 1}
228!12 = !{i32 999000, i64 100, i32 1}
229!13 = !{i32 999999, i64 1, i32 2}
230!14 = !{!"function_entry_count", i64 0}
231