xref: /llvm-project/llvm/test/Transforms/Inline/inline-tail.ll (revision 25bc999d1fb2efccc3ece398550af738aea7d310)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -passes=inline -S | FileCheck %s
3
4; We have to apply the less restrictive TailCallKind of the call site being
5; inlined and any call sites cloned into the caller.
6
7; No tail marker after inlining, since test_capture_c captures an alloca.
8declare void @test_capture_c(ptr)
9define internal void @test_capture_b(ptr %P) {
10  tail call void @test_capture_c(ptr %P)
11  ret void
12}
13define void @test_capture_a() {
14; CHECK-LABEL: define void @test_capture_a() {
15; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
16; CHECK-NEXT:    call void @test_capture_c(ptr [[A]])
17; CHECK-NEXT:    ret void
18;
19  %A = alloca i32  		; captured by test_capture_b
20  call void @test_capture_b(ptr %A)
21  ret void
22}
23
24; No musttail marker after inlining, since the prototypes don't match.
25declare void @test_proto_mismatch_c(ptr)
26define internal void @test_proto_mismatch_b(ptr %p) {
27  musttail call void @test_proto_mismatch_c(ptr %p)
28  ret void
29}
30define void @test_proto_mismatch_a() {
31; CHECK-LABEL: define void @test_proto_mismatch_a() {
32; CHECK-NEXT:    call void @test_proto_mismatch_c(ptr null)
33; CHECK-NEXT:    ret void
34;
35  call void @test_proto_mismatch_b(ptr null)
36  ret void
37}
38
39; After inlining through a musttail call site, we need to keep musttail markers
40; to prevent unbounded stack growth.
41declare void @test_musttail_basic_c(ptr %p)
42define internal void @test_musttail_basic_b(ptr %p) {
43  musttail call void @test_musttail_basic_c(ptr %p)
44  ret void
45}
46define void @test_musttail_basic_a(ptr %p) {
47; CHECK-LABEL: define void @test_musttail_basic_a
48; CHECK-SAME: (ptr [[P:%.*]]) {
49; CHECK-NEXT:    musttail call void @test_musttail_basic_c(ptr [[P]])
50; CHECK-NEXT:    ret void
51;
52  musttail call void @test_musttail_basic_b(ptr %p)
53  ret void
54}
55
56; Don't insert lifetime end markers here, the lifetime is trivially over due
57; the return.
58declare void @test_byval_c(ptr byval(i32) %p)
59define internal void @test_byval_b(ptr byval(i32) %p) {
60  musttail call void @test_byval_c(ptr byval(i32) %p)
61  ret void
62}
63define void @test_byval_a(ptr byval(i32) %p) {
64; CHECK-LABEL: define void @test_byval_a
65; CHECK-SAME: (ptr byval(i32) [[P:%.*]]) {
66; CHECK-NEXT:    [[P1:%.*]] = alloca i32, align 4
67; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[P1]])
68; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[P1]], ptr align 1 [[P]], i64 4, i1 false)
69; CHECK-NEXT:    musttail call void @test_byval_c(ptr byval(i32) [[P1]])
70; CHECK-NEXT:    ret void
71;
72  musttail call void @test_byval_b(ptr byval(i32) %p)
73  ret void
74}
75
76; Don't insert a stack restore, we're about to return.
77declare void @escape(ptr %buf)
78declare void @test_dynalloca_c(ptr byval(i32) %p, i32 %n)
79define internal void @test_dynalloca_b(ptr byval(i32) %p, i32 %n) alwaysinline {
80  %buf = alloca i8, i32 %n              ; dynamic alloca
81  call void @escape(ptr %buf)           ; escape it
82  musttail call void @test_dynalloca_c(ptr byval(i32) %p, i32 %n)
83  ret void
84}
85define void @test_dynalloca_a(ptr byval(i32) %p, i32 %n) {
86; CHECK-LABEL: define void @test_dynalloca_a
87; CHECK-SAME: (ptr byval(i32) [[P:%.*]], i32 [[N:%.*]]) {
88; CHECK-NEXT:    [[P1:%.*]] = alloca i32, align 4
89; CHECK-NEXT:    [[SAVEDSTACK:%.*]] = call ptr @llvm.stacksave.p0()
90; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[P1]])
91; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[P1]], ptr align 1 [[P]], i64 4, i1 false)
92; CHECK-NEXT:    [[BUF_I:%.*]] = alloca i8, i32 [[N]], align 1
93; CHECK-NEXT:    call void @escape(ptr [[BUF_I]])
94; CHECK-NEXT:    musttail call void @test_dynalloca_c(ptr byval(i32) [[P1]], i32 [[N]])
95; CHECK-NEXT:    ret void
96;
97  musttail call void @test_dynalloca_b(ptr byval(i32) %p, i32 %n)
98  ret void
99}
100
101; We can't merge the returns.
102declare void @test_multiret_c(i1 zeroext %b)
103declare void @test_multiret_d(i1 zeroext %b)
104define internal void @test_multiret_b(i1 zeroext %b) {
105  br i1 %b, label %c, label %d
106c:
107  musttail call void @test_multiret_c(i1 zeroext %b)
108  ret void
109d:
110  musttail call void @test_multiret_d(i1 zeroext %b)
111  ret void
112}
113define void @test_multiret_a(i1 zeroext %b) {
114; CHECK-LABEL: define void @test_multiret_a
115; CHECK-SAME: (i1 zeroext [[B:%.*]]) {
116; CHECK-NEXT:    br i1 [[B]], label [[C_I:%.*]], label [[D_I:%.*]]
117; CHECK:       c.i:
118; CHECK-NEXT:    musttail call void @test_multiret_c(i1 zeroext [[B]])
119; CHECK-NEXT:    ret void
120; CHECK:       d.i:
121; CHECK-NEXT:    musttail call void @test_multiret_d(i1 zeroext [[B]])
122; CHECK-NEXT:    ret void
123;
124  musttail call void @test_multiret_b(i1 zeroext %b)
125  ret void
126}
127
128; We have to avoid bitcast chains.
129declare ptr @test_retptr_c()
130define internal ptr @test_retptr_b() {
131  %rv = musttail call ptr @test_retptr_c()
132  ret ptr %rv
133}
134define ptr @test_retptr_a() {
135; CHECK-LABEL: define ptr @test_retptr_a() {
136; CHECK-NEXT:    [[RV_I:%.*]] = musttail call ptr @test_retptr_c()
137; CHECK-NEXT:    ret ptr [[RV_I]]
138;
139  %rv = musttail call ptr @test_retptr_b()
140  ret ptr %rv
141}
142
143; Combine the last two cases: multiple returns with pointer bitcasts.
144declare ptr @test_multiptrret_c(i1 zeroext %b)
145declare ptr @test_multiptrret_d(i1 zeroext %b)
146define internal ptr @test_multiptrret_b(i1 zeroext %b) {
147  br i1 %b, label %c, label %d
148c:
149  %c_rv = musttail call ptr @test_multiptrret_c(i1 zeroext %b)
150  ret ptr %c_rv
151d:
152  %d_rv = musttail call ptr @test_multiptrret_d(i1 zeroext %b)
153  ret ptr %d_rv
154}
155define ptr @test_multiptrret_a(i1 zeroext %b) {
156; CHECK-LABEL: define ptr @test_multiptrret_a
157; CHECK-SAME: (i1 zeroext [[B:%.*]]) {
158; CHECK-NEXT:    br i1 [[B]], label [[C_I:%.*]], label [[D_I:%.*]]
159; CHECK:       c.i:
160; CHECK-NEXT:    [[C_RV_I:%.*]] = musttail call ptr @test_multiptrret_c(i1 zeroext [[B]])
161; CHECK-NEXT:    ret ptr [[C_RV_I]]
162; CHECK:       d.i:
163; CHECK-NEXT:    [[D_RV_I:%.*]] = musttail call ptr @test_multiptrret_d(i1 zeroext [[B]])
164; CHECK-NEXT:    ret ptr [[D_RV_I]]
165;
166  %rv = musttail call ptr @test_multiptrret_b(i1 zeroext %b)
167  ret ptr %rv
168}
169
170; Inline a musttail call site which contains a normal return and a musttail call.
171declare i32 @test_mixedret_c(i1 zeroext %b)
172declare i32 @test_mixedret_d(i1 zeroext %b)
173define internal i32 @test_mixedret_b(i1 zeroext %b) {
174  br i1 %b, label %c, label %d
175c:
176  %c_rv = musttail call i32 @test_mixedret_c(i1 zeroext %b)
177  ret i32 %c_rv
178d:
179  %d_rv = call i32 @test_mixedret_d(i1 zeroext %b)
180  %d_rv1 = add i32 1, %d_rv
181  ret i32 %d_rv1
182}
183define i32 @test_mixedret_a(i1 zeroext %b) {
184; CHECK-LABEL: define i32 @test_mixedret_a
185; CHECK-SAME: (i1 zeroext [[B:%.*]]) {
186; CHECK-NEXT:    br i1 [[B]], label [[C_I:%.*]], label [[TEST_MIXEDRET_B_EXIT:%.*]]
187; CHECK:       c.i:
188; CHECK-NEXT:    [[C_RV_I:%.*]] = musttail call i32 @test_mixedret_c(i1 zeroext [[B]])
189; CHECK-NEXT:    ret i32 [[C_RV_I]]
190; CHECK:       test_mixedret_b.exit:
191; CHECK-NEXT:    [[D_RV_I:%.*]] = call i32 @test_mixedret_d(i1 zeroext [[B]])
192; CHECK-NEXT:    [[D_RV1_I:%.*]] = add i32 1, [[D_RV_I]]
193; CHECK-NEXT:    ret i32 [[D_RV1_I]]
194;
195  %rv = musttail call i32 @test_mixedret_b(i1 zeroext %b)
196  ret i32 %rv
197}
198
199declare i32 @donttailcall()
200
201define i32 @notail() {
202; CHECK-LABEL: define i32 @notail() {
203; CHECK-NEXT:    [[RV:%.*]] = notail call i32 @donttailcall()
204; CHECK-NEXT:    ret i32 [[RV]]
205;
206  %rv = notail call i32 @donttailcall()
207  ret i32 %rv
208}
209
210define i32 @test_notail() {
211; CHECK-LABEL: define i32 @test_notail() {
212; CHECK-NEXT:    [[RV_I:%.*]] = notail call i32 @donttailcall()
213; CHECK-NEXT:    ret i32 [[RV_I]]
214;
215  %rv = tail call i32 @notail()
216  ret i32 %rv
217}
218
219; PR31014: Inlining a musttail call through a notail call site should remove
220; any tail marking, otherwise we break verifier invariants.
221
222declare void @do_ret(i32)
223
224define void @test_notail_inline_musttail(i32 %a) {
225; CHECK-LABEL: define void @test_notail_inline_musttail
226; CHECK-SAME: (i32 [[A:%.*]]) {
227; CHECK-NEXT:    call void @do_ret(i32 [[A]])
228; CHECK-NEXT:    musttail call void @do_ret(i32 [[A]])
229; CHECK-NEXT:    ret void
230;
231  notail call void @inline_musttail(i32 %a)
232  musttail call void @do_ret(i32 %a)
233  ret void
234}
235
236define internal void @inline_musttail(i32 %a) {
237  musttail call void @do_ret(i32 %a)
238  ret void
239}
240