llvm.org GIT mirror llvm / 4fc1ca1
[PredicateInfo] Enable -reverse-iterate tests only for +Asserts builds Summary: The flag -reverse-iterate is present only on +Asserts builds. Reviewers: dberlin, davide, RKSimon, efriedma, chapuni Reviewed By: efriedma, chapuni Subscribers: chapuni, llvm-commits Differential Revision: https://reviews.llvm.org/D33795 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304498 91177308-0d34-0410-b5e6-96231b3b80d8 Mandeep Singh Grang 2 years ago
4 changed file(s) with 688 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
11 ; RUN: opt -print-predicateinfo -analyze < %s 2>&1 | FileCheck %s
2 ; RUN: opt -print-predicateinfo -analyze -reverse-iterate < %s 2>&1 | FileCheck %s
32
43 @a = external global i32 ; [#uses=7]
54
0 ; REQUIRES: asserts
1 ; NOTE: The flag -reverse-iterate is present only in a +Asserts build.
2 ; Hence, this test has been split from condprop.ll to test with -reverse-iterate.
3 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
4 ; RUN: opt -print-predicateinfo -analyze -reverse-iterate < %s 2>&1 | FileCheck %s
5
6 @a = external global i32 ; [#uses=7]
7
8 define i32 @test1() nounwind {
9 ; CHECK-LABEL: @test1(
10 ; CHECK-NEXT: entry:
11 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
12 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 4
13 ; CHECK-NEXT: br i1 [[TMP1]], label [[BB:%.*]], label [[BB1:%.*]]
14 ; CHECK: bb:
15 ; CHECK-NEXT: br label [[BB8:%.*]]
16 ; CHECK: bb1:
17 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* @a, align 4
18 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 5
19 ; CHECK-NEXT: br i1 [[TMP3]], label [[BB2:%.*]], label [[BB3:%.*]]
20 ; CHECK: bb2:
21 ; CHECK-NEXT: br label [[BB8]]
22 ; CHECK: bb3:
23 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* @a, align 4
24 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 4
25 ; CHECK-NEXT: br i1 [[TMP5]], label [[BB4:%.*]], label [[BB5:%.*]]
26 ; CHECK: bb4:
27 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* @a, align 4
28 ; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 5
29 ; CHECK-NEXT: br label [[BB8]]
30 ; CHECK: bb5:
31 ; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* @a, align 4
32 ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 5
33 ; CHECK-NEXT: br i1 [[TMP9]], label [[BB6:%.*]], label [[BB7:%.*]]
34 ; CHECK: bb6:
35 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* @a, align 4
36 ; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP10]], 4
37 ; CHECK-NEXT: br label [[BB8]]
38 ; CHECK: bb7:
39 ; CHECK-NEXT: [[TMP12:%.*]] = load i32, i32* @a, align 4
40 ; CHECK-NEXT: br label [[BB8]]
41 ; CHECK: bb8:
42 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP12]], [[BB7]] ], [ [[TMP11]], [[BB6]] ], [ [[TMP7]], [[BB4]] ], [ 4, [[BB2]] ], [ 5, [[BB]] ]
43 ; CHECK-NEXT: br label [[RETURN:%.*]]
44 ; CHECK: return:
45 ; CHECK-NEXT: ret i32 [[DOT0]]
46 ;
47 entry:
48 %0 = load i32, i32* @a, align 4
49 %1 = icmp eq i32 %0, 4
50 br i1 %1, label %bb, label %bb1
51
52 bb: ; preds = %entry
53 br label %bb8
54
55 bb1: ; preds = %entry
56 %2 = load i32, i32* @a, align 4
57 %3 = icmp eq i32 %2, 5
58 br i1 %3, label %bb2, label %bb3
59
60 bb2: ; preds = %bb1
61 br label %bb8
62
63 bb3: ; preds = %bb1
64 %4 = load i32, i32* @a, align 4
65 %5 = icmp eq i32 %4, 4
66 br i1 %5, label %bb4, label %bb5
67
68 bb4: ; preds = %bb3
69 %6 = load i32, i32* @a, align 4
70 %7 = add i32 %6, 5
71 br label %bb8
72
73 bb5: ; preds = %bb3
74 %8 = load i32, i32* @a, align 4
75 %9 = icmp eq i32 %8, 5
76 br i1 %9, label %bb6, label %bb7
77
78 bb6: ; preds = %bb5
79 %10 = load i32, i32* @a, align 4
80 %11 = add i32 %10, 4
81 br label %bb8
82
83 bb7: ; preds = %bb5
84 %12 = load i32, i32* @a, align 4
85 br label %bb8
86
87 bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb
88 %.0 = phi i32 [ %12, %bb7 ], [ %11, %bb6 ], [ %7, %bb4 ], [ 4, %bb2 ], [ 5, %bb ]
89 br label %return
90
91 return: ; preds = %bb8
92 ret i32 %.0
93 }
94
95 declare void @foo(i1)
96 declare void @bar(i32)
97
98 define void @test3(i32 %x, i32 %y) {
99 ; CHECK-LABEL: @test3(
100 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
101 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
102 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
103 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
104 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
105 ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
106 ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
107 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
108 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]
109 ; CHECK: both_zero:
110 ; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
111 ; CHECK-NEXT: call void @foo(i1 [[YZ_0]])
112 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
113 ; CHECK-NEXT: call void @bar(i32 [[Y_0]])
114 ; CHECK-NEXT: ret void
115 ; CHECK: nope:
116 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
117 ; CHECK-NEXT: ret void
118 ;
119 %xz = icmp eq i32 %x, 0
120 %yz = icmp eq i32 %y, 0
121 %z = and i1 %xz, %yz
122 br i1 %z, label %both_zero, label %nope
123 both_zero:
124 call void @foo(i1 %xz)
125 call void @foo(i1 %yz)
126 call void @bar(i32 %x)
127 call void @bar(i32 %y)
128 ret void
129 nope:
130 call void @foo(i1 %z)
131 ret void
132 }
133
134 define void @test4(i1 %b, i32 %x) {
135 ; CHECK-LABEL: @test4(
136 ; CHECK-NEXT: br i1 [[B:%.*]], label [[SW:%.*]], label [[CASE3:%.*]]
137 ; CHECK: sw:
138 ; CHECK: i32 0, label [[CASE0:%.*]]
139 ; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
140 ; CHECK-NEXT: i32 2, label [[CASE0]]
141 ; CHECK-NEXT: i32 3, label [[CASE3]]
142 ; CHECK-NEXT: i32 4, label [[DEFAULT:%.*]]
143 ; CHECK-NEXT: ] Edge: [label [[SW]],label %case1] }
144 ; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X:%.*]])
145 ; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT]] [
146 ; CHECK-NEXT: i32 0, label [[CASE0]]
147 ; CHECK-NEXT: i32 1, label [[CASE1]]
148 ; CHECK-NEXT: i32 2, label [[CASE0]]
149 ; CHECK-NEXT: i32 3, label [[CASE3]]
150 ; CHECK-NEXT: i32 4, label [[DEFAULT]]
151 ; CHECK-NEXT: ]
152 ; CHECK: default:
153 ; CHECK-NEXT: call void @bar(i32 [[X]])
154 ; CHECK-NEXT: ret void
155 ; CHECK: case0:
156 ; CHECK-NEXT: call void @bar(i32 [[X]])
157 ; CHECK-NEXT: ret void
158 ; CHECK: case1:
159 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
160 ; CHECK-NEXT: ret void
161 ; CHECK: case3:
162 ; CHECK-NEXT: call void @bar(i32 [[X]])
163 ; CHECK-NEXT: ret void
164 ;
165 br i1 %b, label %sw, label %case3
166 sw:
167 switch i32 %x, label %default [
168 i32 0, label %case0
169 i32 1, label %case1
170 i32 2, label %case0
171 i32 3, label %case3
172 i32 4, label %default
173 ]
174 default:
175 call void @bar(i32 %x)
176 ret void
177 case0:
178 call void @bar(i32 %x)
179 ret void
180 case1:
181 call void @bar(i32 %x)
182 ret void
183 case3:
184 call void @bar(i32 %x)
185 ret void
186 }
187
188 define i1 @test5(i32 %x, i32 %y) {
189 ; CHECK-LABEL: @test5(
190 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
191 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
192 ; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
193 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
194 ; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
195 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
196 ; CHECK: same:
197 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X_0]], [[Y_0]]
198 ; CHECK-NEXT: ret i1 [[CMP2]]
199 ; CHECK: different:
200 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X_1]], [[Y_1]]
201 ; CHECK-NEXT: ret i1 [[CMP3]]
202 ;
203 %cmp = icmp eq i32 %x, %y
204 br i1 %cmp, label %same, label %different
205
206 same:
207 %cmp2 = icmp ne i32 %x, %y
208 ret i1 %cmp2
209
210 different:
211 %cmp3 = icmp eq i32 %x, %y
212 ret i1 %cmp3
213 }
214
215 define i1 @test6(i32 %x, i32 %y) {
216 ; CHECK-LABEL: @test6(
217 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
218 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
219 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X]], [[Y]]
220 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
221 ; CHECK: same:
222 ; CHECK-NEXT: ret i1 [[CMP2]]
223 ; CHECK: different:
224 ; CHECK-NEXT: ret i1 [[CMP3]]
225 ;
226 %cmp2 = icmp ne i32 %x, %y
227 %cmp = icmp eq i32 %x, %y
228 %cmp3 = icmp eq i32 %x, %y
229 br i1 %cmp, label %same, label %different
230
231 same:
232 ret i1 %cmp2
233
234 different:
235 ret i1 %cmp3
236 }
237
238 define i1 @test6_fp(float %x, float %y) {
239 ; CHECK-LABEL: @test6_fp(
240 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]
241 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X]], [[Y]]
242 ; CHECK-NEXT: [[CMP3:%.*]] = fcmp oeq float [[X]], [[Y]]
243 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
244 ; CHECK: same:
245 ; CHECK-NEXT: ret i1 [[CMP2]]
246 ; CHECK: different:
247 ; CHECK-NEXT: ret i1 [[CMP3]]
248 ;
249 %cmp2 = fcmp une float %x, %y
250 %cmp = fcmp oeq float %x, %y
251 %cmp3 = fcmp oeq float %x, %y
252 br i1 %cmp, label %same, label %different
253
254 same:
255 ret i1 %cmp2
256
257 different:
258 ret i1 %cmp3
259 }
260
261 define i1 @test7(i32 %x, i32 %y) {
262 ; CHECK-LABEL: @test7(
263 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
264 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
265 ; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
266 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
267 ; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
268 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
269 ; CHECK: same:
270 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X_0]], [[Y_0]]
271 ; CHECK-NEXT: ret i1 [[CMP2]]
272 ; CHECK: different:
273 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[X_1]], [[Y_1]]
274 ; CHECK-NEXT: ret i1 [[CMP3]]
275 ;
276 %cmp = icmp sgt i32 %x, %y
277 br i1 %cmp, label %same, label %different
278
279 same:
280 %cmp2 = icmp sle i32 %x, %y
281 ret i1 %cmp2
282
283 different:
284 %cmp3 = icmp sgt i32 %x, %y
285 ret i1 %cmp3
286 }
287
288 define i1 @test7_fp(float %x, float %y) {
289 ; CHECK-LABEL: @test7_fp(
290 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
291 ; CHECK: [[X_0:%.*]] = call float @llvm.ssa.copy.f32(float [[X]])
292 ; CHECK: [[X_1:%.*]] = call float @llvm.ssa.copy.f32(float [[X]])
293 ; CHECK: [[Y_0:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]])
294 ; CHECK: [[Y_1:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]])
295 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
296 ; CHECK: same:
297 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X_0]], [[Y_0]]
298 ; CHECK-NEXT: ret i1 [[CMP2]]
299 ; CHECK: different:
300 ; CHECK-NEXT: [[CMP3:%.*]] = fcmp ogt float [[X_1]], [[Y_1]]
301 ; CHECK-NEXT: ret i1 [[CMP3]]
302 ;
303 %cmp = fcmp ogt float %x, %y
304 br i1 %cmp, label %same, label %different
305
306 same:
307 %cmp2 = fcmp ule float %x, %y
308 ret i1 %cmp2
309
310 different:
311 %cmp3 = fcmp ogt float %x, %y
312 ret i1 %cmp3
313 }
314
315 define i1 @test8(i32 %x, i32 %y) {
316 ; CHECK-LABEL: @test8(
317 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
318 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]
319 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[X]], [[Y]]
320 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
321 ; CHECK: same:
322 ; CHECK-NEXT: ret i1 [[CMP2]]
323 ; CHECK: different:
324 ; CHECK-NEXT: ret i1 [[CMP3]]
325 ;
326 %cmp2 = icmp sle i32 %x, %y
327 %cmp = icmp sgt i32 %x, %y
328 %cmp3 = icmp sgt i32 %x, %y
329 br i1 %cmp, label %same, label %different
330
331 same:
332 ret i1 %cmp2
333
334 different:
335 ret i1 %cmp3
336 }
337
338 define i1 @test8_fp(float %x, float %y) {
339 ; CHECK-LABEL: @test8_fp(
340 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
341 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X]], [[Y]]
342 ; CHECK-NEXT: [[CMP3:%.*]] = fcmp ogt float [[X]], [[Y]]
343 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
344 ; CHECK: same:
345 ; CHECK-NEXT: ret i1 [[CMP2]]
346 ; CHECK: different:
347 ; CHECK-NEXT: ret i1 [[CMP3]]
348 ;
349 %cmp2 = fcmp ule float %x, %y
350 %cmp = fcmp ogt float %x, %y
351 %cmp3 = fcmp ogt float %x, %y
352 br i1 %cmp, label %same, label %different
353
354 same:
355 ret i1 %cmp2
356
357 different:
358 ret i1 %cmp3
359 }
360
361 define i32 @test9(i32 %i, i32 %j) {
362 ; CHECK-LABEL: @test9(
363 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
364 ; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]])
365 ; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]])
366 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
367 ; CHECK: cond_true:
368 ; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
369 ; CHECK-NEXT: ret i32 [[DIFF]]
370 ; CHECK: ret:
371 ; CHECK-NEXT: ret i32 5
372 ;
373 %cmp = icmp eq i32 %i, %j
374 br i1 %cmp, label %cond_true, label %ret
375
376 cond_true:
377 %diff = sub i32 %i, %j
378 ret i32 %diff
379
380 ret:
381 ret i32 5
382 }
383
384 define i32 @test10(i32 %j, i32 %i) {
385 ; CHECK-LABEL: @test10(
386 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
387 ; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]])
388 ; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]])
389 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
390 ; CHECK: cond_true:
391 ; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
392 ; CHECK-NEXT: ret i32 [[DIFF]]
393 ; CHECK: ret:
394 ; CHECK-NEXT: ret i32 5
395 ;
396 %cmp = icmp eq i32 %i, %j
397 br i1 %cmp, label %cond_true, label %ret
398
399 cond_true:
400 %diff = sub i32 %i, %j
401 ret i32 %diff
402
403 ret:
404 ret i32 5
405 }
406
407 declare i32 @yogibar()
408
409 define i32 @test11(i32 %x) {
410 ; CHECK-LABEL: @test11(
411 ; CHECK-NEXT: [[V0:%.*]] = call i32 @yogibar()
412 ; CHECK-NEXT: [[V1:%.*]] = call i32 @yogibar()
413 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V0]], [[V1]]
414 ; CHECK: [[V0_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0]])
415 ; CHECK: [[V1_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V1]])
416 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[NEXT:%.*]]
417 ; CHECK: cond_true:
418 ; CHECK-NEXT: ret i32 [[V1_0]]
419 ; CHECK: next:
420 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], [[V0_0]]
421 ; CHECK: [[V0_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0_0]])
422 ; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE2:%.*]], label [[NEXT2:%.*]]
423 ; CHECK: cond_true2:
424 ; CHECK-NEXT: ret i32 [[V0_0_1]]
425 ; CHECK: next2:
426 ; CHECK-NEXT: ret i32 0
427 ;
428 %v0 = call i32 @yogibar()
429 %v1 = call i32 @yogibar()
430 %cmp = icmp eq i32 %v0, %v1
431 br i1 %cmp, label %cond_true, label %next
432
433 cond_true:
434 ret i32 %v1
435
436 next:
437 %cmp2 = icmp eq i32 %x, %v0
438 br i1 %cmp2, label %cond_true2, label %next2
439
440 cond_true2:
441 ret i32 %v0
442
443 next2:
444 ret i32 0
445 }
446
447 define i32 @test12(i32 %x) {
448 ; CHECK-LABEL: @test12(
449 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
450 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
451 ; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
452 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
453 ; CHECK: cond_true:
454 ; CHECK-NEXT: br label [[RET:%.*]]
455 ; CHECK: cond_false:
456 ; CHECK-NEXT: br label [[RET]]
457 ; CHECK: ret:
458 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0]], [[COND_TRUE]] ], [ [[X_1]], [[COND_FALSE]] ]
459 ; CHECK-NEXT: ret i32 [[RES]]
460 ;
461 %cmp = icmp eq i32 %x, 0
462 br i1 %cmp, label %cond_true, label %cond_false
463
464 cond_true:
465 br label %ret
466
467 cond_false:
468 br label %ret
469
470 ret:
471 %res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ]
472 ret i32 %res
473 }
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
11 ; RUN: opt -print-predicateinfo < %s 2>&1 | FileCheck %s
2 ; RUN: opt -print-predicateinfo -reverse-iterate < %s 2>&1 | FileCheck %s
32
43 declare void @foo(i1)
54 declare void @bar(i32)
0 ; REQUIRES: asserts
1 ; NOTE: The flag -reverse-iterate is present only in a +Asserts build.
2 ; Hence, this test has been split from testandor.ll to test with -reverse-iterate.
3 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
4 ; RUN: opt -print-predicateinfo -reverse-iterate < %s 2>&1 | FileCheck %s
5
6 declare void @foo(i1)
7 declare void @bar(i32)
8 declare void @llvm.assume(i1)
9
10 define void @testor(i32 %x, i32 %y) {
11 ; CHECK-LABEL: @testor(
12 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
13 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
14 ; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
15 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
16 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
17 ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
18 ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
19 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
20 ; CHECK-NEXT: br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
21 ; CHECK: oneof:
22 ; CHECK-NEXT: call void @foo(i1 [[XZ]])
23 ; CHECK-NEXT: call void @foo(i1 [[YZ]])
24 ; CHECK-NEXT: call void @bar(i32 [[X]])
25 ; CHECK-NEXT: call void @bar(i32 [[Y]])
26 ; CHECK-NEXT: ret void
27 ; CHECK: neither:
28 ; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
29 ; CHECK-NEXT: call void @foo(i1 [[YZ_0]])
30 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
31 ; CHECK-NEXT: call void @bar(i32 [[Y_0]])
32 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
33 ; CHECK-NEXT: ret void
34 ;
35 %xz = icmp eq i32 %x, 0
36 %yz = icmp eq i32 %y, 0
37 %z = or i1 %xz, %yz
38 br i1 %z, label %oneof, label %neither
39 oneof:
40 ;; Should not insert on the true edge for or
41 call void @foo(i1 %xz)
42 call void @foo(i1 %yz)
43 call void @bar(i32 %x)
44 call void @bar(i32 %y)
45 ret void
46 neither:
47 call void @foo(i1 %xz)
48 call void @foo(i1 %yz)
49 call void @bar(i32 %x)
50 call void @bar(i32 %y)
51 call void @foo(i1 %z)
52 ret void
53 }
54 define void @testand(i32 %x, i32 %y) {
55 ; CHECK-LABEL: @testand(
56 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
57 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
58 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
59 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
60 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
61 ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
62 ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
63 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
64 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
65 ; CHECK: both:
66 ; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
67 ; CHECK-NEXT: call void @foo(i1 [[YZ_0]])
68 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
69 ; CHECK-NEXT: call void @bar(i32 [[Y_0]])
70 ; CHECK-NEXT: ret void
71 ; CHECK: nope:
72 ; CHECK-NEXT: call void @foo(i1 [[XZ]])
73 ; CHECK-NEXT: call void @foo(i1 [[YZ]])
74 ; CHECK-NEXT: call void @bar(i32 [[X]])
75 ; CHECK-NEXT: call void @bar(i32 [[Y]])
76 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
77 ; CHECK-NEXT: ret void
78 ;
79 %xz = icmp eq i32 %x, 0
80 %yz = icmp eq i32 %y, 0
81 %z = and i1 %xz, %yz
82 br i1 %z, label %both, label %nope
83 both:
84 call void @foo(i1 %xz)
85 call void @foo(i1 %yz)
86 call void @bar(i32 %x)
87 call void @bar(i32 %y)
88 ret void
89 nope:
90 ;; Should not insert on the false edge for and
91 call void @foo(i1 %xz)
92 call void @foo(i1 %yz)
93 call void @bar(i32 %x)
94 call void @bar(i32 %y)
95 call void @foo(i1 %z)
96 ret void
97 }
98 define void @testandsame(i32 %x, i32 %y) {
99 ; CHECK-LABEL: @testandsame(
100 ; CHECK-NEXT: [[XGT:%.*]] = icmp sgt i32 [[X:%.*]], 0
101 ; CHECK-NEXT: [[XLT:%.*]] = icmp slt i32 [[X]], 100
102 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XGT]], [[XLT]]
103 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
104 ; CHECK: [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X_0]])
105 ; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XGT]])
106 ; CHECK: [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XLT]])
107 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
108 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
109 ; CHECK: both:
110 ; CHECK-NEXT: call void @foo(i1 [[XGT_0]])
111 ; CHECK-NEXT: call void @foo(i1 [[XLT_0]])
112 ; CHECK-NEXT: call void @bar(i32 [[X_0_1]])
113 ; CHECK-NEXT: ret void
114 ; CHECK: nope:
115 ; CHECK-NEXT: call void @foo(i1 [[XGT]])
116 ; CHECK-NEXT: call void @foo(i1 [[XLT]])
117 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
118 ; CHECK-NEXT: ret void
119 ;
120 %xgt = icmp sgt i32 %x, 0
121 %xlt = icmp slt i32 %x, 100
122 %z = and i1 %xgt, %xlt
123 br i1 %z, label %both, label %nope
124 both:
125 call void @foo(i1 %xgt)
126 call void @foo(i1 %xlt)
127 call void @bar(i32 %x)
128 ret void
129 nope:
130 call void @foo(i1 %xgt)
131 call void @foo(i1 %xlt)
132 call void @foo(i1 %z)
133 ret void
134 }
135
136 define void @testandassume(i32 %x, i32 %y) {
137 ; CHECK-LABEL: @testandassume(
138 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
139 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
140 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
141 ; CHECK: [[TMP1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
142 ; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
143 ; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
144 ; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
145 ; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
146 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP5]])
147 ; CHECK: [[DOT0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP1]])
148 ; CHECK: [[DOT01:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP2]])
149 ; CHECK: [[DOT02:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP3]])
150 ; CHECK: [[DOT03:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP4]])
151 ; CHECK: [[DOT04:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP5]])
152 ; CHECK-NEXT: br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]]
153 ; CHECK: both:
154 ; CHECK-NEXT: call void @foo(i1 [[DOT02]])
155 ; CHECK-NEXT: call void @foo(i1 [[DOT03]])
156 ; CHECK-NEXT: call void @bar(i32 [[DOT0]])
157 ; CHECK-NEXT: call void @bar(i32 [[DOT01]])
158 ; CHECK-NEXT: ret void
159 ; CHECK: nope:
160 ; CHECK-NEXT: call void @foo(i1 [[DOT04]])
161 ; CHECK-NEXT: ret void
162 ;
163 %xz = icmp eq i32 %x, 0
164 %yz = icmp eq i32 %y, 0
165 %z = and i1 %xz, %yz
166 call void @llvm.assume(i1 %z)
167 br i1 %z, label %both, label %nope
168 both:
169 call void @foo(i1 %xz)
170 call void @foo(i1 %yz)
171 call void @bar(i32 %x)
172 call void @bar(i32 %y)
173 ret void
174 nope:
175 call void @foo(i1 %z)
176 ret void
177 }
178
179 ;; Unlike and/or for branches, assume is *always* true, so we only match and for it
180 define void @testorassume(i32 %x, i32 %y) {
181 ;
182 ; CHECK-LABEL: @testorassume(
183 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
184 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
185 ; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
186 ; CHECK-NEXT: call void @llvm.assume(i1 [[Z]])
187 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
188 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
189 ; CHECK: both:
190 ; CHECK-NEXT: call void @foo(i1 [[XZ]])
191 ; CHECK-NEXT: call void @foo(i1 [[YZ]])
192 ; CHECK-NEXT: call void @bar(i32 [[X]])
193 ; CHECK-NEXT: call void @bar(i32 [[Y]])
194 ; CHECK-NEXT: ret void
195 ; CHECK: nope:
196 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
197 ; CHECK-NEXT: ret void
198 ;
199 %xz = icmp eq i32 %x, 0
200 %yz = icmp eq i32 %y, 0
201 %z = or i1 %xz, %yz
202 call void @llvm.assume(i1 %z)
203 br i1 %z, label %both, label %nope
204 both:
205 call void @foo(i1 %xz)
206 call void @foo(i1 %yz)
207 call void @bar(i32 %x)
208 call void @bar(i32 %y)
209 ret void
210 nope:
211 call void @foo(i1 %z)
212 ret void
213 }