Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / RISCV / tail-calls.ll
blobe3079424230bcc31fd4d69232114500364f6010a
1 ; RUN: llc -mtriple riscv32-unknown-linux-gnu -o - %s | FileCheck %s
2 ; RUN: llc -mtriple riscv32-unknown-elf       -o - %s | FileCheck %s
4 ; Perform tail call optimization for global address.
5 declare i32 @callee_tail(i32 %i)
6 define i32 @caller_tail(i32 %i) nounwind {
7 ; CHECK-LABEL: caller_tail
8 ; CHECK: tail callee_tail
9 entry:
10   %r = tail call i32 @callee_tail(i32 %i)
11   ret i32 %r
14 ; Perform tail call optimization for external symbol.
15 @dest = global [2 x i8] zeroinitializer
16 declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1)
17 define void @caller_extern(ptr %src) optsize {
18 entry:
19 ; CHECK: caller_extern
20 ; CHECK-NOT: call memcpy
21 ; CHECK: tail memcpy
22   tail call void @llvm.memcpy.p0.p0.i32(ptr @dest, ptr %src, i32 7, i1 false)
23   ret void
26 ; Perform tail call optimization for external symbol.
27 @dest_pgso = global [2 x i8] zeroinitializer
28 define void @caller_extern_pgso(ptr %src) !prof !14 {
29 entry:
30 ; CHECK: caller_extern_pgso
31 ; CHECK-NOT: call memcpy
32 ; CHECK: tail memcpy
33   tail call void @llvm.memcpy.p0.p0.i32(ptr @dest_pgso, ptr %src, i32 7, i1 false)
34   ret void
37 ; Perform indirect tail call optimization (for function pointer call).
38 declare void @callee_indirect1()
39 declare void @callee_indirect2()
40 define 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
47 ; CHECK: lui a0, %hi(callee_indirect2)
48 ; CHECK-NEXT: addi t1, a0, %lo(callee_indirect2)
49 ; CHECK-NEXT: jr t1
51 ; CHECK: lui a0, %hi(callee_indirect1)
52 ; CHECK-NEXT: addi t1, a0, %lo(callee_indirect1)
53 ; CHECK-NEXT: jr t1
54 entry:
55   %tobool = icmp eq i32 %a, 0
56   %callee = select i1 %tobool, ptr @callee_indirect1, ptr @callee_indirect2
57   tail call void %callee()
58   ret void
61 ; Make sure we don't use t0 as the source for jr as that is a hint to pop the
62 ; return address stack on some microarchitectures.
63 define i32 @caller_indirect_no_t0(ptr %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7) {
64 ; CHECK-LABEL: caller_indirect_no_t0:
65 ; CHECK:       # %bb.0:
66 ; CHECK-NEXT:    mv t1, a0
67 ; CHECK-NEXT:    mv a0, a1
68 ; CHECK-NEXT:    mv a1, a2
69 ; CHECK-NEXT:    mv a2, a3
70 ; CHECK-NEXT:    mv a3, a4
71 ; CHECK-NEXT:    mv a4, a5
72 ; CHECK-NEXT:    mv a5, a6
73 ; CHECK-NEXT:    mv a6, a7
74 ; CHECK-NEXT:    jr t1
75   %9 = tail call i32 %0(i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7)
76   ret i32 %9
79 ; Do not tail call optimize functions with varargs passed by stack.
80 declare i32 @callee_varargs(i32, ...)
81 define void @caller_varargs(i32 %a, i32 %b) nounwind {
82 ; CHECK-LABEL: caller_varargs
83 ; CHECK-NOT: tail callee_varargs
84 ; CHECK: call callee_varargs
85 entry:
86   %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)
87   ret void
90 ; Do not tail call optimize if stack is used to pass parameters.
91 declare 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)
92 define 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 {
93 ; CHECK-LABEL: caller_args
94 ; CHECK-NOT: tail callee_args
95 ; CHECK: call callee_args
96 entry:
97   %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)
98   ret i32 %r
101 ; Do not tail call optimize if parameters need to be passed indirectly.
102 declare i32 @callee_indirect_args(fp128 %a)
103 define void @caller_indirect_args() nounwind {
104 ; CHECK-LABEL: caller_indirect_args
105 ; CHECK-NOT: tail callee_indirect_args
106 ; CHECK: call callee_indirect_args
107 entry:
108   %call = tail call i32 @callee_indirect_args(fp128 0xL00000000000000003FFF000000000000)
109   ret void
112 ; Perform tail call optimization for external weak symbol.
113 declare extern_weak void @callee_weak()
114 define void @caller_weak() nounwind {
115 ; CHECK-LABEL: caller_weak
116 ; CHECK: tail callee_weak
117 entry:
118   tail call void @callee_weak()
119   ret void
122 ; Exception-handling functions need a special set of instructions to indicate a
123 ; return to the hardware. Tail-calling another function would probably break
124 ; this.
125 declare void @callee_irq()
126 define void @caller_irq() #0 {
127 ; CHECK-LABEL: caller_irq
128 ; CHECK-NOT: tail callee_irq
129 ; CHECK: call callee_irq
130 entry:
131   tail call void @callee_irq()
132   ret void
134 attributes #0 = { "interrupt"="machine" }
136 ; Byval parameters hand the function a pointer directly into the stack area
137 ; we want to reuse during a tail call. Do not tail call optimize functions with
138 ; byval parameters.
139 declare i32 @callee_byval(ptr byval(ptr) %a)
140 define i32 @caller_byval() nounwind {
141 ; CHECK-LABEL: caller_byval
142 ; CHECK-NOT: tail callee_byval
143 ; CHECK: call callee_byval
144 entry:
145   %a = alloca ptr
146   %r = tail call i32 @callee_byval(ptr byval(ptr) %a)
147   ret i32 %r
150 ; Do not tail call optimize if callee uses structret semantics.
151 %struct.A = type { i32 }
152 @a = global %struct.A zeroinitializer
154 declare void @callee_struct(ptr sret(%struct.A) %a)
155 define void @caller_nostruct() nounwind {
156 ; CHECK-LABEL: caller_nostruct
157 ; CHECK-NOT: tail callee_struct
158 ; CHECK: call callee_struct
159 entry:
160   tail call void @callee_struct(ptr sret(%struct.A) @a)
161   ret void
164 ; Do not tail call optimize if caller uses structret semantics.
165 declare void @callee_nostruct()
166 define void @caller_struct(ptr sret(%struct.A) %a) nounwind {
167 ; CHECK-LABEL: caller_struct
168 ; CHECK-NOT: tail callee_nostruct
169 ; CHECK: call callee_nostruct
170 entry:
171   tail call void @callee_nostruct()
172   ret void
175 ; Do not tail call optimize if disabled.
176 define i32 @disable_tail_calls(i32 %i) nounwind "disable-tail-calls"="true" {
177 ; CHECK-LABEL: disable_tail_calls:
178 ; CHECK-NOT: tail callee_nostruct
179 ; CHECK: call callee_tail
180 entry:
181   %rv = tail call i32 @callee_tail(i32 %i)
182   ret i32 %rv
185 ; Duplicate returns to enable tail call optimizations.
186 declare i32 @test()
187 declare i32 @test1()
188 declare i32 @test2()
189 declare i32 @test3()
190 define i32 @duplicate_returns(i32 %a, i32 %b) nounwind {
191 ; CHECK-LABEL: duplicate_returns:
192 ; CHECK:    tail test2
193 ; CHECK:    tail test
194 ; CHECK:    tail test1
195 ; CHECK:    tail test3
196 entry:
197   %cmp = icmp eq i32 %a, 0
198   br i1 %cmp, label %if.then, label %if.else
200 if.then:                                          ; preds = %entry
201   %call = tail call i32 @test()
202   br label %return
204 if.else:                                          ; preds = %entry
205   %cmp1 = icmp eq i32 %b, 0
206   br i1 %cmp1, label %if.then2, label %if.else4
208 if.then2:                                         ; preds = %if.else
209   %call3 = tail call i32 @test1()
210   br label %return
212 if.else4:                                         ; preds = %if.else
213   %cmp5 = icmp sgt i32 %a, %b
214   br i1 %cmp5, label %if.then6, label %if.else8
216 if.then6:                                         ; preds = %if.else4
217   %call7 = tail call i32 @test2()
218   br label %return
220 if.else8:                                         ; preds = %if.else4
221   %call9 = tail call i32 @test3()
222   br label %return
224 return:                                           ; preds = %if.else8, %if.then6, %if.then2, %if.then
225   %retval = phi i32 [ %call, %if.then ], [ %call3, %if.then2 ], [ %call7, %if.then6 ], [ %call9, %if.else8 ]
226   ret i32 %retval
229 !llvm.module.flags = !{!0}
230 !0 = !{i32 1, !"ProfileSummary", !1}
231 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
232 !2 = !{!"ProfileFormat", !"InstrProf"}
233 !3 = !{!"TotalCount", i64 10000}
234 !4 = !{!"MaxCount", i64 10}
235 !5 = !{!"MaxInternalCount", i64 1}
236 !6 = !{!"MaxFunctionCount", i64 1000}
237 !7 = !{!"NumCounts", i64 3}
238 !8 = !{!"NumFunctions", i64 3}
239 !9 = !{!"DetailedSummary", !10}
240 !10 = !{!11, !12, !13}
241 !11 = !{i32 10000, i64 100, i32 1}
242 !12 = !{i32 999000, i64 100, i32 1}
243 !13 = !{i32 999999, i64 1, i32 2}
244 !14 = !{!"function_entry_count", i64 0}