xref: /aosp_15_r20/external/llvm/test/Transforms/TailCallElim/basic.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -tailcallelim -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdeclare void @noarg()
4*9880d681SAndroid Build Coastguard Workerdeclare void @use(i32*)
5*9880d681SAndroid Build Coastguard Workerdeclare void @use_nocapture(i32* nocapture)
6*9880d681SAndroid Build Coastguard Workerdeclare void @use2_nocapture(i32* nocapture, i32* nocapture)
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker; Trivial case. Mark @noarg with tail call.
9*9880d681SAndroid Build Coastguard Workerdefine void @test0() {
10*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @noarg()
11*9880d681SAndroid Build Coastguard Worker	call void @noarg()
12*9880d681SAndroid Build Coastguard Worker	ret void
13*9880d681SAndroid Build Coastguard Worker}
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker; PR615. Make sure that we do not move the alloca so that it interferes with the tail call.
16*9880d681SAndroid Build Coastguard Workerdefine i32 @test1() {
17*9880d681SAndroid Build Coastguard Worker; CHECK: i32 @test1()
18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: alloca
19*9880d681SAndroid Build Coastguard Worker	%A = alloca i32		; <i32*> [#uses=2]
20*9880d681SAndroid Build Coastguard Worker	store i32 5, i32* %A
21*9880d681SAndroid Build Coastguard Worker	call void @use(i32* %A)
22*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i32 @test1
23*9880d681SAndroid Build Coastguard Worker	%X = tail call i32 @test1()		; <i32> [#uses=1]
24*9880d681SAndroid Build Coastguard Worker	ret i32 %X
25*9880d681SAndroid Build Coastguard Worker}
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker; This function contains intervening instructions which should be moved out of the way
28*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32 %X) {
29*9880d681SAndroid Build Coastguard Worker; CHECK: i32 @test2
30*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call
31*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32
32*9880d681SAndroid Build Coastguard Workerentry:
33*9880d681SAndroid Build Coastguard Worker	%tmp.1 = icmp eq i32 %X, 0		; <i1> [#uses=1]
34*9880d681SAndroid Build Coastguard Worker	br i1 %tmp.1, label %then.0, label %endif.0
35*9880d681SAndroid Build Coastguard Workerthen.0:		; preds = %entry
36*9880d681SAndroid Build Coastguard Worker	%tmp.4 = add i32 %X, 1		; <i32> [#uses=1]
37*9880d681SAndroid Build Coastguard Worker	ret i32 %tmp.4
38*9880d681SAndroid Build Coastguard Workerendif.0:		; preds = %entry
39*9880d681SAndroid Build Coastguard Worker	%tmp.10 = add i32 %X, -1		; <i32> [#uses=1]
40*9880d681SAndroid Build Coastguard Worker	%tmp.8 = call i32 @test2(i32 %tmp.10)		; <i32> [#uses=1]
41*9880d681SAndroid Build Coastguard Worker	%DUMMY = add i32 %X, 1		; <i32> [#uses=0]
42*9880d681SAndroid Build Coastguard Worker	ret i32 %tmp.8
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; Though this case seems to be fairly unlikely to occur in the wild, someone
46*9880d681SAndroid Build Coastguard Worker; plunked it into the demo script, so maybe they care about it.
47*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32 %c) {
48*9880d681SAndroid Build Coastguard Worker; CHECK: i32 @test3
49*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call
50*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
51*9880d681SAndroid Build Coastguard Workerentry:
52*9880d681SAndroid Build Coastguard Worker	%tmp.1 = icmp eq i32 %c, 0		; <i1> [#uses=1]
53*9880d681SAndroid Build Coastguard Worker	br i1 %tmp.1, label %return, label %else
54*9880d681SAndroid Build Coastguard Workerelse:		; preds = %entry
55*9880d681SAndroid Build Coastguard Worker	%tmp.5 = add i32 %c, -1		; <i32> [#uses=1]
56*9880d681SAndroid Build Coastguard Worker	%tmp.3 = call i32 @test3(i32 %tmp.5)		; <i32> [#uses=0]
57*9880d681SAndroid Build Coastguard Worker	ret i32 0
58*9880d681SAndroid Build Coastguard Workerreturn:		; preds = %entry
59*9880d681SAndroid Build Coastguard Worker	ret i32 0
60*9880d681SAndroid Build Coastguard Worker}
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; Make sure that a nocapture pointer does not stop adding a tail call marker to
63*9880d681SAndroid Build Coastguard Worker; an unrelated call and additionally that we do not mark the nocapture call with
64*9880d681SAndroid Build Coastguard Worker; a tail call.
65*9880d681SAndroid Build Coastguard Worker;
66*9880d681SAndroid Build Coastguard Worker; rdar://14324281
67*9880d681SAndroid Build Coastguard Workerdefine void @test4() {
68*9880d681SAndroid Build Coastguard Worker; CHECK: void @test4
69*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tail call void @use_nocapture
70*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @noarg()
71*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
72*9880d681SAndroid Build Coastguard Worker  %a = alloca i32
73*9880d681SAndroid Build Coastguard Worker  call void @use_nocapture(i32* %a)
74*9880d681SAndroid Build Coastguard Worker  call void @noarg()
75*9880d681SAndroid Build Coastguard Worker  ret void
76*9880d681SAndroid Build Coastguard Worker}
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker; Make sure that we do not perform TRE even with a nocapture use. This is due to
79*9880d681SAndroid Build Coastguard Worker; bad codegen caused by PR962.
80*9880d681SAndroid Build Coastguard Worker;
81*9880d681SAndroid Build Coastguard Worker; rdar://14324281.
82*9880d681SAndroid Build Coastguard Workerdefine i32* @test5(i32* nocapture %A, i1 %cond) {
83*9880d681SAndroid Build Coastguard Worker; CHECK: i32* @test5
84*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tailrecurse:
85*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32* null
86*9880d681SAndroid Build Coastguard Worker  %B = alloca i32
87*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %cond_true, label %cond_false
88*9880d681SAndroid Build Coastguard Workercond_true:
89*9880d681SAndroid Build Coastguard Worker  call i32* @test5(i32* %B, i1 false)
90*9880d681SAndroid Build Coastguard Worker  ret i32* null
91*9880d681SAndroid Build Coastguard Workercond_false:
92*9880d681SAndroid Build Coastguard Worker  call void @use2_nocapture(i32* %A, i32* %B)
93*9880d681SAndroid Build Coastguard Worker  call void @noarg()
94*9880d681SAndroid Build Coastguard Worker  ret i32* null
95*9880d681SAndroid Build Coastguard Worker}
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker; PR14143: Make sure that we do not mark functions with nocapture allocas with tail.
98*9880d681SAndroid Build Coastguard Worker;
99*9880d681SAndroid Build Coastguard Worker; rdar://14324281.
100*9880d681SAndroid Build Coastguard Workerdefine void @test6(i32* %a, i32* %b) {
101*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6(
102*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tail call
103*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
104*9880d681SAndroid Build Coastguard Worker  %c = alloca [100 x i8], align 16
105*9880d681SAndroid Build Coastguard Worker  %tmp = bitcast [100 x i8]* %c to i32*
106*9880d681SAndroid Build Coastguard Worker  call void @use2_nocapture(i32* %b, i32* %tmp)
107*9880d681SAndroid Build Coastguard Worker  ret void
108*9880d681SAndroid Build Coastguard Worker}
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker; PR14143: Make sure that we do not mark functions with nocapture allocas with tail.
111*9880d681SAndroid Build Coastguard Worker;
112*9880d681SAndroid Build Coastguard Worker; rdar://14324281
113*9880d681SAndroid Build Coastguard Workerdefine void @test7(i32* %a, i32* %b) nounwind uwtable {
114*9880d681SAndroid Build Coastguard Workerentry:
115*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7(
116*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tail call
117*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
118*9880d681SAndroid Build Coastguard Worker  %c = alloca [100 x i8], align 16
119*9880d681SAndroid Build Coastguard Worker  %0 = bitcast [100 x i8]* %c to i32*
120*9880d681SAndroid Build Coastguard Worker  call void @use2_nocapture(i32* %0, i32* %a)
121*9880d681SAndroid Build Coastguard Worker  call void @use2_nocapture(i32* %b, i32* %0)
122*9880d681SAndroid Build Coastguard Worker  ret void
123*9880d681SAndroid Build Coastguard Worker}
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker; If we have a mix of escaping captured/non-captured allocas, ensure that we do
126*9880d681SAndroid Build Coastguard Worker; not do anything including marking callsites with the tail call marker.
127*9880d681SAndroid Build Coastguard Worker;
128*9880d681SAndroid Build Coastguard Worker; rdar://14324281.
129*9880d681SAndroid Build Coastguard Workerdefine i32* @test8(i32* nocapture %A, i1 %cond) {
130*9880d681SAndroid Build Coastguard Worker; CHECK: i32* @test8
131*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tailrecurse:
132*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tail call
133*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32* null
134*9880d681SAndroid Build Coastguard Worker  %B = alloca i32
135*9880d681SAndroid Build Coastguard Worker  %B2 = alloca i32
136*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %cond_true, label %cond_false
137*9880d681SAndroid Build Coastguard Workercond_true:
138*9880d681SAndroid Build Coastguard Worker  call void @use(i32* %B2)
139*9880d681SAndroid Build Coastguard Worker  call i32* @test8(i32* %B, i1 false)
140*9880d681SAndroid Build Coastguard Worker  ret i32* null
141*9880d681SAndroid Build Coastguard Workercond_false:
142*9880d681SAndroid Build Coastguard Worker  call void @use2_nocapture(i32* %A, i32* %B)
143*9880d681SAndroid Build Coastguard Worker  call void @noarg()
144*9880d681SAndroid Build Coastguard Worker  ret i32* null
145*9880d681SAndroid Build Coastguard Worker}
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker; Don't tail call if a byval arg is captured.
148*9880d681SAndroid Build Coastguard Workerdefine void @test9(i32* byval %a) {
149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test9(
150*9880d681SAndroid Build Coastguard Worker; CHECK: {{^ *}}call void @use(
151*9880d681SAndroid Build Coastguard Worker  call void @use(i32* %a)
152*9880d681SAndroid Build Coastguard Worker  ret void
153*9880d681SAndroid Build Coastguard Worker}
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker%struct.X = type { i8* }
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Workerdeclare void @ctor(%struct.X*)
158*9880d681SAndroid Build Coastguard Workerdefine void @test10(%struct.X* noalias sret %agg.result, i1 zeroext %b) {
159*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10
160*9880d681SAndroid Build Coastguard Workerentry:
161*9880d681SAndroid Build Coastguard Worker  %x = alloca %struct.X, align 8
162*9880d681SAndroid Build Coastguard Worker  br i1 %b, label %if.then, label %if.end
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
165*9880d681SAndroid Build Coastguard Worker  call void @ctor(%struct.X* %agg.result)
166*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @ctor
167*9880d681SAndroid Build Coastguard Worker  br label %return
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerif.end:
170*9880d681SAndroid Build Coastguard Worker  call void @ctor(%struct.X* %x)
171*9880d681SAndroid Build Coastguard Worker; CHECK: call void @ctor
172*9880d681SAndroid Build Coastguard Worker  br label %return
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Workerreturn:
175*9880d681SAndroid Build Coastguard Worker  ret void
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Workerdeclare void @test11_helper1(i8** nocapture, i8*)
179*9880d681SAndroid Build Coastguard Workerdeclare void @test11_helper2(i8*)
180*9880d681SAndroid Build Coastguard Workerdefine void @test11() {
181*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11
182*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: tail
183*9880d681SAndroid Build Coastguard Worker  %a = alloca i8*
184*9880d681SAndroid Build Coastguard Worker  %b = alloca i8
185*9880d681SAndroid Build Coastguard Worker  call void @test11_helper1(i8** %a, i8* %b)  ; a = &b
186*9880d681SAndroid Build Coastguard Worker  %c = load i8*, i8** %a
187*9880d681SAndroid Build Coastguard Worker  call void @test11_helper2(i8* %c)
188*9880d681SAndroid Build Coastguard Worker; CHECK: call void @test11_helper2
189*9880d681SAndroid Build Coastguard Worker  ret void
190*9880d681SAndroid Build Coastguard Worker}
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker; PR25928
193*9880d681SAndroid Build Coastguard Workerdefine void @test12() {
194*9880d681SAndroid Build Coastguard Workerentry:
195*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12
196*9880d681SAndroid Build Coastguard Worker; CHECK: {{^ *}} call void undef(i8* undef) [ "foo"(i8* %e) ]
197*9880d681SAndroid Build Coastguard Worker  %e = alloca i8
198*9880d681SAndroid Build Coastguard Worker  call void undef(i8* undef) [ "foo"(i8* %e) ]
199*9880d681SAndroid Build Coastguard Worker  unreachable
200*9880d681SAndroid Build Coastguard Worker}
201