blob: 291c003acfe38852b1302b2ea68c99c744b5eb25 [file] [log] [blame]
Jun Bum Lim0c990072017-11-03 20:41:16 +00001; 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:
Florian Hahn2a266a32017-11-18 18:14:13 +0000198;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 2)
Jun Bum Lim0c990072017-11-03 20:41:16 +0000199;CHECK-LABEL: Tail.predBB2.split:
Florian Hahn2a266a32017-11-18 18:14:13 +0000200;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1)
Jun Bum Lim0c990072017-11-03 20:41:16 +0000201;CHECK-LABEL: Tail
Florian Hahn2a266a32017-11-18 18:14:13 +0000202;CHECK: %p = phi i32 [ 2, %Tail.predBB1.split ], [ 1, %Tail.predBB2.split ]
Jun Bum Lim0c990072017-11-03 20:41:16 +0000203;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
Florian Hahn2a266a32017-11-18 18:14:13 +0000223;CHECK-LABEL: @test_cfg_no_or_phi
224;CHECK-LABEL: Tail.predBB1.split
225;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 2)
226;CHECK-LABEL: Tail.predBB2.split:
227;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1)
228;CHECK-LABEL: Tail
229;CHECK: %p = phi i32 [ 2, %Tail.predBB1.split ], [ 1, %Tail.predBB2.split ]
230;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
231;CHECK: ret i32 %[[MERGED]]
232define i32 @test_cfg_no_or_phi(i32* %a, i32 %v) {
233entry:
234 br i1 undef, label %TBB0, label %TBB1
235TBB0:
236 br i1 undef, label %Tail, label %End
237TBB1:
238 br i1 undef, label %Tail, label %End
239Tail:
240 %p = phi i32[1,%TBB0], [2, %TBB1]
241 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
242 ret i32 %r
243End:
244 ret i32 %v
245}
246
Jun Bum Lim0c990072017-11-03 20:41:16 +0000247;CHECK-LABEL: @test_nonconst_nonconst_phi_noncost
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_nonconst_nonconst_phi_noncost(i32* %a, i32* %b, i32 %v, i32 %v2) {
254Header:
255 %tobool1 = icmp eq i32* %a, %b
256 br i1 %tobool1, label %Tail, label %TBB
257
258TBB:
259 %cmp = icmp eq i32 %v, %v2
260 br i1 %cmp, label %Tail, label %End
261
262Tail:
263 %p = phi i32[%v,%Header], [%v2, %TBB]
264 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
265 ret i32 %r
266
267End:
268 ret i32 %v
269}
270
271;CHECK-LABEL: @test_fisrtnonphi
272;CHECK-NOT: Tail.predBB1.split:
273;CHECK-NOT: Tail.predBB2.split:
274;CHECK-LABEL: Tail:
275;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
276;CHECK: ret i32 %r
277define i32 @test_fisrtnonphi(i32* %a, i32 %v) {
278Header:
279 %tobool1 = icmp eq i32* %a, null
280 br i1 %tobool1, label %Tail, label %TBB
281
282TBB:
283 %cmp = icmp eq i32 %v, 1
284 br i1 %cmp, label %Tail, label %End
285
286Tail:
287 %p = phi i32[1,%Header], [2, %TBB]
288 store i32 %v, i32* %a
289 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
290 ret i32 %r
291
292End:
293 ret i32 %v
294}
295
296;CHECK-LABEL: @test_3preds_constphi
297;CHECK-NOT: Tail.predBB1.split:
298;CHECK-NOT: Tail.predBB2.split:
299;CHECK-LABEL: Tail:
300;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
301;CHECK: ret i32 %r
302define i32 @test_3preds_constphi(i32* %a, i32 %v, i1 %c1, i1 %c2, i1 %c3) {
303Header:
304 br i1 %c1, label %Tail, label %TBB1
305
306TBB1:
307 br i1 %c2, label %Tail, label %TBB2
308
309TBB2:
310 br i1 %c3, label %Tail, label %End
311
312Tail:
313 %p = phi i32[1,%Header], [2, %TBB1], [3, %TBB2]
314 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
315 ret i32 %r
316
317End:
318 ret i32 %v
319}
320
321;CHECK-LABEL: @test_indirectbr_phi
322;CHECK-NOT: Tail.predBB1.split:
323;CHECK-NOT: Tail.predBB2.split:
324;CHECK-LABEL: Tail:
325;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
326;CHECK: ret i32 %r
327define i32 @test_indirectbr_phi(i8* %address, i32* %a, i32* %b, i32 %v) {
328Header:
329 %indirect.goto.dest = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address
330 indirectbr i8* %indirect.goto.dest, [label %TBB, label %Tail]
331
332TBB:
333 %indirect.goto.dest2 = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address
334 indirectbr i8* %indirect.goto.dest2, [label %Tail, label %End]
335
336Tail:
337 %p = phi i32[1,%Header], [2, %TBB]
338 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
339 ret i32 %r
340
341End:
342 ret i32 %v
343}
344
345define i32 @callee(i32* %a, i32 %v, i32 %p) {
346entry:
347 %c = icmp ne i32* %a, null
348 br i1 %c, label %BB1, label %BB2
349
350BB1:
351 call void @dummy(i32* %a, i32 %p)
352 br label %End
353
354BB2:
355 call void @dummy2(i32 %v, i32 %p)
356 br label %End
357
358End:
359 ret i32 %p
360}
361
362declare void @dummy(i32*, i32)
363declare void @dummy2(i32, i32)