1; RUN: opt < %s -callsite-splitting -S | FileCheck %s
2; RUN: opt < %s  -passes='function(callsite-splitting)' -S | FileCheck %s
3
4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5target triple = "aarch64-linaro-linux-gnueabi"
6
7;CHECK-LABEL: @test_eq_eq
8;CHECK-LABEL: Tail.predBB1.split:
9;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
10;CHECK-LABEL: Tail.predBB2.split:
11;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
12;CHECK-LABEL: Tail
13;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
14;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
15;CHECK: ret i32 %[[MERGED]]
16define i32 @test_eq_eq(i32* %a, i32 %v) {
17Header:
18  %tobool1 = icmp eq i32* %a, null
19  br i1 %tobool1, label %Tail, label %TBB
20
21TBB:
22  %cmp = icmp eq i32 %v, 1
23  br i1 %cmp, label %Tail, label %End
24
25Tail:
26  %p = phi i32[1,%Header], [2, %TBB]
27  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
28  ret i32 %r
29
30End:
31  ret i32 %v
32}
33
34;CHECK-LABEL: @test_ne_eq
35;CHECK-LABEL: Tail.predBB1.split:
36;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1)
37;CHECK-LABEL: Tail.predBB2.split:
38;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 2)
39;CHECK-LABEL: Tail
40;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
41;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
42;CHECK: ret i32 %[[MERGED]]
43define i32 @test_ne_eq(i32* %a, i32 %v) {
44Header:
45  %tobool1 = icmp ne i32* %a, null
46  br i1 %tobool1, label %Tail, label %TBB
47
48TBB:
49  %cmp = icmp eq i32 %v, 1
50  br i1 %cmp, label %Tail, label %End
51
52Tail:
53  %p = phi i32[1,%Header], [2, %TBB]
54  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
55  ret i32 %r
56
57End:
58  ret i32 %v
59}
60
61;CHECK-LABEL: @test_ne_ne
62;CHECK-LABEL: Tail.predBB1.split:
63;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1)
64;CHECK-LABEL: Tail.predBB2.split:
65;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 2)
66;CHECK-LABEL: Tail
67;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
68;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
69;CHECK: ret i32 %[[MERGED]]
70define i32 @test_ne_ne(i32* %a, i32 %v) {
71Header:
72  %tobool1 = icmp ne i32* %a, null
73  br i1 %tobool1, label %Tail, label %TBB
74
75TBB:
76  %cmp = icmp ne i32 %v, 1
77  br i1 %cmp, label %Tail, label %End
78
79Tail:
80  %p = phi i32[1,%Header], [2, %TBB]
81  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
82  ret i32 %r
83
84End:
85  ret i32 %v
86}
87
88;CHECK-LABEL: @test_eq_eq_untaken
89;CHECK-LABEL: Tail.predBB1.split:
90;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1)
91;CHECK-LABEL: Tail.predBB2.split:
92;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 2)
93;CHECK-LABEL: Tail
94;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
95;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
96;CHECK: ret i32 %[[MERGED]]
97define i32 @test_eq_eq_untaken(i32* %a, i32 %v) {
98Header:
99  %tobool1 = icmp eq i32* %a, null
100  br i1 %tobool1, label %TBB, label %Tail
101
102TBB:
103  %cmp = icmp eq i32 %v, 1
104  br i1 %cmp, label %Tail, label %End
105
106Tail:
107  %p = phi i32[1,%Header], [2, %TBB]
108  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
109  ret i32 %r
110
111End:
112  ret i32 %v
113}
114
115;CHECK-LABEL: @test_ne_eq_untaken
116;CHECK-LABEL: Tail.predBB1.split:
117;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
118;CHECK-LABEL: Tail.predBB2.split:
119;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
120;CHECK-LABEL: Tail
121;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
122;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
123;CHECK: ret i32 %[[MERGED]]
124define i32 @test_ne_eq_untaken(i32* %a, i32 %v) {
125Header:
126  %tobool1 = icmp ne i32* %a, null
127  br i1 %tobool1, label %TBB, label %Tail
128
129TBB:
130  %cmp = icmp eq i32 %v, 1
131  br i1 %cmp, label %Tail, label %End
132
133Tail:
134  %p = phi i32[1,%Header], [2, %TBB]
135  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
136  ret i32 %r
137
138End:
139  ret i32 %v
140}
141
142;CHECK-LABEL: @test_ne_ne_untaken
143;CHECK-LABEL: Tail.predBB1.split:
144;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
145;CHECK-LABEL: Tail.predBB2.split:
146;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
147;CHECK-LABEL: Tail
148;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
149;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
150;CHECK: ret i32 %[[MERGED]]
151define i32 @test_ne_ne_untaken(i32* %a, i32 %v) {
152Header:
153  %tobool1 = icmp ne i32* %a, null
154  br i1 %tobool1, label %TBB, label %Tail
155
156TBB:
157  %cmp = icmp ne i32 %v, 1
158  br i1 %cmp, label %End, label %Tail
159
160Tail:
161  %p = phi i32[1,%Header], [2, %TBB]
162  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
163  ret i32 %r
164
165End:
166  ret i32 %v
167}
168
169;CHECK-LABEL: @test_nonconst_const_phi
170;CHECK-LABEL: Tail.predBB1.split:
171;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1)
172;CHECK-LABEL: Tail.predBB2.split:
173;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 1, i32 2)
174;CHECK-LABEL: Tail
175;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
176;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
177;CHECK: ret i32 %[[MERGED]]
178define i32 @test_nonconst_const_phi(i32* %a, i32* %b, i32 %v) {
179Header:
180  %tobool1 = icmp eq i32* %a, %b
181  br i1 %tobool1, label %Tail, label %TBB
182
183TBB:
184  %cmp = icmp eq i32 %v, 1
185  br i1 %cmp, label %Tail, label %End
186
187Tail:
188  %p = phi i32[1,%Header], [2, %TBB]
189  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
190  ret i32 %r
191
192End:
193  ret i32 %v
194}
195
196;CHECK-LABEL: @test_nonconst_nonconst_phi
197;CHECK-LABEL: Tail.predBB1.split:
198;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1)
199;CHECK-LABEL: Tail.predBB2.split:
200;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 %v, i32 2)
201;CHECK-LABEL: Tail
202;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
203;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
204;CHECK: ret i32 %[[MERGED]]
205define i32 @test_nonconst_nonconst_phi(i32* %a, i32* %b, i32 %v, i32 %v2) {
206Header:
207  %tobool1 = icmp eq i32* %a, %b
208  br i1 %tobool1, label %Tail, label %TBB
209
210TBB:
211  %cmp = icmp eq i32 %v, %v2
212  br i1 %cmp, label %Tail, label %End
213
214Tail:
215  %p = phi i32[1,%Header], [2, %TBB]
216  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
217  ret i32 %r
218
219End:
220  ret i32 %v
221}
222
223;CHECK-LABEL: @test_nonconst_nonconst_phi_noncost
224;CHECK-NOT: Tail.predBB1.split:
225;CHECK-NOT: Tail.predBB2.split:
226;CHECK-LABEL: Tail:
227;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
228;CHECK: ret i32 %r
229define i32 @test_nonconst_nonconst_phi_noncost(i32* %a, i32* %b, i32 %v, i32 %v2) {
230Header:
231  %tobool1 = icmp eq i32* %a, %b
232  br i1 %tobool1, label %Tail, label %TBB
233
234TBB:
235  %cmp = icmp eq i32 %v, %v2
236  br i1 %cmp, label %Tail, label %End
237
238Tail:
239  %p = phi i32[%v,%Header], [%v2, %TBB]
240  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
241  ret i32 %r
242
243End:
244  ret i32 %v
245}
246
247;CHECK-LABEL: @test_fisrtnonphi
248;CHECK-NOT: Tail.predBB1.split:
249;CHECK-NOT: Tail.predBB2.split:
250;CHECK-LABEL: Tail:
251;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
252;CHECK: ret i32 %r
253define i32 @test_fisrtnonphi(i32* %a, i32 %v) {
254Header:
255  %tobool1 = icmp eq i32* %a, null
256  br i1 %tobool1, label %Tail, label %TBB
257
258TBB:
259  %cmp = icmp eq i32 %v, 1
260  br i1 %cmp, label %Tail, label %End
261
262Tail:
263  %p = phi i32[1,%Header], [2, %TBB]
264  store i32 %v, i32* %a
265  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
266  ret i32 %r
267
268End:
269  ret i32 %v
270}
271
272;CHECK-LABEL: @test_3preds_constphi
273;CHECK-NOT: Tail.predBB1.split:
274;CHECK-NOT: Tail.predBB2.split:
275;CHECK-LABEL: Tail:
276;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
277;CHECK: ret i32 %r
278define i32 @test_3preds_constphi(i32* %a, i32 %v, i1 %c1, i1 %c2, i1 %c3) {
279Header:
280  br i1 %c1, label %Tail, label %TBB1
281
282TBB1:
283  br i1 %c2, label %Tail, label %TBB2
284
285TBB2:
286  br i1 %c3, label %Tail, label %End
287
288Tail:
289  %p = phi i32[1,%Header], [2, %TBB1], [3, %TBB2]
290  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
291  ret i32 %r
292
293End:
294  ret i32 %v
295}
296
297;CHECK-LABEL: @test_indirectbr_phi
298;CHECK-NOT: Tail.predBB1.split:
299;CHECK-NOT: Tail.predBB2.split:
300;CHECK-LABEL: Tail:
301;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
302;CHECK: ret i32 %r
303define i32 @test_indirectbr_phi(i8* %address, i32* %a, i32* %b, i32 %v) {
304Header:
305   %indirect.goto.dest = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address
306   indirectbr i8* %indirect.goto.dest, [label %TBB, label %Tail]
307
308TBB:
309  %indirect.goto.dest2 = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address
310  indirectbr i8* %indirect.goto.dest2, [label %Tail, label %End]
311
312Tail:
313  %p = phi i32[1,%Header], [2, %TBB]
314  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
315  ret i32 %r
316
317End:
318  ret i32 %v
319}
320
321define i32 @callee(i32* %a, i32 %v, i32 %p) {
322entry:
323  %c = icmp ne i32* %a, null
324  br i1 %c, label %BB1, label %BB2
325
326BB1:
327  call void @dummy(i32* %a, i32 %p)
328  br label %End
329
330BB2:
331  call void @dummy2(i32 %v, i32 %p)
332  br label %End
333
334End:
335  ret i32 %p
336}
337
338declare void @dummy(i32*, i32)
339declare void @dummy2(i32, i32)
340