1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=sparc -verify-machineinstrs | FileCheck %s
3
4define i32 @simple_leaf(i32 %i) #0 {
5; CHECK-LABEL: simple_leaf:
6; CHECK:       ! %bb.0: ! %entry
7; CHECK-NEXT:    mov %o7, %g1
8; CHECK-NEXT:    call foo
9; CHECK-NEXT:    mov %g1, %o7
10entry:
11  %call = tail call i32 @foo(i32 %i)
12  ret i32 %call
13}
14
15define i32 @simple_standard(i32 %i) #1 {
16; CHECK-LABEL: simple_standard:
17; CHECK:       ! %bb.0: ! %entry
18; CHECK-NEXT:    save %sp, -96, %sp
19; CHECK-NEXT:    call foo
20; CHECK-NEXT:    restore
21entry:
22  %call = tail call i32 @foo(i32 %i)
23  ret i32 %call
24}
25
26define i32 @extra_arg_leaf(i32 %i) #0 {
27; CHECK-LABEL: extra_arg_leaf:
28; CHECK:       ! %bb.0: ! %entry
29; CHECK-NEXT:    mov 12, %o1
30; CHECK-NEXT:    mov %o7, %g1
31; CHECK-NEXT:    call foo2
32; CHECK-NEXT:    mov %g1, %o7
33entry:
34  %call = tail call i32 @foo2(i32 %i, i32 12)
35  ret i32 %call
36}
37
38define i32 @extra_arg_standard(i32 %i) #1 {
39; CHECK-LABEL: extra_arg_standard:
40; CHECK:       ! %bb.0: ! %entry
41; CHECK-NEXT:    save %sp, -96, %sp
42; CHECK-NEXT:    call foo2
43; CHECK-NEXT:    restore %g0, 12, %o1
44entry:
45  %call = tail call i32 @foo2(i32 %i, i32 12)
46  ret i32 %call
47}
48
49; Perform tail call optimization for external symbol.
50
51define void @caller_extern(i8* %src) optsize #0 {
52; CHECK-LABEL: caller_extern:
53; CHECK:       ! %bb.0: ! %entry
54; CHECK-NEXT:    sethi %hi(dest), %o1
55; CHECK-NEXT:    add %o1, %lo(dest), %o1
56; CHECK-NEXT:    mov 7, %o2
57; CHECK-NEXT:    mov %o0, %o3
58; CHECK-NEXT:    mov %o1, %o0
59; CHECK-NEXT:    mov %o3, %o1
60; CHECK-NEXT:    mov %o7, %g1
61; CHECK-NEXT:    call memcpy
62; CHECK-NEXT:    mov %g1, %o7
63entry:
64  tail call void @llvm.memcpy.p0i8.p0i8.i32(
65    i8* getelementptr inbounds ([2 x i8],
66    [2 x i8]* @dest, i32 0, i32 0),
67    i8* %src, i32 7, i1 false)
68  ret void
69}
70
71; Perform tail call optimization for function pointer.
72
73define i32 @func_ptr_test(i32 ()* nocapture %func_ptr) #0 {
74; CHECK-LABEL: func_ptr_test:
75; CHECK:       ! %bb.0: ! %entry
76; CHECK-NEXT:    jmp %o0
77; CHECK-NEXT:    nop
78entry:
79  %call = tail call i32 %func_ptr() #1
80  ret i32 %call
81}
82
83define i32 @func_ptr_test2(i32 (i32, i32, i32)* nocapture %func_ptr,
84; CHECK-LABEL: func_ptr_test2:
85; CHECK:       ! %bb.0: ! %entry
86; CHECK-NEXT:    save %sp, -96, %sp
87; CHECK-NEXT:    mov 10, %i3
88; CHECK-NEXT:    mov %i0, %i4
89; CHECK-NEXT:    mov %i1, %i0
90; CHECK-NEXT:    jmp %i4
91; CHECK-NEXT:    restore %g0, %i3, %o1
92                           i32 %r, i32 %q) #1 {
93entry:
94  %call = tail call i32 %func_ptr(i32 %r, i32 10, i32 %q) #1
95  ret i32 %call
96}
97
98
99; Do not tail call optimize if stack is used to pass parameters.
100
101define i32 @caller_args() #0 {
102; CHECK-LABEL: caller_args:
103; CHECK:       ! %bb.0: ! %entry
104; CHECK-NEXT:    save %sp, -104, %sp
105; CHECK-NEXT:    mov 6, %i0
106; CHECK-NEXT:    mov %g0, %o0
107; CHECK-NEXT:    mov 1, %o1
108; CHECK-NEXT:    mov 2, %o2
109; CHECK-NEXT:    mov 3, %o3
110; CHECK-NEXT:    mov 4, %o4
111; CHECK-NEXT:    mov 5, %o5
112; CHECK-NEXT:    call foo7
113; CHECK-NEXT:    st %i0, [%sp+92]
114; CHECK-NEXT:    ret
115; CHECK-NEXT:    restore %g0, %o0, %o0
116entry:
117  %r = tail call i32 @foo7(i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6)
118  ret i32 %r
119}
120
121; Byval parameters hand the function a pointer directly into the stack area
122; we want to reuse during a tail call. Do not tail call optimize functions with
123; byval parameters.
124
125define i32 @caller_byval() #0 {
126; CHECK-LABEL: caller_byval:
127; CHECK:       ! %bb.0: ! %entry
128; CHECK-NEXT:    save %sp, -104, %sp
129; CHECK-NEXT:    ld [%fp+-4], %i0
130; CHECK-NEXT:    st %i0, [%fp+-8]
131; CHECK-NEXT:    call callee_byval
132; CHECK-NEXT:    add %fp, -8, %o0
133; CHECK-NEXT:    ret
134; CHECK-NEXT:    restore %g0, %o0, %o0
135entry:
136  %a = alloca i32*
137  %r = tail call i32 @callee_byval(i32** byval(i32*) %a)
138  ret i32 %r
139}
140
141; Perform tail call optimization for sret function.
142
143define void @sret_test(%struct.a* noalias sret(%struct.a) %agg.result) #0 {
144; CHECK-LABEL: sret_test:
145; CHECK:       ! %bb.0: ! %entry
146; CHECK-NEXT:    mov %o7, %g1
147; CHECK-NEXT:    call sret_func
148; CHECK-NEXT:    mov %g1, %o7
149entry:
150  tail call void bitcast (void (%struct.a*)* @sret_func to
151                          void (%struct.a*)*)(%struct.a* sret(%struct.a) %agg.result)
152  ret void
153}
154
155; Do not tail call if either caller or callee returns
156; a struct and the other does not. Returning a large
157; struct will generate a memcpy as the tail function.
158
159define void @ret_large_struct(%struct.big* noalias sret(%struct.big) %agg.result) #0 {
160; CHECK-LABEL: ret_large_struct:
161; CHECK:       ! %bb.0: ! %entry
162; CHECK-NEXT:    save %sp, -96, %sp
163; CHECK-NEXT:    ld [%fp+64], %i0
164; CHECK-NEXT:    sethi %hi(bigstruct), %i1
165; CHECK-NEXT:    add %i1, %lo(bigstruct), %o1
166; CHECK-NEXT:    mov 400, %o2
167; CHECK-NEXT:    call memcpy
168; CHECK-NEXT:    mov %i0, %o0
169; CHECK-NEXT:    jmp %i7+12
170; CHECK-NEXT:    restore
171entry:
172  %0 = bitcast %struct.big* %agg.result to i8*
173  tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast (%struct.big* @bigstruct to i8*), i32 400, i1 false)
174  ret void
175}
176
177; Test register + immediate pattern.
178
179define void @addri_test(i32 %ptr) #0 {
180; CHECK-LABEL: addri_test:
181; CHECK:       ! %bb.0: ! %entry
182; CHECK-NEXT:    jmp %o0+4
183; CHECK-NEXT:    nop
184entry:
185  %add = add nsw i32 %ptr, 4
186  %0 = inttoptr i32 %add to void ()*
187  tail call void %0() #1
188  ret void
189}
190
191%struct.a = type { i32, i32 }
192@dest = global [2 x i8] zeroinitializer
193
194%struct.big = type { [100 x i32] }
195@bigstruct = global %struct.big zeroinitializer
196
197declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
198declare void @sret_func(%struct.a* sret(%struct.a))
199declare i32 @callee_byval(i32** byval(i32*) %a)
200declare i32 @foo(i32)
201declare i32 @foo2(i32, i32)
202declare i32 @foo7(i32, i32, i32, i32, i32, i32, i32)
203
204attributes #0 = { nounwind "disable-tail-calls"="false"
205                  "frame-pointer"="none" }
206attributes #1 = { nounwind "disable-tail-calls"="false"
207                  "frame-pointer"="all" }
208