1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=print-predicateinfo -disable-output < %s 2>&1 | FileCheck %s
4 @a = external global i32 ; <ptr> [#uses=7]
6 define i32 @test1() nounwind {
9 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4
10 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 4
11 ; CHECK-NEXT: br i1 [[TMP1]], label [[BB:%.*]], label [[BB1:%.*]]
13 ; CHECK-NEXT: br label [[BB8:%.*]]
15 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @a, align 4
16 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 5
17 ; CHECK-NEXT: br i1 [[TMP3]], label [[BB2:%.*]], label [[BB3:%.*]]
19 ; CHECK-NEXT: br label [[BB8]]
21 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr @a, align 4
22 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 4
23 ; CHECK-NEXT: br i1 [[TMP5]], label [[BB4:%.*]], label [[BB5:%.*]]
25 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr @a, align 4
26 ; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 5
27 ; CHECK-NEXT: br label [[BB8]]
29 ; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr @a, align 4
30 ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 5
31 ; CHECK-NEXT: br i1 [[TMP9]], label [[BB6:%.*]], label [[BB7:%.*]]
33 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr @a, align 4
34 ; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP10]], 4
35 ; CHECK-NEXT: br label [[BB8]]
37 ; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr @a, align 4
38 ; CHECK-NEXT: br label [[BB8]]
40 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP12]], [[BB7]] ], [ [[TMP11]], [[BB6]] ], [ [[TMP7]], [[BB4]] ], [ 4, [[BB2]] ], [ 5, [[BB]] ]
41 ; CHECK-NEXT: br label [[RETURN:%.*]]
43 ; CHECK-NEXT: ret i32 [[DOT0]]
46 %0 = load i32, ptr @a, align 4
47 %1 = icmp eq i32 %0, 4
48 br i1 %1, label %bb, label %bb1
54 %2 = load i32, ptr @a, align 4
55 %3 = icmp eq i32 %2, 5
56 br i1 %3, label %bb2, label %bb3
62 %4 = load i32, ptr @a, align 4
63 %5 = icmp eq i32 %4, 4
64 br i1 %5, label %bb4, label %bb5
67 %6 = load i32, ptr @a, align 4
72 %8 = load i32, ptr @a, align 4
73 %9 = icmp eq i32 %8, 5
74 br i1 %9, label %bb6, label %bb7
77 %10 = load i32, ptr @a, align 4
82 %12 = load i32, ptr @a, align 4
85 bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb
86 %.0 = phi i32 [ %12, %bb7 ], [ %11, %bb6 ], [ %7, %bb4 ], [ 4, %bb2 ], [ 5, %bb ]
89 return: ; preds = %bb8
94 declare void @bar(i32)
96 define void @test3(i32 %x, i32 %y) {
97 ; CHECK-LABEL: @test3(
98 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
99 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
100 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
101 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
102 ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
103 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
104 ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
105 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
106 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]
108 ; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
109 ; CHECK-NEXT: call void @foo(i1 [[YZ_0]])
110 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
111 ; CHECK-NEXT: call void @bar(i32 [[Y_0]])
112 ; CHECK-NEXT: ret void
114 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
115 ; CHECK-NEXT: ret void
117 %xz = icmp eq i32 %x, 0
118 %yz = icmp eq i32 %y, 0
120 br i1 %z, label %both_zero, label %nope
122 call void @foo(i1 %xz)
123 call void @foo(i1 %yz)
124 call void @bar(i32 %x)
125 call void @bar(i32 %y)
128 call void @foo(i1 %z)
132 define void @test4(i1 %b, i32 %x) {
133 ; CHECK-LABEL: @test4(
134 ; CHECK-NEXT: br i1 [[B:%.*]], label [[SW:%.*]], label [[CASE3:%.*]]
136 ; CHECK: i32 0, label [[CASE0:%.*]]
137 ; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
138 ; CHECK-NEXT: i32 2, label [[CASE0]]
139 ; CHECK-NEXT: i32 3, label [[CASE3]]
140 ; CHECK-NEXT: i32 4, label [[DEFAULT:%.*]]
141 ; CHECK-NEXT: ] Edge: [label [[SW]],label %case1], RenamedOp: [[X:%.*]] }
142 ; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
143 ; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT]] [
144 ; CHECK-NEXT: i32 0, label [[CASE0]]
145 ; CHECK-NEXT: i32 1, label [[CASE1]]
146 ; CHECK-NEXT: i32 2, label [[CASE0]]
147 ; CHECK-NEXT: i32 3, label [[CASE3]]
148 ; CHECK-NEXT: i32 4, label [[DEFAULT]]
151 ; CHECK-NEXT: call void @bar(i32 [[X]])
152 ; CHECK-NEXT: ret void
154 ; CHECK-NEXT: call void @bar(i32 [[X]])
155 ; CHECK-NEXT: ret void
157 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
158 ; CHECK-NEXT: ret void
160 ; CHECK-NEXT: call void @bar(i32 [[X]])
161 ; CHECK-NEXT: ret void
163 br i1 %b, label %sw, label %case3
165 switch i32 %x, label %default [
170 i32 4, label %default
173 call void @bar(i32 %x)
176 call void @bar(i32 %x)
179 call void @bar(i32 %x)
182 call void @bar(i32 %x)
186 define i1 @test5(i32 %x, i32 %y) {
187 ; CHECK-LABEL: @test5(
188 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
189 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
190 ; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
191 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
192 ; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
193 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
195 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X_0]], [[Y_0]]
196 ; CHECK-NEXT: ret i1 [[CMP2]]
198 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X_1]], [[Y_1]]
199 ; CHECK-NEXT: ret i1 [[CMP3]]
201 %cmp = icmp eq i32 %x, %y
202 br i1 %cmp, label %same, label %different
205 %cmp2 = icmp ne i32 %x, %y
209 %cmp3 = icmp eq i32 %x, %y
213 define i1 @test6(i32 %x, i32 %y) {
214 ; CHECK-LABEL: @test6(
215 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
216 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
217 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X]], [[Y]]
218 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
220 ; CHECK-NEXT: ret i1 [[CMP2]]
222 ; CHECK-NEXT: ret i1 [[CMP3]]
224 %cmp2 = icmp ne i32 %x, %y
225 %cmp = icmp eq i32 %x, %y
226 %cmp3 = icmp eq i32 %x, %y
227 br i1 %cmp, label %same, label %different
236 define i1 @test6_fp(float %x, float %y) {
237 ; CHECK-LABEL: @test6_fp(
238 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]
239 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X]], [[Y]]
240 ; CHECK-NEXT: [[CMP3:%.*]] = fcmp oeq float [[X]], [[Y]]
241 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
243 ; CHECK-NEXT: ret i1 [[CMP2]]
245 ; CHECK-NEXT: ret i1 [[CMP3]]
247 %cmp2 = fcmp une float %x, %y
248 %cmp = fcmp oeq float %x, %y
249 %cmp3 = fcmp oeq float %x, %y
250 br i1 %cmp, label %same, label %different
259 define i1 @test7(i32 %x, i32 %y) {
260 ; CHECK-LABEL: @test7(
261 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
262 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
263 ; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
264 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
265 ; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
266 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
268 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X_0]], [[Y_0]]
269 ; CHECK-NEXT: ret i1 [[CMP2]]
271 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[X_1]], [[Y_1]]
272 ; CHECK-NEXT: ret i1 [[CMP3]]
274 %cmp = icmp sgt i32 %x, %y
275 br i1 %cmp, label %same, label %different
278 %cmp2 = icmp sle i32 %x, %y
282 %cmp3 = icmp sgt i32 %x, %y
286 define i1 @test7_fp(float %x, float %y) {
287 ; CHECK-LABEL: @test7_fp(
288 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
289 ; CHECK: [[X_0:%.*]] = call float @llvm.ssa.copy.f32(float [[X]])
290 ; CHECK: [[X_1:%.*]] = call float @llvm.ssa.copy.f32(float [[X]])
291 ; CHECK: [[Y_0:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]])
292 ; CHECK: [[Y_1:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]])
293 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
295 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X_0]], [[Y_0]]
296 ; CHECK-NEXT: ret i1 [[CMP2]]
298 ; CHECK-NEXT: [[CMP3:%.*]] = fcmp ogt float [[X_1]], [[Y_1]]
299 ; CHECK-NEXT: ret i1 [[CMP3]]
301 %cmp = fcmp ogt float %x, %y
302 br i1 %cmp, label %same, label %different
305 %cmp2 = fcmp ule float %x, %y
309 %cmp3 = fcmp ogt float %x, %y
313 define i1 @test8(i32 %x, i32 %y) {
314 ; CHECK-LABEL: @test8(
315 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
316 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]
317 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[X]], [[Y]]
318 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
320 ; CHECK-NEXT: ret i1 [[CMP2]]
322 ; CHECK-NEXT: ret i1 [[CMP3]]
324 %cmp2 = icmp sle i32 %x, %y
325 %cmp = icmp sgt i32 %x, %y
326 %cmp3 = icmp sgt i32 %x, %y
327 br i1 %cmp, label %same, label %different
336 define i1 @test8_fp(float %x, float %y) {
337 ; CHECK-LABEL: @test8_fp(
338 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
339 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X]], [[Y]]
340 ; CHECK-NEXT: [[CMP3:%.*]] = fcmp ogt float [[X]], [[Y]]
341 ; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
343 ; CHECK-NEXT: ret i1 [[CMP2]]
345 ; CHECK-NEXT: ret i1 [[CMP3]]
347 %cmp2 = fcmp ule float %x, %y
348 %cmp = fcmp ogt float %x, %y
349 %cmp3 = fcmp ogt float %x, %y
350 br i1 %cmp, label %same, label %different
359 define i32 @test9(i32 %i, i32 %j) {
360 ; CHECK-LABEL: @test9(
361 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
362 ; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]])
363 ; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]])
364 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
366 ; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
367 ; CHECK-NEXT: ret i32 [[DIFF]]
369 ; CHECK-NEXT: ret i32 5
371 %cmp = icmp eq i32 %i, %j
372 br i1 %cmp, label %cond_true, label %ret
375 %diff = sub i32 %i, %j
382 define i32 @test10(i32 %j, i32 %i) {
383 ; CHECK-LABEL: @test10(
384 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
385 ; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]])
386 ; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]])
387 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
389 ; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
390 ; CHECK-NEXT: ret i32 [[DIFF]]
392 ; CHECK-NEXT: ret i32 5
394 %cmp = icmp eq i32 %i, %j
395 br i1 %cmp, label %cond_true, label %ret
398 %diff = sub i32 %i, %j
405 declare i32 @yogibar()
407 define i32 @test11(i32 %x) {
408 ; CHECK-LABEL: @test11(
409 ; CHECK-NEXT: [[V0:%.*]] = call i32 @yogibar()
410 ; CHECK-NEXT: [[V1:%.*]] = call i32 @yogibar()
411 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V0]], [[V1]]
412 ; CHECK: [[V0_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0]])
413 ; CHECK: [[V1_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V1]])
414 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[NEXT:%.*]]
416 ; CHECK-NEXT: ret i32 [[V1_0]]
418 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], [[V0_0]]
419 ; CHECK: [[V0_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0_0]])
420 ; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE2:%.*]], label [[NEXT2:%.*]]
422 ; CHECK-NEXT: ret i32 [[V0_0_1]]
424 ; CHECK-NEXT: ret i32 0
426 %v0 = call i32 @yogibar()
427 %v1 = call i32 @yogibar()
428 %cmp = icmp eq i32 %v0, %v1
429 br i1 %cmp, label %cond_true, label %next
435 %cmp2 = icmp eq i32 %x, %v0
436 br i1 %cmp2, label %cond_true2, label %next2
445 define i32 @test12(i32 %x) {
446 ; CHECK-LABEL: @test12(
447 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
448 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
449 ; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
450 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
452 ; CHECK-NEXT: br label [[RET:%.*]]
454 ; CHECK-NEXT: br label [[RET]]
456 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0]], [[COND_TRUE]] ], [ [[X_1]], [[COND_FALSE]] ]
457 ; CHECK-NEXT: ret i32 [[RES]]
459 %cmp = icmp eq i32 %x, 0
460 br i1 %cmp, label %cond_true, label %cond_false
469 %res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ]