1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6 define i32 @test1(i32 %A, i1 %b) {
9 ; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
11 ; CHECK-NEXT: ret i32 [[A:%.*]]
13 ; CHECK-NEXT: ret i32 [[A]]
16 br i1 %b, label %BB1, label %BB2
19 ; Combine away one argument PHI nodes
20 %B = phi i32 [ %A, %BB0 ]
27 define i32 @test2(i32 %A, i1 %b) {
28 ; CHECK-LABEL: @test2(
30 ; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
32 ; CHECK-NEXT: br label [[BB2]]
34 ; CHECK-NEXT: ret i32 [[A:%.*]]
37 br i1 %b, label %BB1, label %BB2
43 ; Combine away PHI nodes with same values
44 %B = phi i32 [ %A, %BB0 ], [ %A, %BB1 ]
48 define i32 @test3(i32 %A, i1 %b) {
49 ; CHECK-LABEL: @test3(
51 ; CHECK-NEXT: br label [[LOOP:%.*]]
53 ; CHECK-NEXT: br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]]
55 ; CHECK-NEXT: ret i32 [[A:%.*]]
61 ; PHI has same value always.
62 %B = phi i32 [ %A, %BB0 ], [ %B, %Loop ]
63 br i1 %b, label %Loop, label %Exit
69 define i32 @test4(i1 %b) {
70 ; CHECK-LABEL: @test4(
72 ; CHECK-NEXT: ret i32 7
74 ; CHECK-NEXT: br i1 [[B:%.*]], label [[L2:%.*]], label [[LOOP:%.*]]
76 ; CHECK-NEXT: br label [[LOOP]]
82 Loop: ; preds = %L2, %Loop
83 ; PHI has same value always.
84 %B = phi i32 [ %B, %L2 ], [ %B, %Loop ]
85 br i1 %b, label %L2, label %Loop
91 define i32 @test5_undef(i32 %A, i1 %cond) {
92 ; CHECK-LABEL: @test5_undef(
94 ; CHECK-NEXT: br label [[LOOP:%.*]]
96 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A:%.*]], [[BB0:%.*]] ], [ undef, [[LOOP]] ]
97 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
99 ; CHECK-NEXT: ret i32 [[B]]
104 Loop: ; preds = %Loop, %BB0
105 ; PHI has same value always.
106 %B = phi i32 [ %A, %BB0 ], [ undef, %Loop ]
107 br i1 %cond, label %Loop, label %Exit
109 Exit: ; preds = %Loop
113 define i32 @test5_poison(i32 %A, i1 %cond) {
114 ; CHECK-LABEL: @test5_poison(
116 ; CHECK-NEXT: br label [[LOOP:%.*]]
118 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
120 ; CHECK-NEXT: ret i32 [[A:%.*]]
125 Loop: ; preds = %Loop, %BB0
126 ; PHI has same value always.
127 %B = phi i32 [ %A, %BB0 ], [ poison, %Loop ]
128 br i1 %cond, label %Loop, label %Exit
130 Exit: ; preds = %Loop
134 define i32 @test6(i16 %A, i1 %b) {
135 ; CHECK-LABEL: @test6(
137 ; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
139 ; CHECK-NEXT: br label [[BB2]]
141 ; CHECK-NEXT: [[C:%.*]] = zext i16 [[A:%.*]] to i32
142 ; CHECK-NEXT: ret i32 [[C]]
145 %X = zext i16 %A to i32
146 br i1 %b, label %BB1, label %BB2
149 %Y = zext i16 %A to i32
153 ;; Suck casts into phi
154 %c = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
158 define i32 @test_dead_cycle(i32 %A, i1 %cond) {
159 ; CHECK-LABEL: @test_dead_cycle(
161 ; CHECK-NEXT: br label [[LOOP:%.*]]
163 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
165 ; CHECK-NEXT: ret i32 0
170 Loop: ; preds = %Loop, %BB0
171 %B = phi i32 [ %A, %BB0 ], [ %C, %Loop ]
173 br i1 %cond, label %Loop, label %Exit
175 Exit: ; preds = %Loop
179 define i32 @test_dead_UnaryOp_cycle(double %A, i1 %cond) {
180 ; CHECK-LABEL: @test_dead_UnaryOp_cycle(
182 ; CHECK-NEXT: br label [[LOOP:%.*]]
184 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
186 ; CHECK-NEXT: ret i32 0
191 Loop: ; preds = %Loop, %BB0
192 %B = phi double [ %A, %BB0 ], [ %C, %Loop ]
194 br i1 %cond, label %Loop, label %Exit
196 Exit: ; preds = %Loop
200 define i32 @test_dead_cycle_two_insts(i32 %A, i1 %cond) {
201 ; CHECK-LABEL: @test_dead_cycle_two_insts(
203 ; CHECK-NEXT: br label [[LOOP:%.*]]
205 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A:%.*]], [[BB0:%.*]] ], [ [[D:%.*]], [[LOOP]] ]
206 ; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], 123
207 ; CHECK-NEXT: [[D]] = lshr i32 [[C]], 1
208 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
210 ; CHECK-NEXT: ret i32 0
215 Loop: ; preds = %Loop, %BB0
216 %B = phi i32 [ %A, %BB0 ], [ %D, %Loop ]
219 br i1 %cond, label %Loop, label %Exit
221 Exit: ; preds = %Loop
225 declare i32 @llvm.uadd.sat.i32(i32, i32)
227 define i32 @test_dead_cycle_intrin(i32 %A, i1 %cond) {
228 ; CHECK-LABEL: @test_dead_cycle_intrin(
230 ; CHECK-NEXT: br label [[LOOP:%.*]]
232 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A:%.*]], [[BB0:%.*]] ], [ [[C:%.*]], [[LOOP]] ]
233 ; CHECK-NEXT: [[C]] = call i32 @llvm.uadd.sat.i32(i32 [[B]], i32 123)
234 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
236 ; CHECK-NEXT: ret i32 0
241 Loop: ; preds = %Loop, %BB0
242 %B = phi i32 [ %A, %BB0 ], [ %C, %Loop ]
243 %C = call i32 @llvm.uadd.sat.i32(i32 %B, i32 123)
244 br i1 %cond, label %Loop, label %Exit
246 Exit: ; preds = %Loop
250 define ptr @test8(ptr %A, i1 %b) {
251 ; CHECK-LABEL: @test8(
253 ; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
255 ; CHECK-NEXT: br label [[BB2]]
257 ; CHECK-NEXT: [[C:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4
258 ; CHECK-NEXT: ret ptr [[C]]
261 %X = getelementptr inbounds { i32, i32 }, ptr %A, i32 0, i32 1
262 br i1 %b, label %BB1, label %BB2
265 %Y = getelementptr { i32, i32 }, ptr %A, i32 0, i32 1
269 ;; Suck GEPs into phi
270 %c = phi ptr [ %X, %BB0 ], [ %Y, %BB1 ]
274 define i32 @test9(ptr %A, ptr %B) {
275 ; CHECK-LABEL: @test9(
277 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A:%.*]], null
278 ; CHECK-NEXT: br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]]
280 ; CHECK-NEXT: br label [[BB2:%.*]]
282 ; CHECK-NEXT: br label [[BB2]]
284 ; CHECK-NEXT: [[E_IN:%.*]] = phi ptr [ [[B:%.*]], [[BB]] ], [ [[A]], [[BB1]] ]
285 ; CHECK-NEXT: [[E:%.*]] = load i32, ptr [[E_IN]], align 1
286 ; CHECK-NEXT: ret i32 [[E]]
289 %c = icmp eq ptr %A, null
290 br i1 %c, label %bb1, label %bb
293 %C = load i32, ptr %B, align 1
297 %D = load i32, ptr %A, align 1
301 %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
306 define i32 @test10(ptr %A, ptr %B) {
307 ; CHECK-LABEL: @test10(
309 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A:%.*]], null
310 ; CHECK-NEXT: br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]]
312 ; CHECK-NEXT: br label [[BB2:%.*]]
314 ; CHECK-NEXT: br label [[BB2]]
316 ; CHECK-NEXT: [[E_IN:%.*]] = phi ptr [ [[B:%.*]], [[BB]] ], [ [[A]], [[BB1]] ]
317 ; CHECK-NEXT: [[E:%.*]] = load i32, ptr [[E_IN]], align 16
318 ; CHECK-NEXT: ret i32 [[E]]
321 %c = icmp eq ptr %A, null
322 br i1 %c, label %bb1, label %bb
325 %C = load i32, ptr %B, align 16
329 %D = load i32, ptr %A, align 32
333 %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
339 declare i1 @test11a()
341 define i1 @test11() {
342 ; CHECK-LABEL: @test11(
344 ; CHECK-NEXT: [[B:%.*]] = call i1 @test11a()
345 ; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
347 ; CHECK-NEXT: [[C:%.*]] = call i1 @test11a()
348 ; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]]
350 ; CHECK-NEXT: [[D:%.*]] = call i1 @test11a()
351 ; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]]
353 ; CHECK-NEXT: [[Z:%.*]] = call i1 @test11a()
354 ; CHECK-NEXT: ret i1 [[Z]]
358 %i = ptrtoint ptr %a to i64
359 %b = call i1 @test11a()
360 br i1 %b, label %one, label %two
363 %x = phi i64 [%i, %entry], [%y, %two]
364 %c = call i1 @test11a()
365 br i1 %c, label %two, label %end
368 %y = phi i64 [%i, %entry], [%x, %one]
369 %d = call i1 @test11a()
370 br i1 %d, label %one, label %end
373 %f = phi i64 [ %x, %one], [%y, %two]
374 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
375 ; even though %f must equal %i at this point
376 %g = inttoptr i64 %f to ptr
378 %z = call i1 @test11a()
383 define i64 @test12(i1 %cond, ptr %Ptr, i64 %Val) {
384 ; CHECK-LABEL: @test12(
386 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]]
388 ; CHECK-NEXT: br label [[END]]
390 ; CHECK-NEXT: [[T869_0_OFF64:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[VAL:%.*]], [[TWO]] ]
391 ; CHECK-NEXT: [[T41:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
392 ; CHECK-NEXT: [[T2:%.*]] = add i64 [[T869_0_OFF64]], [[T41]]
393 ; CHECK-NEXT: ret i64 [[T2]]
396 %t41 = ptrtoint ptr %Ptr to i64
397 %t42 = zext i64 %t41 to i128
398 br i1 %cond, label %end, label %two
401 %t36 = zext i64 %Val to i128 ; <i128> [#uses=1]
402 %t37 = shl i128 %t36, 64 ; <i128> [#uses=1]
403 %ins39 = or i128 %t42, %t37 ; <i128> [#uses=1]
407 %t869.0 = phi i128 [ %t42, %entry ], [ %ins39, %two ]
408 %t32 = trunc i128 %t869.0 to i64 ; <i64> [#uses=1]
409 %t29 = lshr i128 %t869.0, 64 ; <i128> [#uses=1]
410 %t30 = trunc i128 %t29 to i64 ; <i64> [#uses=1]
412 %t2 = add i64 %t32, %t30
416 declare void @test13f(double, i32)
418 define void @test13(i1 %cond, i32 %V1, double %Vald) {
419 ; CHECK-LABEL: @test13(
421 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]]
423 ; CHECK-NEXT: br label [[END]]
425 ; CHECK-NEXT: [[T31:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[VALD:%.*]], [[TWO]] ]
426 ; CHECK-NEXT: call void @test13f(double [[T31]], i32 [[V1:%.*]])
427 ; CHECK-NEXT: ret void
430 %t42 = zext i32 %V1 to i128
431 br i1 %cond, label %end, label %two
434 %Val = bitcast double %Vald to i64
435 %t36 = zext i64 %Val to i128 ; <i128> [#uses=1]
436 %t37 = shl i128 %t36, 64 ; <i128> [#uses=1]
437 %ins39 = or i128 %t42, %t37 ; <i128> [#uses=1]
441 %t869.0 = phi i128 [ %t42, %entry ], [ %ins39, %two ]
442 %t32 = trunc i128 %t869.0 to i32
443 %t29 = lshr i128 %t869.0, 64 ; <i128> [#uses=1]
444 %t30 = trunc i128 %t29 to i64 ; <i64> [#uses=1]
445 %t31 = bitcast i64 %t30 to double
447 call void @test13f(double %t31, i32 %t32)
451 define i640 @test14a(i320 %A, i320 %B, i1 %b1) {
452 ; CHECK-LABEL: @test14a(
454 ; CHECK-NEXT: br label [[LOOP:%.*]]
456 ; CHECK-NEXT: [[C_IN:%.*]] = phi i320 [ [[A:%.*]], [[BB0:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
457 ; CHECK-NEXT: br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
459 ; CHECK-NEXT: [[C:%.*]] = zext i320 [[C_IN]] to i640
460 ; CHECK-NEXT: ret i640 [[C]]
463 %a = zext i320 %A to i640
464 %b = zext i320 %B to i640
468 %C = phi i640 [ %a, %BB0 ], [ %b, %Loop ]
469 br i1 %b1, label %Loop, label %Exit
471 Exit: ; preds = %Loop
475 define i160 @test14b(i320 %pA, i320 %pB, i1 %b1) {
476 ; CHECK-LABEL: @test14b(
478 ; CHECK-NEXT: [[A:%.*]] = trunc i320 [[PA:%.*]] to i160
479 ; CHECK-NEXT: [[B:%.*]] = trunc i320 [[PB:%.*]] to i160
480 ; CHECK-NEXT: br label [[LOOP:%.*]]
482 ; CHECK-NEXT: [[C:%.*]] = phi i160 [ [[A]], [[BB0:%.*]] ], [ [[B]], [[LOOP]] ]
483 ; CHECK-NEXT: br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
485 ; CHECK-NEXT: ret i160 [[C]]
488 %a = trunc i320 %pA to i160
489 %b = trunc i320 %pB to i160
493 %C = phi i160 [ %a, %BB0 ], [ %b, %Loop ]
494 br i1 %b1, label %Loop, label %Exit
496 Exit: ; preds = %Loop
500 declare i64 @test15a(i64)
502 define i64 @test15b(i64 %A, i1 %b) {
503 ; CHECK-LABEL: @test15b(
505 ; CHECK-NEXT: br i1 [[B:%.*]], label [[ONE:%.*]], label [[TWO:%.*]]
507 ; CHECK-NEXT: [[X_OFF64:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[Y_OFF64:%.*]], [[TWO]] ]
508 ; CHECK-NEXT: [[C:%.*]] = call i64 @test15a(i64 [[X_OFF64]])
509 ; CHECK-NEXT: br label [[TWO]]
511 ; CHECK-NEXT: [[Y_OFF0:%.*]] = phi i64 [ [[A]], [[ENTRY]] ], [ [[C]], [[ONE]] ]
512 ; CHECK-NEXT: [[Y_OFF64]] = phi i64 [ [[A]], [[ENTRY]] ], [ 0, [[ONE]] ]
513 ; CHECK-NEXT: [[D:%.*]] = call i64 @test15a(i64 [[Y_OFF64]])
514 ; CHECK-NEXT: [[D1:%.*]] = trunc i64 [[D]] to i1
515 ; CHECK-NEXT: br i1 [[D1]], label [[ONE]], label [[END:%.*]]
517 ; CHECK-NEXT: ret i64 [[Y_OFF0]]
520 %i0 = zext i64 %A to i128
521 %i1 = shl i128 %i0, 64
522 %i = or i128 %i1, %i0
523 br i1 %b, label %one, label %two
526 %x = phi i128 [%i, %entry], [%y, %two]
527 %x1 = lshr i128 %x, 64
528 %x2 = trunc i128 %x1 to i64
529 %c = call i64 @test15a(i64 %x2)
530 %c1 = zext i64 %c to i128
535 %y = phi i128 [%i, %entry], [%c1, %one]
536 %y1 = lshr i128 %y, 64
537 %y2 = trunc i128 %y1 to i64
538 %d = call i64 @test15a(i64 %y2)
539 %d1 = trunc i64 %d to i1
540 br i1 %d1, label %one, label %end
544 %g = trunc i128 %y to i64
548 ; PR6512 - Shouldn't merge loads from different addr spaces.
549 define i32 @test16(ptr addrspace(1) %pointer1, i32 %flag, ptr %pointer2)
550 ; CHECK-LABEL: @test16(
552 ; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
553 ; CHECK-NEXT: [[POINTER1_ADDR:%.*]] = alloca ptr addrspace(1), align 4
554 ; CHECK-NEXT: [[POINTER2_ADDR:%.*]] = alloca ptr, align 4
555 ; CHECK-NEXT: store ptr addrspace(1) [[POINTER1:%.*]], ptr [[POINTER1_ADDR]], align 8
556 ; CHECK-NEXT: store ptr [[POINTER2:%.*]], ptr [[POINTER2_ADDR]], align 8
557 ; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[FLAG:%.*]], 0
558 ; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
560 ; CHECK-NEXT: [[T7:%.*]] = load i32, ptr [[RETVAL]], align 4
561 ; CHECK-NEXT: ret i32 [[T7]]
563 ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[T5:%.*]], [[IF_ELSE]] ], [ [[T2:%.*]], [[IF_THEN]] ]
564 ; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[RETVAL]], align 4
565 ; CHECK-NEXT: br label [[RETURN:%.*]]
567 ; CHECK-NEXT: [[T1:%.*]] = load ptr addrspace(1), ptr [[POINTER1_ADDR]], align 8
568 ; CHECK-NEXT: [[T2]] = load i32, ptr addrspace(1) [[T1]], align 4
569 ; CHECK-NEXT: br label [[IF_END:%.*]]
571 ; CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[POINTER2_ADDR]], align 8
572 ; CHECK-NEXT: [[T5]] = load i32, ptr [[T3]], align 4
573 ; CHECK-NEXT: br label [[IF_END]]
577 %retval = alloca i32, align 4 ; <ptr> [#uses=2]
578 %pointer1.addr = alloca ptr addrspace(1), align 4 ; <ptr>
579 %flag.addr = alloca i32, align 4 ; <ptr> [#uses=2]
580 %pointer2.addr = alloca ptr, align 4 ; <ptr> [#uses=2]
581 %res = alloca i32, align 4 ; <ptr> [#uses=4]
582 store ptr addrspace(1) %pointer1, ptr %pointer1.addr
583 store i32 %flag, ptr %flag.addr
584 store ptr %pointer2, ptr %pointer2.addr
585 store i32 10, ptr %res
586 %t = load i32, ptr %flag.addr ; <i32> [#uses=1]
587 %tobool = icmp ne i32 %t, 0 ; <i1> [#uses=1]
588 br i1 %tobool, label %if.then, label %if.else
590 return: ; preds = %if.end
591 %t7 = load i32, ptr %retval ; <i32> [#uses=1]
594 if.end: ; preds = %if.else, %if.then
595 %t6 = load i32, ptr %res ; <i32> [#uses=1]
596 store i32 %t6, ptr %retval
599 if.then: ; preds = %entry
600 %t1 = load ptr addrspace(1), ptr %pointer1.addr ; <ptr addrspace(1)>
601 %arrayidx = getelementptr i32, ptr addrspace(1) %t1, i32 0 ; <ptr addrspace(1)> [#uses=1]
602 %t2 = load i32, ptr addrspace(1) %arrayidx ; <i32> [#uses=1]
603 store i32 %t2, ptr %res
606 if.else: ; preds = %entry
607 %t3 = load ptr, ptr %pointer2.addr ; <ptr> [#uses=1]
608 %arrayidx4 = getelementptr i32, ptr %t3, i32 0 ; <ptr> [#uses=1]
609 %t5 = load i32, ptr %arrayidx4 ; <i32> [#uses=1]
610 store i32 %t5, ptr %res
616 define i32 @test17(i1 %a) {
617 ; CHECK-LABEL: @test17(
619 ; CHECK-NEXT: br i1 [[A:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
621 ; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @ext()
622 ; CHECK-NEXT: br label [[BB2]]
624 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[TMP0]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]
625 ; CHECK-NEXT: ret i32 [[RES]]
628 br i1 %a, label %bb1, label %bb2
630 bb1: ; preds = %entry
631 %0 = tail call i32 @ext() ; <i32> [#uses=1]
634 bb2: ; preds = %bb1, %entry
635 %cond = phi i1 [ true, %bb1 ], [ false, %entry ] ; <i1> [#uses=1]
636 %val = phi i32 [ %0, %bb1 ], [ 0, %entry ] ; <i32> [#uses=1]
637 %res = select i1 %cond, i32 %val, i32 0 ; <i32> [#uses=1]
641 ; Atomic and non-atomic loads should not be combined.
642 define i32 @PR51435(ptr %ptr, ptr %atomic_ptr, i1 %c) {
643 ; CHECK-LABEL: @PR51435(
645 ; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[PTR:%.*]], align 4
646 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]
648 ; CHECK-NEXT: [[Y:%.*]] = load atomic i32, ptr [[ATOMIC_PTR:%.*]] acquire, align 4
649 ; CHECK-NEXT: br label [[END]]
651 ; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[X]], [[ENTRY:%.*]] ], [ [[Y]], [[IF]] ]
652 ; CHECK-NEXT: ret i32 [[COND]]
655 %x = load i32, ptr %ptr, align 4
656 br i1 %c, label %if, label %end
659 %y = load atomic i32, ptr %atomic_ptr acquire, align 4
663 %cond = phi i32 [ %x, %entry ], [ %y, %if ]
667 define i1 @test18(i1 %cond) {
668 ; CHECK-LABEL: @test18(
669 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
671 ; CHECK-NEXT: br label [[RET:%.*]]
673 ; CHECK-NEXT: br label [[RET]]
675 ; CHECK-NEXT: ret i1 false
679 br i1 %cond, label %true, label %false
685 %ptr = phi ptr [ %zero, %true ] , [ %one, %false ]
686 %isnull = icmp eq ptr %ptr, null
690 define i1 @test19(i1 %cond, double %x) {
691 ; CHECK-LABEL: @test19(
692 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
694 ; CHECK-NEXT: br label [[RET:%.*]]
696 ; CHECK-NEXT: br label [[RET]]
698 ; CHECK-NEXT: ret i1 true
700 br i1 %cond, label %true, label %false
706 %p = phi double [ %x, %true ], [ 0x7FF0000000000000, %false ]; RHS = +infty
707 %cmp = fcmp ule double %x, %p
711 define i1 @test20(i1 %cond) {
712 ; CHECK-LABEL: @test20(
713 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
715 ; CHECK-NEXT: br label [[RET:%.*]]
717 ; CHECK-NEXT: br label [[RET]]
719 ; CHECK-NEXT: ret i1 false
724 br i1 %cond, label %true, label %false
730 %p = phi ptr [ %a, %true ], [ %b, %false ]
731 %r = icmp eq ptr %p, %c
735 define i1 @test21(i1 %c1, i1 %c2) {
736 ; CHECK-LABEL: @test21(
737 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
739 ; CHECK-NEXT: br label [[LOOP:%.*]]
741 ; CHECK-NEXT: br label [[LOOP]]
743 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[RET:%.*]], label [[LOOP]]
745 ; CHECK-NEXT: ret i1 false
750 br i1 %c1, label %true, label %false
756 %p = phi ptr [ %a, %true ], [ %b, %false ], [ %p, %loop ]
757 %r = icmp eq ptr %p, %c
758 br i1 %c2, label %ret, label %loop
763 define void @test22() {
764 ; CHECK-LABEL: @test22(
766 ; CHECK-NEXT: br label [[LOOP:%.*]]
768 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y:%.*]], [[LOOP]] ]
769 ; CHECK-NEXT: [[Y]] = add i32 [[PHI]], 1
770 ; CHECK-NEXT: [[O:%.*]] = or i32 [[Y]], [[PHI]]
771 ; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[O]], [[Y]]
772 ; CHECK-NEXT: br i1 [[E]], label [[LOOP]], label [[RET:%.*]]
774 ; CHECK-NEXT: ret void
779 %phi = phi i32 [ 0, %entry ], [ %y, %loop ]
782 %e = icmp eq i32 %o, %y
783 br i1 %e, label %loop, label %ret
788 define i32 @test23(i32 %A, i1 %pb, ptr %P) {
789 ; CHECK-LABEL: @test23(
791 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[A:%.*]], 19
792 ; CHECK-NEXT: br label [[LOOP:%.*]]
794 ; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[TMP0]], [[BB0:%.*]] ], [ 61, [[LOOP]] ]
795 ; CHECK-NEXT: store i32 [[B]], ptr [[P:%.*]], align 4
796 ; CHECK-NEXT: br i1 [[PB:%.*]], label [[LOOP]], label [[EXIT:%.*]]
798 ; CHECK-NEXT: ret i32 [[B]]
803 Loop: ; preds = %Loop, %BB0
804 ; PHI has same value always.
805 %B = phi i32 [ %A, %BB0 ], [ 42, %Loop ]
808 br i1 %pb, label %Loop, label %Exit
810 Exit: ; preds = %Loop
815 define i32 @test24(i32 %A, i1 %cond) {
816 ; CHECK-LABEL: @test24(
818 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
820 ; CHECK-NEXT: br label [[BB2]]
822 ; CHECK-NEXT: [[C:%.*]] = add nuw i32 [[A:%.*]], 1
823 ; CHECK-NEXT: ret i32 [[C]]
826 %X = add nuw nsw i32 %A, 1
827 br i1 %cond, label %BB1, label %BB2
830 %Y = add nuw i32 %A, 1
834 %C = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
838 ; Same as test11, but used to be missed due to a bug.
839 declare i1 @test25a()
841 define i1 @test25() {
842 ; CHECK-LABEL: @test25(
844 ; CHECK-NEXT: [[B:%.*]] = call i1 @test25a()
845 ; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
847 ; CHECK-NEXT: [[C:%.*]] = call i1 @test25a()
848 ; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]]
850 ; CHECK-NEXT: [[D:%.*]] = call i1 @test25a()
851 ; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]]
853 ; CHECK-NEXT: [[Z:%.*]] = call i1 @test25a()
854 ; CHECK-NEXT: ret i1 [[Z]]
858 %i = ptrtoint ptr %a to i64
859 %b = call i1 @test25a()
860 br i1 %b, label %one, label %two
863 %x = phi i64 [%y, %two], [%i, %entry]
864 %c = call i1 @test25a()
865 br i1 %c, label %two, label %end
868 %y = phi i64 [%x, %one], [%i, %entry]
869 %d = call i1 @test25a()
870 br i1 %d, label %one, label %end
873 %f = phi i64 [ %x, %one], [%y, %two]
874 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
875 ; even though %f must equal %i at this point
876 %g = inttoptr i64 %f to ptr
878 %z = call i1 @test25a()
882 ; Same as above, but the input is also a phi
883 define i1 @test25b(i1 %ci, i64 %ai, i64 %bi) {
884 ; CHECK-LABEL: @test25b(
886 ; CHECK-NEXT: br i1 [[CI:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
888 ; CHECK-NEXT: br label [[ELSE]]
890 ; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[AI:%.*]], [[ENTRY:%.*]] ], [ [[BI:%.*]], [[THEN]] ]
891 ; CHECK-NEXT: [[B:%.*]] = call i1 @test25a()
892 ; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
894 ; CHECK-NEXT: [[C:%.*]] = call i1 @test25a()
895 ; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]]
897 ; CHECK-NEXT: [[D:%.*]] = call i1 @test25a()
898 ; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]]
900 ; CHECK-NEXT: [[G:%.*]] = inttoptr i64 [[I]] to ptr
901 ; CHECK-NEXT: store i32 10, ptr [[G]], align 4
902 ; CHECK-NEXT: [[Z:%.*]] = call i1 @test25a()
903 ; CHECK-NEXT: ret i1 [[Z]]
906 br i1 %ci, label %then, label %else
912 %i = phi i64 [ %ai, %entry ], [ %bi, %then ]
913 %b = call i1 @test25a()
914 br i1 %b, label %one, label %two
917 %x = phi i64 [%y, %two], [%i, %else]
918 %c = call i1 @test25a()
919 br i1 %c, label %two, label %end
922 %y = phi i64 [%x, %one], [%i, %else]
923 %d = call i1 @test25a()
924 br i1 %d, label %one, label %end
927 %f = phi i64 [ %x, %one], [%y, %two]
928 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
929 ; even though %f must equal %i at this point
930 %g = inttoptr i64 %f to ptr
932 %z = call i1 @test25a()
936 declare i1 @test26a()
938 define i1 @test26(i32 %n) {
939 ; CHECK-LABEL: @test26(
941 ; CHECK-NEXT: [[B:%.*]] = call i1 @test26a()
942 ; CHECK-NEXT: br label [[ONE:%.*]]
944 ; CHECK-NEXT: [[C:%.*]] = call i1 @test26a()
945 ; CHECK-NEXT: switch i32 [[N:%.*]], label [[END:%.*]] [
946 ; CHECK-NEXT: i32 2, label [[TWO:%.*]]
947 ; CHECK-NEXT: i32 3, label [[THREE:%.*]]
950 ; CHECK-NEXT: [[D:%.*]] = call i1 @test26a()
951 ; CHECK-NEXT: switch i32 [[N]], label [[END]] [
952 ; CHECK-NEXT: i32 10, label [[ONE]]
953 ; CHECK-NEXT: i32 30, label [[THREE]]
956 ; CHECK-NEXT: [[E:%.*]] = call i1 @test26a()
957 ; CHECK-NEXT: br i1 [[E]], label [[ONE]], label [[TWO]]
959 ; CHECK-NEXT: [[Z:%.*]] = call i1 @test26a()
960 ; CHECK-NEXT: ret i1 [[Z]]
964 %i = ptrtoint ptr %a to i64
965 %b = call i1 @test26a()
969 %x = phi i64 [%y, %two], [%w, %three], [%i, %entry]
970 %c = call i1 @test26a()
971 switch i32 %n, label %end [
977 %y = phi i64 [%x, %one], [%w, %three]
978 %d = call i1 @test26a()
979 switch i32 %n, label %end [
985 %w = phi i64 [%y, %two], [%x, %one]
986 %e = call i1 @test26a()
987 br i1 %e, label %one, label %two
990 %f = phi i64 [ %x, %one], [%y, %two]
991 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
992 ; even though %f must equal %i at this point
993 %g = inttoptr i64 %f to ptr
995 %z = call i1 @test26a()
999 define i32 @test27(i1 %b) {
1000 ; CHECK-LABEL: @test27(
1001 ; CHECK-NEXT: entry:
1002 ; CHECK-NEXT: br label [[DONE:%.*]]
1004 ; CHECK-NEXT: ret i32 undef
1009 %y = phi i32 [ undef, %entry ]
1013 ; We should be able to fold the zexts to the other side of the phi
1014 ; even though there's a constant value input to the phi. This is
1015 ; because we can shrink that constant to the smaller phi type.
1017 define i1 @PR24766(i8 %x1, i8 %x2, i8 %condition) {
1018 ; CHECK-LABEL: @PR24766(
1019 ; CHECK-NEXT: entry:
1020 ; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1021 ; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1022 ; CHECK-NEXT: i8 1, label [[SW2:%.*]]
1025 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1026 ; CHECK-NEXT: br label [[EPILOG]]
1028 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1029 ; CHECK-NEXT: br label [[EPILOG]]
1031 ; CHECK-NEXT: [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ]
1032 ; CHECK-NEXT: ret i1 [[CONDITIONMET_SHRUNK]]
1035 %conv = sext i8 %condition to i32
1036 switch i32 %conv, label %epilog [
1042 %cmp1 = icmp eq i8 %x1, %x2
1043 %frombool1 = zext i1 %cmp1 to i8
1047 %cmp2 = icmp sle i8 %x1, %x2
1048 %frombool2 = zext i1 %cmp2 to i8
1052 %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
1053 %tobool = icmp ne i8 %conditionMet, 0
1058 ; Same as above (a phi with more than 2 operands), but no constants
1060 define i1 @PR24766_no_constants(i8 %x1, i8 %x2, i8 %condition, i1 %another_condition) {
1061 ; CHECK-LABEL: @PR24766_no_constants(
1062 ; CHECK-NEXT: entry:
1063 ; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1064 ; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1065 ; CHECK-NEXT: i8 1, label [[SW2:%.*]]
1068 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1069 ; CHECK-NEXT: br label [[EPILOG]]
1071 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1072 ; CHECK-NEXT: br label [[EPILOG]]
1074 ; CHECK-NEXT: [[CONDITIONMET_IN:%.*]] = phi i1 [ [[ANOTHER_CONDITION:%.*]], [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ]
1075 ; CHECK-NEXT: ret i1 [[CONDITIONMET_IN]]
1078 %frombool0 = zext i1 %another_condition to i8
1079 %conv = sext i8 %condition to i32
1080 switch i32 %conv, label %epilog [
1086 %cmp1 = icmp eq i8 %x1, %x2
1087 %frombool1 = zext i1 %cmp1 to i8
1091 %cmp2 = icmp sle i8 %x1, %x2
1092 %frombool2 = zext i1 %cmp2 to i8
1096 %conditionMet = phi i8 [ %frombool0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
1097 %tobool = icmp ne i8 %conditionMet, 0
1102 ; Same as above (a phi with more than 2 operands), but two constants
1104 define i1 @PR24766_two_constants(i8 %x1, i8 %x2, i8 %condition) {
1105 ; CHECK-LABEL: @PR24766_two_constants(
1106 ; CHECK-NEXT: entry:
1107 ; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1108 ; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1109 ; CHECK-NEXT: i8 1, label [[SW2:%.*]]
1112 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1113 ; CHECK-NEXT: br label [[EPILOG]]
1115 ; CHECK-NEXT: br label [[EPILOG]]
1117 ; CHECK-NEXT: [[CONDITIONMET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[SW2]] ], [ [[CMP1]], [[SW1]] ]
1118 ; CHECK-NEXT: ret i1 [[CONDITIONMET]]
1121 %conv = sext i8 %condition to i32
1122 switch i32 %conv, label %epilog [
1128 %cmp1 = icmp eq i8 %x1, %x2
1129 %frombool1 = zext i1 %cmp1 to i8
1133 %cmp2 = icmp sle i8 %x1, %x2
1134 %frombool2 = zext i1 %cmp2 to i8
1138 %conditionMet = phi i8 [ 0, %entry ], [ 1, %sw2 ], [ %frombool1, %sw1 ]
1139 %tobool = icmp ne i8 %conditionMet, 0
1144 ; Same as above (a phi with more than 2 operands), but two constants and two variables
1146 define i1 @PR24766_two_constants_two_var(i8 %x1, i8 %x2, i8 %condition) {
1147 ; CHECK-LABEL: @PR24766_two_constants_two_var(
1148 ; CHECK-NEXT: entry:
1149 ; CHECK-NEXT: switch i8 [[CONDITION:%.*]], label [[EPILOG:%.*]] [
1150 ; CHECK-NEXT: i8 0, label [[SW1:%.*]]
1151 ; CHECK-NEXT: i8 1, label [[SW2:%.*]]
1152 ; CHECK-NEXT: i8 2, label [[SW3:%.*]]
1155 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1156 ; CHECK-NEXT: br label [[EPILOG]]
1158 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1159 ; CHECK-NEXT: br label [[EPILOG]]
1161 ; CHECK-NEXT: br label [[EPILOG]]
1163 ; CHECK-NEXT: [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ], [ true, [[SW3]] ]
1164 ; CHECK-NEXT: ret i1 [[CONDITIONMET_SHRUNK]]
1167 %conv = sext i8 %condition to i32
1168 switch i32 %conv, label %epilog [
1175 %cmp1 = icmp eq i8 %x1, %x2
1176 %frombool1 = zext i1 %cmp1 to i8
1180 %cmp2 = icmp sle i8 %x1, %x2
1181 %frombool2 = zext i1 %cmp2 to i8
1185 %cmp3 = icmp sge i8 %x1, %x2
1186 %frombool3 = zext i1 %cmp3 to i8
1190 %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ], [ 1, %sw3 ]
1191 %tobool = icmp ne i8 %conditionMet, 0
1196 define i1 @phi_allnonzeroconstant(i1 %c, i32 %a, i32 %b) {
1197 ; CHECK-LABEL: @phi_allnonzeroconstant(
1198 ; CHECK-NEXT: entry:
1199 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1201 ; CHECK-NEXT: br label [[IF_END:%.*]]
1203 ; CHECK-NEXT: call void @dummy()
1204 ; CHECK-NEXT: br label [[IF_END]]
1206 ; CHECK-NEXT: ret i1 false
1209 br i1 %c, label %if.then, label %if.else
1211 if.then: ; preds = %entry
1214 if.else: ; preds = %entry
1219 if.end: ; preds = %if.else, %if.then
1220 %x.0 = phi i32 [ 1, %if.then ], [ 2, %if.else ]
1221 %or = or i32 %x.0, %a
1222 %cmp1 = icmp eq i32 %or, 0
1226 define i1 @phi_allnonzerononconstant(i1 %c, i32 %a, ptr nonnull %b1, ptr nonnull %b2) {
1227 ; CHECK-LABEL: @phi_allnonzerononconstant(
1228 ; CHECK-NEXT: entry:
1229 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1231 ; CHECK-NEXT: br label [[IF_END:%.*]]
1233 ; CHECK-NEXT: call void @dummy()
1234 ; CHECK-NEXT: br label [[IF_END]]
1236 ; CHECK-NEXT: ret i1 false
1239 br i1 %c, label %if.then, label %if.else
1241 if.then: ; preds = %entry
1244 if.else: ; preds = %entry
1249 if.end: ; preds = %if.else, %if.then
1250 %x.0 = phi ptr [ %b1, %if.then ], [ %b2, %if.else ]
1251 %cmp1 = icmp eq ptr %x.0, null
1255 declare void @dummy()
1257 define i1 @phi_knownnonzero_eq(i32 %n, i32 %s, ptr nocapture readonly %P) {
1258 ; CHECK-LABEL: @phi_knownnonzero_eq(
1259 ; CHECK-NEXT: entry:
1260 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1261 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1263 ; CHECK-NEXT: br label [[IF_END]]
1265 ; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1266 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0
1267 ; CHECK-NEXT: ret i1 [[CMP1]]
1270 %tobool = icmp slt i32 %n, %s
1271 br i1 %tobool, label %if.end, label %if.then
1273 if.then: ; preds = %entry
1274 %0 = load i32, ptr %P
1275 %cmp = icmp eq i32 %n, %0
1276 %1 = select i1 %cmp, i32 1, i32 2
1279 if.end: ; preds = %entry, %if.then
1280 %a.0 = phi i32 [ %1, %if.then ], [ %n, %entry ]
1281 %cmp1 = icmp eq i32 %a.0, 0
1285 define i1 @phi_knownnonzero_ne(i32 %n, i32 %s, ptr nocapture readonly %P) {
1286 ; CHECK-LABEL: @phi_knownnonzero_ne(
1287 ; CHECK-NEXT: entry:
1288 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1289 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1291 ; CHECK-NEXT: br label [[IF_END]]
1293 ; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1294 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0
1295 ; CHECK-NEXT: ret i1 [[CMP1]]
1298 %tobool = icmp slt i32 %n, %s
1299 br i1 %tobool, label %if.end, label %if.then
1301 if.then: ; preds = %entry
1302 %0 = load i32, ptr %P
1303 %cmp = icmp eq i32 %n, %0
1304 %1 = select i1 %cmp, i32 1, i32 2
1307 if.end: ; preds = %entry, %if.then
1308 %a.0 = phi i32 [ %1, %if.then ], [ %n, %entry ]
1309 %cmp1 = icmp ne i32 %a.0, 0
1313 define i1 @phi_knownnonzero_eq_2(i32 %n, i32 %s, ptr nocapture readonly %P) {
1314 ; CHECK-LABEL: @phi_knownnonzero_eq_2(
1315 ; CHECK-NEXT: entry:
1316 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1317 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1319 ; CHECK-NEXT: br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]]
1321 ; CHECK-NEXT: br label [[IF_END]]
1323 ; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ poison, [[IF_THEN]] ]
1324 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0
1325 ; CHECK-NEXT: ret i1 [[CMP1]]
1328 %tobool = icmp slt i32 %n, %s
1329 br i1 %tobool, label %if.then, label %if.end
1332 %tobool2 = icmp slt i32 %n, %s
1333 br i1 %tobool2, label %if.else, label %if.end
1335 if.else: ; preds = %entry
1336 %0 = load i32, ptr %P
1337 %cmp = icmp eq i32 %n, %0
1338 %1 = select i1 %cmp, i32 1, i32 2
1341 if.end: ; preds = %entry, %if.then
1342 %a.0 = phi i32 [ %1, %if.else], [ %n, %entry ], [2, %if.then]
1343 %cmp1 = icmp eq i32 %a.0, 0
1347 define i1 @phi_knownnonzero_ne_2(i32 %n, i32 %s, ptr nocapture readonly %P) {
1348 ; CHECK-LABEL: @phi_knownnonzero_ne_2(
1349 ; CHECK-NEXT: entry:
1350 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1351 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1353 ; CHECK-NEXT: br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]]
1355 ; CHECK-NEXT: br label [[IF_END]]
1357 ; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ poison, [[IF_THEN]] ]
1358 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0
1359 ; CHECK-NEXT: ret i1 [[CMP1]]
1362 %tobool = icmp slt i32 %n, %s
1363 br i1 %tobool, label %if.then, label %if.end
1366 %tobool2 = icmp slt i32 %n, %s
1367 br i1 %tobool2, label %if.else, label %if.end
1369 if.else: ; preds = %entry
1370 %0 = load i32, ptr %P
1371 %cmp = icmp eq i32 %n, %0
1372 %1 = select i1 %cmp, i32 1, i32 2
1375 if.end: ; preds = %entry, %if.then
1376 %a.0 = phi i32 [ %1, %if.else], [ %n, %entry ], [2, %if.then]
1377 %cmp1 = icmp ne i32 %a.0, 0
1381 define i1 @phi_knownnonzero_eq_oricmp(i32 %n, i32 %s, ptr %P, i32 %val) {
1382 ; CHECK-LABEL: @phi_knownnonzero_eq_oricmp(
1383 ; CHECK-NEXT: entry:
1384 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1385 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1387 ; CHECK-NEXT: br label [[IF_END]]
1389 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1390 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[PHI]], [[VAL:%.*]]
1391 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ORPHI]], 0
1392 ; CHECK-NEXT: ret i1 [[CMP1]]
1395 %tobool = icmp slt i32 %n, %s
1396 br i1 %tobool, label %if.end, label %if.then
1399 %load = load i32, ptr %P
1400 %cmp = icmp eq i32 %n, %load
1401 %sel = select i1 %cmp, i32 1, i32 2
1405 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1406 %orphi = or i32 %phi, %val
1407 %cmp1 = icmp eq i32 %orphi, 0
1411 define i1 @phi_knownnonzero_eq_oricmp_commuted(i32 %n, i32 %s, ptr %P, i32 %val) {
1412 ; CHECK-LABEL: @phi_knownnonzero_eq_oricmp_commuted(
1413 ; CHECK-NEXT: entry:
1414 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1415 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1417 ; CHECK-NEXT: br label [[IF_END]]
1419 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1420 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[VAL:%.*]], [[PHI]]
1421 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ORPHI]], 0
1422 ; CHECK-NEXT: ret i1 [[CMP1]]
1425 %tobool = icmp slt i32 %n, %s
1426 br i1 %tobool, label %if.end, label %if.then
1429 %load = load i32, ptr %P
1430 %cmp = icmp eq i32 %n, %load
1431 %sel = select i1 %cmp, i32 1, i32 2
1435 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1436 %orphi = or i32 %val, %phi
1437 %cmp1 = icmp eq i32 %orphi, 0
1441 define i1 @phi_knownnonzero_eq_or_disjoint_icmp(i32 %n, i32 %s, ptr %P, i32 %val) {
1442 ; CHECK-LABEL: @phi_knownnonzero_eq_or_disjoint_icmp(
1443 ; CHECK-NEXT: entry:
1444 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1445 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1447 ; CHECK-NEXT: br label [[IF_END]]
1449 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1450 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[PHI]], [[VAL:%.*]]
1451 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ORPHI]], 0
1452 ; CHECK-NEXT: ret i1 [[CMP1]]
1455 %tobool = icmp slt i32 %n, %s
1456 br i1 %tobool, label %if.end, label %if.then
1459 %load = load i32, ptr %P
1460 %cmp = icmp eq i32 %n, %load
1461 %sel = select i1 %cmp, i32 1, i32 2
1465 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1466 %orphi = or disjoint i32 %phi, %val
1467 %cmp1 = icmp eq i32 %orphi, 0
1471 define i1 @phi_knownnonzero_ne_oricmp(i32 %n, i32 %s, ptr %P, i32 %val) {
1472 ; CHECK-LABEL: @phi_knownnonzero_ne_oricmp(
1473 ; CHECK-NEXT: entry:
1474 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1475 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1477 ; CHECK-NEXT: br label [[IF_END]]
1479 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1480 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[PHI]], [[VAL:%.*]]
1481 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[ORPHI]], 0
1482 ; CHECK-NEXT: ret i1 [[CMP1]]
1485 %tobool = icmp slt i32 %n, %s
1486 br i1 %tobool, label %if.end, label %if.then
1489 %load = load i32, ptr %P
1490 %cmp = icmp eq i32 %n, %load
1491 %sel = select i1 %cmp, i32 1, i32 2
1495 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1496 %orphi = or i32 %phi, %val
1497 %cmp1 = icmp ne i32 %orphi, 0
1501 define i1 @phi_knownnonzero_ne_oricmp_commuted(i32 %n, i32 %s, ptr %P, i32 %val) {
1502 ; CHECK-LABEL: @phi_knownnonzero_ne_oricmp_commuted(
1503 ; CHECK-NEXT: entry:
1504 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1505 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1507 ; CHECK-NEXT: br label [[IF_END]]
1509 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1510 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[VAL:%.*]], [[PHI]]
1511 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[ORPHI]], 0
1512 ; CHECK-NEXT: ret i1 [[CMP1]]
1515 %tobool = icmp slt i32 %n, %s
1516 br i1 %tobool, label %if.end, label %if.then
1519 %load = load i32, ptr %P
1520 %cmp = icmp eq i32 %n, %load
1521 %sel = select i1 %cmp, i32 1, i32 2
1525 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1526 %orphi = or i32 %val, %phi
1527 %cmp1 = icmp ne i32 %orphi, 0
1531 define i1 @phi_knownnonzero_eq_multiuse_oricmp(i32 %n, i32 %s, ptr %P, i32 %val) {
1532 ; CHECK-LABEL: @phi_knownnonzero_eq_multiuse_oricmp(
1533 ; CHECK-NEXT: entry:
1534 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1535 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1537 ; CHECK-NEXT: br label [[IF_END]]
1539 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1540 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[PHI]], [[VAL:%.*]]
1541 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ORPHI]], 0
1542 ; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[CLEANUP:%.*]]
1544 ; CHECK-NEXT: [[BOOL2:%.*]] = icmp eq i32 [[PHI]], 0
1545 ; CHECK-NEXT: br label [[CLEANUP]]
1547 ; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1548 ; CHECK-NEXT: ret i1 [[FINAL]]
1551 %tobool = icmp slt i32 %n, %s
1552 br i1 %tobool, label %if.end, label %if.then
1555 %load = load i32, ptr %P
1556 %cmp = icmp eq i32 %n, %load
1557 %sel = select i1 %cmp, i32 1, i32 2
1561 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1562 %orphi = or i32 %phi, %val
1563 %cmp1 = icmp eq i32 %orphi, 0
1564 br i1 %cmp1, label %next, label %cleanup
1567 %bool2 = icmp eq i32 %phi, 0
1571 %final = phi i1 [ %cmp1, %if.end ], [ %bool2, %next ]
1575 define i1 @phi_knownnonzero_ne_multiuse_oricmp_commuted(i32 %n, i32 %s, ptr %P, i32 %val) {
1576 ; CHECK-LABEL: @phi_knownnonzero_ne_multiuse_oricmp_commuted(
1577 ; CHECK-NEXT: entry:
1578 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1579 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1581 ; CHECK-NEXT: br label [[IF_END]]
1583 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1584 ; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[VAL:%.*]], [[PHI]]
1585 ; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[ORPHI]], 0
1586 ; CHECK-NEXT: br i1 [[CMP1_NOT]], label [[CLEANUP:%.*]], label [[NEXT:%.*]]
1588 ; CHECK-NEXT: [[BOOL2:%.*]] = icmp ne i32 [[PHI]], 0
1589 ; CHECK-NEXT: br label [[CLEANUP]]
1591 ; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1592 ; CHECK-NEXT: ret i1 [[FINAL]]
1595 %tobool = icmp slt i32 %n, %s
1596 br i1 %tobool, label %if.end, label %if.then
1599 %load = load i32, ptr %P
1600 %cmp = icmp eq i32 %n, %load
1601 %sel = select i1 %cmp, i32 1, i32 2
1605 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1606 %orphi = or i32 %val, %phi
1607 %cmp1 = icmp ne i32 %orphi, 0
1608 br i1 %cmp1, label %next, label %cleanup
1611 %bool2 = icmp ne i32 %phi, 0
1615 %final = phi i1 [ %cmp1, %if.end ], [ %bool2, %next ]
1619 define i1 @phi_knownnonzero_eq_multiuse_andicmp(i32 %n, i32 %s, ptr %P, i32 %val) {
1620 ; CHECK-LABEL: @phi_knownnonzero_eq_multiuse_andicmp(
1621 ; CHECK-NEXT: entry:
1622 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1623 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1625 ; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[P:%.*]], align 4
1626 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[N]], [[LOAD]]
1627 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 2
1628 ; CHECK-NEXT: br label [[IF_END]]
1630 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SEL]], [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1631 ; CHECK-NEXT: [[ANDPHI:%.*]] = and i32 [[PHI]], [[VAL:%.*]]
1632 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ANDPHI]], 0
1633 ; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[CLEANUP:%.*]]
1635 ; CHECK-NEXT: [[BOOL2:%.*]] = icmp eq i32 [[PHI]], 0
1636 ; CHECK-NEXT: br label [[CLEANUP]]
1638 ; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1639 ; CHECK-NEXT: ret i1 [[FINAL]]
1642 %tobool = icmp slt i32 %n, %s
1643 br i1 %tobool, label %if.end, label %if.then
1646 %load = load i32, ptr %P
1647 %cmp = icmp eq i32 %n, %load
1648 %sel = select i1 %cmp, i32 1, i32 2
1652 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1653 %andphi = and i32 %phi, %val
1654 %cmp1 = icmp eq i32 %andphi, 0
1655 br i1 %cmp1, label %next, label %cleanup
1658 %bool2 = icmp eq i32 %phi, 0
1662 %final = phi i1 [ %cmp1, %if.end ], [ %bool2, %next ]
1666 define i1 @phi_knownnonzero_ne_multiuse_andicmp(i32 %n, i32 %s, ptr %P, i32 %val) {
1667 ; CHECK-LABEL: @phi_knownnonzero_ne_multiuse_andicmp(
1668 ; CHECK-NEXT: entry:
1669 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1670 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1672 ; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[P:%.*]], align 4
1673 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[N]], [[LOAD]]
1674 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 2
1675 ; CHECK-NEXT: br label [[IF_END]]
1677 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SEL]], [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1678 ; CHECK-NEXT: [[ANDPHI:%.*]] = and i32 [[PHI]], [[VAL:%.*]]
1679 ; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[ANDPHI]], 0
1680 ; CHECK-NEXT: br i1 [[CMP1_NOT]], label [[CLEANUP:%.*]], label [[NEXT:%.*]]
1682 ; CHECK-NEXT: [[BOOL2:%.*]] = icmp ne i32 [[PHI]], 0
1683 ; CHECK-NEXT: br label [[CLEANUP]]
1685 ; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1686 ; CHECK-NEXT: ret i1 [[FINAL]]
1689 %tobool = icmp slt i32 %n, %s
1690 br i1 %tobool, label %if.end, label %if.then
1693 %load = load i32, ptr %P
1694 %cmp = icmp eq i32 %n, %load
1695 %sel = select i1 %cmp, i32 1, i32 2
1699 %phi = phi i32 [ %sel, %if.then ], [ %n, %entry ]
1700 %andphi = and i32 %phi, %val
1701 %cmp1 = icmp ne i32 %andphi, 0
1702 br i1 %cmp1, label %next, label %cleanup
1705 %bool2 = icmp ne i32 %phi, 0
1709 %final = phi i1 [ %cmp1, %if.end ], [ %bool2, %next ]
1713 ; This would crash trying to delete an instruction (conv)
1714 ; that still had uses because the user (the phi) was not
1715 ; updated to remove a use from an unreachable block (g.exit).
1717 define void @main(i1 %cond, i16 %x) {
1718 ; CHECK-LABEL: @main(
1719 ; CHECK-NEXT: entry:
1720 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
1722 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]]
1724 ; CHECK-NEXT: unreachable
1726 ; CHECK-NEXT: br label [[FOR_COND]]
1728 ; CHECK-NEXT: store double undef, ptr undef, align 8
1729 ; CHECK-NEXT: ret void
1735 %p = phi double [ %conv, %g.exit ], [ undef, %entry ]
1736 br i1 %cond, label %for.end, label %for.body
1739 %conv = sitofp i16 %x to double
1746 store double %p, ptr undef
1750 define i1 @pr57488_icmp_of_phi(ptr %ptr.base, i64 %len) {
1751 ; CHECK-LABEL: @pr57488_icmp_of_phi(
1752 ; CHECK-NEXT: start:
1753 ; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i64, ptr [[PTR_BASE:%.*]], i64 [[LEN:%.*]]
1754 ; CHECK-NEXT: [[LEN_ZERO:%.*]] = icmp eq i64 [[LEN]], 0
1755 ; CHECK-NEXT: br i1 [[LEN_ZERO]], label [[EXIT:%.*]], label [[LOOP:%.*]]
1757 ; CHECK-NEXT: [[ACCUM:%.*]] = phi i1 [ [[AND:%.*]], [[LOOP]] ], [ true, [[START:%.*]] ]
1758 ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], [[LOOP]] ], [ [[PTR_BASE]], [[START]] ]
1759 ; CHECK-NEXT: [[PTR_NEXT]] = getelementptr inbounds i8, ptr [[PTR]], i64 8
1760 ; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR]], align 8
1761 ; CHECK-NEXT: [[VAL_ZERO:%.*]] = icmp eq i64 [[VAL]], 0
1762 ; CHECK-NEXT: [[AND]] = and i1 [[ACCUM]], [[VAL_ZERO]]
1763 ; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp eq ptr [[PTR_NEXT]], [[END]]
1764 ; CHECK-NEXT: br i1 [[EXIT_COND]], label [[EXIT]], label [[LOOP]]
1766 ; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[START]] ], [ [[AND]], [[LOOP]] ]
1767 ; CHECK-NEXT: ret i1 [[RES]]
1770 %end = getelementptr inbounds i64, ptr %ptr.base, i64 %len
1771 %len.zero = icmp eq i64 %len, 0
1772 br i1 %len.zero, label %exit, label %loop
1775 %accum = phi i8 [ %accum.next, %loop ], [ 1, %start ]
1776 %ptr = phi ptr [ %ptr.next, %loop ], [ %ptr.base, %start ]
1777 %ptr.next = getelementptr inbounds i64, ptr %ptr, i64 1
1778 %accum.bool = icmp ne i8 %accum, 0
1779 %val = load i64, ptr %ptr, align 8
1780 %val.zero = icmp eq i64 %val, 0
1781 %and = and i1 %accum.bool, %val.zero
1782 %accum.next = zext i1 %and to i8
1783 %exit.cond = icmp eq ptr %ptr.next, %end
1784 br i1 %exit.cond, label %exit, label %loop
1787 %res = phi i1 [ true, %start ], [ %and, %loop ]
1791 declare void @use(i32)
1792 declare i1 @get.i1()
1794 define i32 @phi_op_self_simplify() {
1795 ; CHECK-LABEL: @phi_op_self_simplify(
1796 ; CHECK-NEXT: entry:
1797 ; CHECK-NEXT: br label [[LOOP:%.*]]
1799 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_ADD2:%.*]], [[LOOP]] ]
1800 ; CHECK-NEXT: [[IV_ADD:%.*]] = xor i32 [[IV]], -1
1801 ; CHECK-NEXT: call void @use(i32 [[IV_ADD]])
1802 ; CHECK-NEXT: [[IV_ADD2]] = xor i32 [[IV]], -1
1803 ; CHECK-NEXT: br label [[LOOP]]
1809 %iv = phi i32 [ 1, %entry ], [ %iv.add2, %loop ]
1810 %iv.add = xor i32 %iv, -1
1811 call void @use(i32 %iv.add)
1812 %iv.add2 = xor i32 %iv, -1
1816 define i32 @phi_op_self_simplify_2(i32 %x) {
1817 ; CHECK-LABEL: @phi_op_self_simplify_2(
1818 ; CHECK-NEXT: entry:
1819 ; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[X:%.*]], 1
1820 ; CHECK-NEXT: br label [[LOOP:%.*]]
1822 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[PHI]], [[LOOP]] ], [ 11, [[LOOP_LATCH:%.*]] ]
1823 ; CHECK-NEXT: [[C1:%.*]] = call i1 @get.i1()
1824 ; CHECK-NEXT: br i1 [[C1]], label [[LOOP_LATCH]], label [[LOOP]]
1825 ; CHECK: loop.latch:
1826 ; CHECK-NEXT: [[C2:%.*]] = call i1 @get.i1()
1827 ; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[LOOP]]
1829 ; CHECK-NEXT: ret i32 [[PHI]]
1835 %phi = phi i32 [ %x, %entry ], [ %or, %loop ], [ 10, %loop.latch ]
1836 %or = or i32 %phi, 1
1837 %c1 = call i1 @get.i1()
1838 br i1 %c1, label %loop.latch, label %loop
1841 %c2 = call i1 @get.i1()
1842 br i1 %c2, label %exit, label %loop
1848 ; Caused an infinite loop with D134954.
1849 define i64 @inttoptr_of_phi(i1 %c, ptr %arg.ptr, ptr %arg.ptr2) {
1850 ; CHECK-LABEL: @inttoptr_of_phi(
1851 ; CHECK-NEXT: entry:
1852 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1854 ; CHECK-NEXT: [[ARG_PTR2_VAL:%.*]] = load i64, ptr [[ARG_PTR2:%.*]], align 8
1855 ; CHECK-NEXT: [[ARG_PTR2_VAL_PTR:%.*]] = inttoptr i64 [[ARG_PTR2_VAL]] to ptr
1856 ; CHECK-NEXT: br label [[JOIN:%.*]]
1858 ; CHECK-NEXT: br label [[JOIN]]
1860 ; CHECK-NEXT: [[INT_PTR_PTR:%.*]] = phi ptr [ [[ARG_PTR2_VAL_PTR]], [[IF]] ], [ [[ARG_PTR:%.*]], [[ELSE]] ]
1861 ; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[INT_PTR_PTR]], align 8
1862 ; CHECK-NEXT: ret i64 [[V]]
1865 br i1 %c, label %if, label %else
1868 %arg.ptr2.val = load i64, ptr %arg.ptr2, align 8
1872 %arg.int.ptr = ptrtoint ptr %arg.ptr to i64
1876 %int.ptr = phi i64 [ %arg.ptr2.val, %if ], [ %arg.int.ptr, %else ]
1877 %ptr = inttoptr i64 %int.ptr to ptr
1878 %v = load i64, ptr %ptr, align 8
1882 define void @simplify_context_instr(ptr %ptr.base, i64 %n) {
1883 ; CHECK-LABEL: @simplify_context_instr(
1884 ; CHECK-NEXT: entry:
1885 ; CHECK-NEXT: [[PTR_END:%.*]] = getelementptr inbounds i8, ptr [[PTR_BASE:%.*]], i64 [[N:%.*]]
1886 ; CHECK-NEXT: br label [[LOOP:%.*]]
1888 ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], [[LATCH:%.*]] ], [ [[PTR_BASE]], [[ENTRY:%.*]] ]
1889 ; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ [[CMP:%.*]], [[LATCH]] ], [ true, [[ENTRY]] ]
1890 ; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[PTR]], align 1
1891 ; CHECK-NEXT: [[CMP]] = icmp eq i8 [[V]], 95
1892 ; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[IF:%.*]]
1894 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[PHI]], i32 117, i32 100
1895 ; CHECK-NEXT: call void @use(i32 [[SEL]])
1896 ; CHECK-NEXT: br label [[LATCH]]
1898 ; CHECK-NEXT: [[PTR_NEXT]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
1899 ; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq ptr [[PTR_NEXT]], [[PTR_END]]
1900 ; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT:%.*]], label [[LOOP]]
1902 ; CHECK-NEXT: ret void
1905 %ptr.end = getelementptr inbounds i8, ptr %ptr.base, i64 %n
1909 %ptr = phi ptr [ %ptr.next, %latch ], [ %ptr.base, %entry ]
1910 %phi = phi i1 [ %cmp, %latch ], [ true, %entry ]
1911 %v = load i8, ptr %ptr, align 1
1912 %cmp = icmp eq i8 %v, 95
1913 br i1 %cmp, label %latch, label %if
1916 %sel = select i1 %phi, i32 117, i32 100
1917 call void @use(i32 %sel)
1921 %ptr.next = getelementptr inbounds i8, ptr %ptr, i64 1
1922 %cmp.i.not = icmp eq ptr %ptr.next, %ptr.end
1923 br i1 %cmp.i.not, label %exit, label %loop
1929 define i32 @add_two_phi_node_can_fold(i1 %c, i32 %i, i32 %j) {
1930 ; CHECK-LABEL: @add_two_phi_node_can_fold(
1931 ; CHECK-NEXT: entry:
1932 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1934 ; CHECK-NEXT: br label [[IF_END]]
1936 ; CHECK-NEXT: [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
1937 ; CHECK-NEXT: ret i32 [[ADD]]
1940 br i1 %c, label %if.then, label %if.end
1946 %x = phi i32 [ 0, %if.then ], [ %j, %entry ]
1947 %y = phi i32 [ %i, %if.then ], [ 0, %entry ]
1948 %add = add i32 %y, %x
1952 define i32 @add_two_phi_node_cannt_fold(i1 %c, i32 %i, i32 %j) {
1953 ; CHECK-LABEL: @add_two_phi_node_cannt_fold(
1954 ; CHECK-NEXT: entry:
1955 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1957 ; CHECK-NEXT: br label [[IF_END]]
1959 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
1960 ; CHECK-NEXT: [[Y:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ 1, [[ENTRY]] ]
1961 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[Y]], [[X]]
1962 ; CHECK-NEXT: ret i32 [[ADD]]
1965 br i1 %c, label %if.then, label %if.end
1971 %x = phi i32 [ 0, %if.then ], [ %j, %entry ]
1972 %y = phi i32 [ %i, %if.then ], [ 1, %entry ]
1973 %add = add i32 %y, %x
1977 define i32 @or_two_phi_node_can_fold(i1 %c, i32 %i, i32 %j) {
1978 ; CHECK-LABEL: @or_two_phi_node_can_fold(
1979 ; CHECK-NEXT: entry:
1980 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1982 ; CHECK-NEXT: br label [[IF_END]]
1984 ; CHECK-NEXT: [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
1985 ; CHECK-NEXT: ret i32 [[ADD]]
1988 br i1 %c, label %if.then, label %if.end
1994 %x = phi i32 [ 0, %if.then ], [ %j, %entry ]
1995 %y = phi i32 [ %i, %if.then ], [ 0, %entry ]
1996 %add = or i32 %y, %x
2000 define i32 @and_two_phi_node_can_fold(i1 %c, i32 %i, i32 %j) {
2001 ; CHECK-LABEL: @and_two_phi_node_can_fold(
2002 ; CHECK-NEXT: entry:
2003 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
2005 ; CHECK-NEXT: br label [[IF_END]]
2007 ; CHECK-NEXT: [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2008 ; CHECK-NEXT: ret i32 [[ADD]]
2011 br i1 %c, label %if.then, label %if.end
2017 %x = phi i32 [ -1, %if.then ], [ %j, %entry ]
2018 %y = phi i32 [ %i, %if.then ], [ -1, %entry ]
2019 %add = and i32 %y, %x
2023 define i32 @mul_two_phi_node_can_fold(i1 %c, i32 %i, i32 %j) {
2024 ; CHECK-LABEL: @mul_two_phi_node_can_fold(
2025 ; CHECK-NEXT: entry:
2026 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
2028 ; CHECK-NEXT: br label [[IF_END]]
2030 ; CHECK-NEXT: [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2031 ; CHECK-NEXT: ret i32 [[ADD]]
2034 br i1 %c, label %if.then, label %if.end
2040 %x = phi i32 [ 1, %if.then ], [ %j, %entry ]
2041 %y = phi i32 [ %i, %if.then ], [ 1, %entry ]
2042 %add = mul i32 %y, %x
2046 define i32 @xor_two_phi_node_can_fold(i1 %c, i32 %i, i32 %j) {
2047 ; CHECK-LABEL: @xor_two_phi_node_can_fold(
2048 ; CHECK-NEXT: entry:
2049 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
2051 ; CHECK-NEXT: br label [[IF_END]]
2053 ; CHECK-NEXT: [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2054 ; CHECK-NEXT: ret i32 [[ADD]]
2057 br i1 %c, label %if.then, label %if.end
2063 %x = phi i32 [ 0, %if.then ], [ %j, %entry ]
2064 %y = phi i32 [ %i, %if.then ], [ 0, %entry ]
2065 %add = xor i32 %y, %x
2069 define i32 @sub_two_phi_node_cant_fold(i1 %c, i32 %i, i32 %j) {
2070 ; CHECK-LABEL: @sub_two_phi_node_cant_fold(
2071 ; CHECK-NEXT: entry:
2072 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
2074 ; CHECK-NEXT: br label [[IF_END]]
2076 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2077 ; CHECK-NEXT: [[Y:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ 0, [[ENTRY]] ]
2078 ; CHECK-NEXT: [[ADD:%.*]] = sub i32 [[Y]], [[X]]
2079 ; CHECK-NEXT: ret i32 [[ADD]]
2082 br i1 %c, label %if.then, label %if.end
2088 %x = phi i32 [ 0, %if.then ], [ %j, %entry ]
2089 %y = phi i32 [ %i, %if.then ], [ 0, %entry ]
2090 %add = sub i32 %y, %x
2094 define i1 @cmp_eq_phi_node_can_fold_1(ptr %C) {
2095 ; CHECK-LABEL: @cmp_eq_phi_node_can_fold_1(
2096 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2097 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2098 ; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2099 ; CHECK: sub_is_zero:
2100 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2101 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2102 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 0
2103 ; CHECK-NEXT: br label [[JOIN]]
2105 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
2106 ; CHECK-NEXT: ret i1 [[CMP]]
2108 %1 = load i8, ptr %C, align 1
2109 %2 = zext i8 %1 to i32
2110 %3 = sub nsw i32 %2, 48
2111 %4 = icmp eq i32 %3, 0
2112 br i1 %4, label %sub_is_zero, label %join
2115 %5 = getelementptr inbounds i8, ptr %C, i64 1
2116 %6 = load i8, ptr %5, align 1
2117 %7 = zext i8 %6 to i32
2121 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2122 %cmp = icmp eq i32 %8, 0
2126 define i1 @cmp_eq_phi_node_can_fold_2(ptr %C) {
2127 ; CHECK-LABEL: @cmp_eq_phi_node_can_fold_2(
2128 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2129 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2130 ; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2131 ; CHECK: sub_is_zero:
2132 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2133 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2134 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
2135 ; CHECK-NEXT: br i1 [[TMP5]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
2136 ; CHECK: sub_is_zero1:
2137 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2138 ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
2139 ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i8 [[TMP7]], 0
2140 ; CHECK-NEXT: br label [[JOIN]]
2142 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ false, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
2143 ; CHECK-NEXT: ret i1 [[CMP]]
2145 %1 = load i8, ptr %C, align 1
2146 %2 = zext i8 %1 to i32
2147 %3 = sub nsw i32 %2, 48
2148 %4 = icmp eq i32 %3, 0
2149 br i1 %4, label %sub_is_zero, label %join
2152 %5 = getelementptr inbounds i8, ptr %C, i64 1
2153 %6 = load i8, ptr %5, align 1
2154 %7 = zext i8 %6 to i32
2155 %8 = sub nsw i32 %7, 49
2156 %9 = icmp eq i32 %8, 0
2157 br i1 %9, label %sub_is_zero1, label %join
2160 %10 = getelementptr inbounds i8, ptr %C, i64 2
2161 %11 = load i8, ptr %10, align 1
2162 %12 = zext i8 %11 to i32
2166 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2167 %cmp = icmp eq i32 %13, 0
2171 define i1 @cmp_eq_phi_node_can_fold_3(ptr %C) {
2172 ; CHECK-LABEL: @cmp_eq_phi_node_can_fold_3(
2173 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2174 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2175 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2176 ; CHECK: sub_is_zero:
2177 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2178 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2179 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 0
2180 ; CHECK-NEXT: br label [[JOIN]]
2182 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
2183 ; CHECK-NEXT: ret i1 [[CMP]]
2185 %1 = load i8, ptr %C, align 1
2186 %2 = zext i8 %1 to i32
2187 %3 = sub nsw i32 %2, 48
2188 %4 = icmp eq i32 %3, 0
2189 br i1 %4, label %join, label %sub_is_zero
2192 %5 = getelementptr inbounds i8, ptr %C, i64 1
2193 %6 = load i8, ptr %5, align 1
2194 %7 = zext i8 %6 to i32
2198 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2199 %cmp = icmp eq i32 %8, 0
2204 define i1 @cmp_eq_phi_node_can_fold_4(ptr %C) {
2205 ; CHECK-LABEL: @cmp_eq_phi_node_can_fold_4(
2206 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2207 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2208 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2209 ; CHECK: sub_is_zero:
2210 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2211 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2212 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
2213 ; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
2214 ; CHECK: sub_is_zero1:
2215 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2216 ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
2217 ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i8 [[TMP7]], 0
2218 ; CHECK-NEXT: br label [[JOIN]]
2220 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ true, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
2221 ; CHECK-NEXT: ret i1 [[CMP]]
2223 %1 = load i8, ptr %C, align 1
2224 %2 = zext i8 %1 to i32
2225 %3 = sub nsw i32 %2, 48
2226 %4 = icmp eq i32 %3, 0
2227 br i1 %4, label %join, label %sub_is_zero
2230 %5 = getelementptr inbounds i8, ptr %C, i64 1
2231 %6 = load i8, ptr %5, align 1
2232 %7 = zext i8 %6 to i32
2233 %8 = sub nsw i32 %7, 49
2234 %9 = icmp eq i32 %8, 0
2235 br i1 %9, label %join, label %sub_is_zero1
2238 %10 = getelementptr inbounds i8, ptr %C, i64 2
2239 %11 = load i8, ptr %10, align 1
2240 %12 = zext i8 %11 to i32
2244 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2245 %cmp = icmp eq i32 %13, 0
2249 define i1 @cmp_ne_phi_node_can_fold_1(ptr %C) {
2250 ; CHECK-LABEL: @cmp_ne_phi_node_can_fold_1(
2251 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2252 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2253 ; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2254 ; CHECK: sub_is_zero:
2255 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2256 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2257 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
2258 ; CHECK-NEXT: br label [[JOIN]]
2260 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
2261 ; CHECK-NEXT: ret i1 [[CMP]]
2263 %1 = load i8, ptr %C, align 1
2264 %2 = zext i8 %1 to i32
2265 %3 = sub nsw i32 %2, 48
2266 %4 = icmp eq i32 %3, 0
2267 br i1 %4, label %sub_is_zero, label %join
2270 %5 = getelementptr inbounds i8, ptr %C, i64 1
2271 %6 = load i8, ptr %5, align 1
2272 %7 = zext i8 %6 to i32
2276 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2277 %cmp = icmp ne i32 %8, 0
2281 define i1 @cmp_ne_phi_node_can_fold_2(ptr %C) {
2282 ; CHECK-LABEL: @cmp_ne_phi_node_can_fold_2(
2283 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2284 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2285 ; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2286 ; CHECK: sub_is_zero:
2287 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2288 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2289 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
2290 ; CHECK-NEXT: br i1 [[TMP5]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
2291 ; CHECK: sub_is_zero1:
2292 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2293 ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
2294 ; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP7]], 0
2295 ; CHECK-NEXT: br label [[JOIN]]
2297 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ true, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
2298 ; CHECK-NEXT: ret i1 [[CMP]]
2300 %1 = load i8, ptr %C, align 1
2301 %2 = zext i8 %1 to i32
2302 %3 = sub nsw i32 %2, 48
2303 %4 = icmp eq i32 %3, 0
2304 br i1 %4, label %sub_is_zero, label %join
2306 sub_is_zero: ; preds = %0
2307 %5 = getelementptr inbounds i8, ptr %C, i64 1
2308 %6 = load i8, ptr %5, align 1
2309 %7 = zext i8 %6 to i32
2310 %8 = sub nsw i32 %7, 49
2311 %9 = icmp eq i32 %8, 0
2312 br i1 %9, label %sub_is_zero1, label %join
2315 %10 = getelementptr inbounds i8, ptr %C, i64 2
2316 %11 = load i8, ptr %10, align 1
2317 %12 = zext i8 %11 to i32
2321 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2322 %cmp = icmp ne i32 %13, 0
2326 define i1 @cmp_ne_phi_node_can_fold_3(ptr %C) {
2327 ; CHECK-LABEL: @cmp_ne_phi_node_can_fold_3(
2328 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2329 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2330 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2331 ; CHECK: sub_is_zero:
2332 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2333 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2334 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
2335 ; CHECK-NEXT: br label [[JOIN]]
2337 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
2338 ; CHECK-NEXT: ret i1 [[CMP]]
2340 %1 = load i8, ptr %C, align 1
2341 %2 = zext i8 %1 to i32
2342 %3 = sub nsw i32 %2, 48
2343 %4 = icmp eq i32 %3, 0
2344 br i1 %4, label %join, label %sub_is_zero
2347 %5 = getelementptr inbounds i8, ptr %C, i64 1
2348 %6 = load i8, ptr %5, align 1
2349 %7 = zext i8 %6 to i32
2353 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2354 %cmp = icmp ne i32 %8, 0
2358 define i1 @cmp_ne_phi_node_can_fold_4(ptr %C) {
2359 ; CHECK-LABEL: @cmp_ne_phi_node_can_fold_4(
2360 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2361 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2362 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2363 ; CHECK: sub_is_zero:
2364 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2365 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2366 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
2367 ; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
2368 ; CHECK: sub_is_zero1:
2369 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2370 ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
2371 ; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP7]], 0
2372 ; CHECK-NEXT: br label [[JOIN]]
2374 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ false, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
2375 ; CHECK-NEXT: ret i1 [[CMP]]
2377 %1 = load i8, ptr %C, align 1
2378 %2 = zext i8 %1 to i32
2379 %3 = sub nsw i32 %2, 48
2380 %4 = icmp eq i32 %3, 0
2381 br i1 %4, label %join, label %sub_is_zero
2383 sub_is_zero: ; preds = %0
2384 %5 = getelementptr inbounds i8, ptr %C, i64 1
2385 %6 = load i8, ptr %5, align 1
2386 %7 = zext i8 %6 to i32
2387 %8 = sub nsw i32 %7, 49
2388 %9 = icmp eq i32 %8, 0
2389 br i1 %9, label %join, label %sub_is_zero1
2392 %10 = getelementptr inbounds i8, ptr %C, i64 2
2393 %11 = load i8, ptr %10, align 1
2394 %12 = zext i8 %11 to i32
2398 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2399 %cmp = icmp ne i32 %13, 0
2403 define i1 @cmp_sgt_phi_node_can_fold_1(ptr %C) {
2404 ; CHECK-LABEL: @cmp_sgt_phi_node_can_fold_1(
2405 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2406 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2407 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2408 ; CHECK: sub_is_zero:
2409 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2410 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2411 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
2412 ; CHECK-NEXT: br label [[JOIN]]
2414 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
2415 ; CHECK-NEXT: ret i1 [[CMP]]
2417 %1 = load i8, ptr %C, align 1
2418 %2 = zext i8 %1 to i32
2419 %3 = sub nsw i32 %2, 48
2420 %4 = icmp eq i32 %3, 0
2421 br i1 %4, label %join, label %sub_is_zero
2424 %5 = getelementptr inbounds i8, ptr %C, i64 1
2425 %6 = load i8, ptr %5, align 1
2426 %7 = zext i8 %6 to i32
2430 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2431 %cmp = icmp sgt i32 %8, 0
2435 define i1 @cmp_sgt_phi_node_can_fold_2(ptr %C) {
2436 ; CHECK-LABEL: @cmp_sgt_phi_node_can_fold_2(
2437 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2438 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2439 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2440 ; CHECK: sub_is_zero:
2441 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2442 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2443 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
2444 ; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
2445 ; CHECK: sub_is_zero1:
2446 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2447 ; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
2448 ; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP7]], 0
2449 ; CHECK-NEXT: br label [[JOIN]]
2451 ; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ false, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
2452 ; CHECK-NEXT: ret i1 [[CMP]]
2454 %1 = load i8, ptr %C, align 1
2455 %2 = zext i8 %1 to i32
2456 %3 = sub nsw i32 %2, 48
2457 %4 = icmp eq i32 %3, 0
2458 br i1 %4, label %join, label %sub_is_zero
2461 %5 = getelementptr inbounds i8, ptr %C, i64 1
2462 %6 = load i8, ptr %5, align 1
2463 %7 = zext i8 %6 to i32
2464 %8 = sub nsw i32 %7, 49
2465 %9 = icmp eq i32 %8, 0
2466 br i1 %9, label %join, label %sub_is_zero1
2469 %10 = getelementptr inbounds i8, ptr %C, i64 2
2470 %11 = load i8, ptr %10, align 1
2471 %12 = zext i8 %11 to i32
2475 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2476 %cmp = icmp sgt i32 %13, 0
2480 define i1 @cmp_sgt_phi_node_cant_fold_1(ptr %C) {
2481 ; CHECK-LABEL: @cmp_sgt_phi_node_cant_fold_1(
2482 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2483 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
2484 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
2485 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
2486 ; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2487 ; CHECK: sub_is_zero:
2488 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2489 ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
2490 ; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
2491 ; CHECK-NEXT: br label [[JOIN]]
2493 ; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
2494 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 0
2495 ; CHECK-NEXT: ret i1 [[CMP]]
2497 %1 = load i8, ptr %C, align 1
2498 %2 = zext i8 %1 to i32
2499 %3 = sub nsw i32 %2, 48
2500 %4 = icmp eq i32 %3, 0
2501 br i1 %4, label %sub_is_zero, label %join
2504 %5 = getelementptr inbounds i8, ptr %C, i64 1
2505 %6 = load i8, ptr %5, align 1
2506 %7 = zext i8 %6 to i32
2510 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2511 %cmp = icmp sgt i32 %8, 0
2515 define i1 @cmp_sgt_phi_node_cant_fold_2(ptr %C) {
2516 ; CHECK-LABEL: @cmp_sgt_phi_node_cant_fold_2(
2517 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2518 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
2519 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
2520 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
2521 ; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2522 ; CHECK: sub_is_zero:
2523 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2524 ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
2525 ; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
2526 ; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
2527 ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
2528 ; CHECK-NEXT: br i1 [[TMP9]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
2529 ; CHECK: sub_is_zero1:
2530 ; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2531 ; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
2532 ; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
2533 ; CHECK-NEXT: br label [[JOIN]]
2535 ; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
2536 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP13]], 0
2537 ; CHECK-NEXT: ret i1 [[CMP]]
2539 %1 = load i8, ptr %C, align 1
2540 %2 = zext i8 %1 to i32
2541 %3 = sub nsw i32 %2, 48
2542 %4 = icmp eq i32 %3, 0
2543 br i1 %4, label %sub_is_zero, label %join
2546 %5 = getelementptr inbounds i8, ptr %C, i64 1
2547 %6 = load i8, ptr %5, align 1
2548 %7 = zext i8 %6 to i32
2549 %8 = sub nsw i32 %7, 49
2550 %9 = icmp eq i32 %8, 0
2551 br i1 %9, label %sub_is_zero1, label %join
2554 %10 = getelementptr inbounds i8, ptr %C, i64 2
2555 %11 = load i8, ptr %10, align 1
2556 %12 = zext i8 %11 to i32
2560 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2561 %cmp = icmp sgt i32 %13, 0
2565 define i1 @cmp_slt_phi_node_can_fold_1(ptr %C) {
2566 ; CHECK-LABEL: @cmp_slt_phi_node_can_fold_1(
2567 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2568 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2569 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2570 ; CHECK: sub_is_zero:
2571 ; CHECK-NEXT: br label [[JOIN]]
2573 ; CHECK-NEXT: ret i1 false
2575 %1 = load i8, ptr %C, align 1
2576 %2 = zext i8 %1 to i32
2577 %3 = sub nsw i32 %2, 48
2578 %4 = icmp eq i32 %3, 0
2579 br i1 %4, label %join, label %sub_is_zero
2582 %5 = getelementptr inbounds i8, ptr %C, i64 1
2583 %6 = load i8, ptr %5, align 1
2584 %7 = zext i8 %6 to i32
2588 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2589 %cmp = icmp slt i32 %8, 0
2593 define i1 @cmp_slt_phi_node_can_fold_2(ptr %C) {
2594 ; CHECK-LABEL: @cmp_slt_phi_node_can_fold_2(
2595 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2596 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
2597 ; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
2598 ; CHECK: sub_is_zero:
2599 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2600 ; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
2601 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
2602 ; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
2603 ; CHECK: sub_is_zero1:
2604 ; CHECK-NEXT: br label [[JOIN]]
2606 ; CHECK-NEXT: ret i1 false
2608 %1 = load i8, ptr %C, align 1
2609 %2 = zext i8 %1 to i32
2610 %3 = sub nsw i32 %2, 48
2611 %4 = icmp eq i32 %3, 0
2612 br i1 %4, label %join, label %sub_is_zero
2615 %5 = getelementptr inbounds i8, ptr %C, i64 1
2616 %6 = load i8, ptr %5, align 1
2617 %7 = zext i8 %6 to i32
2618 %8 = sub nsw i32 %7, 49
2619 %9 = icmp eq i32 %8, 0
2620 br i1 %9, label %join, label %sub_is_zero1
2623 %10 = getelementptr inbounds i8, ptr %C, i64 2
2624 %11 = load i8, ptr %10, align 1
2625 %12 = zext i8 %11 to i32
2629 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2630 %cmp = icmp slt i32 %13, 0
2634 define i1 @cmp_slt_phi_node_cant_fold_1(ptr %C) {
2635 ; CHECK-LABEL: @cmp_slt_phi_node_cant_fold_1(
2636 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2637 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
2638 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
2639 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
2640 ; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2641 ; CHECK: sub_is_zero:
2642 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2643 ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
2644 ; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
2645 ; CHECK-NEXT: br label [[JOIN]]
2647 ; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
2648 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP8]], 0
2649 ; CHECK-NEXT: ret i1 [[CMP]]
2651 %1 = load i8, ptr %C, align 1
2652 %2 = zext i8 %1 to i32
2653 %3 = sub nsw i32 %2, 48
2654 %4 = icmp eq i32 %3, 0
2655 br i1 %4, label %sub_is_zero, label %join
2658 %5 = getelementptr inbounds i8, ptr %C, i64 1
2659 %6 = load i8, ptr %5, align 1
2660 %7 = zext i8 %6 to i32
2664 %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2665 %cmp = icmp slt i32 %8, 0
2669 define i1 @cmp_slt_phi_node_cant_fold_2(ptr %C) {
2670 ; CHECK-LABEL: @cmp_slt_phi_node_cant_fold_2(
2671 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
2672 ; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
2673 ; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
2674 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
2675 ; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
2676 ; CHECK: sub_is_zero:
2677 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
2678 ; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
2679 ; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
2680 ; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
2681 ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
2682 ; CHECK-NEXT: br i1 [[TMP9]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
2683 ; CHECK: sub_is_zero1:
2684 ; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
2685 ; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
2686 ; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
2687 ; CHECK-NEXT: br label [[JOIN]]
2689 ; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
2690 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP13]], 0
2691 ; CHECK-NEXT: ret i1 [[CMP]]
2693 %1 = load i8, ptr %C, align 1
2694 %2 = zext i8 %1 to i32
2695 %3 = sub nsw i32 %2, 48
2696 %4 = icmp eq i32 %3, 0
2697 br i1 %4, label %sub_is_zero, label %join
2700 %5 = getelementptr inbounds i8, ptr %C, i64 1
2701 %6 = load i8, ptr %5, align 1
2702 %7 = zext i8 %6 to i32
2703 %8 = sub nsw i32 %7, 49
2704 %9 = icmp eq i32 %8, 0
2705 br i1 %9, label %sub_is_zero1, label %join
2708 %10 = getelementptr inbounds i8, ptr %C, i64 2
2709 %11 = load i8, ptr %10, align 1
2710 %12 = zext i8 %11 to i32
2714 %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2715 %cmp = icmp slt i32 %13, 0
2719 define void @phi_op_in_loop(i1 %c, i32 %x) {
2720 ; CHECK-LABEL: @phi_op_in_loop(
2721 ; CHECK-NEXT: br label [[LOOP:%.*]]
2723 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]
2725 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1
2726 ; CHECK-NEXT: br label [[LOOP_LATCH]]
2727 ; CHECK: loop.latch:
2728 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TMP1]], [[IF]] ], [ 0, [[LOOP]] ]
2729 ; CHECK-NEXT: call void @use(i32 [[PHI]])
2730 ; CHECK-NEXT: br label [[LOOP]]
2735 br i1 %c, label %if, label %loop.latch
2738 br label %loop.latch
2741 %phi = phi i32 [ %x, %if ], [ 0, %loop ]
2742 %and = and i32 %phi, 1
2743 call void @use(i32 %and)
2747 define void @test_dead_phi_web(i64 %index, i1 %cond) {
2748 ; CHECK-LABEL: @test_dead_phi_web(
2749 ; CHECK-NEXT: entry:
2750 ; CHECK-NEXT: br label [[BB0:%.*]]
2752 ; CHECK-NEXT: switch i64 [[INDEX:%.*]], label [[BB4:%.*]] [
2753 ; CHECK-NEXT: i64 0, label [[BB1:%.*]]
2754 ; CHECK-NEXT: i64 1, label [[BB2:%.*]]
2755 ; CHECK-NEXT: i64 2, label [[BB3:%.*]]
2758 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB2]], label [[BB4]]
2760 ; CHECK-NEXT: br i1 [[COND]], label [[BB3]], label [[BB4]]
2762 ; CHECK-NEXT: br label [[BB4]]
2764 ; CHECK-NEXT: br i1 [[COND]], label [[BB0]], label [[BB5:%.*]]
2766 ; CHECK-NEXT: ret void
2771 BB0: ; preds = %BB4, %entry
2772 %a = phi float [ 0.0, %entry ], [ %x, %BB4 ]
2773 switch i64 %index, label %BB4 [
2780 br i1 %cond, label %BB2, label %BB4
2782 BB2: ; preds = %BB1, %BB0
2783 %b = phi float [ 2.0, %BB0 ], [ %a, %BB1 ]
2784 br i1 %cond, label %BB3, label %BB4
2786 BB3: ; preds = %BB2, %BB0
2787 %c = phi float [ 3.0, %BB0 ], [ %b, %BB2 ]
2790 BB4: ; preds = %BB3, %BB2, %BB1, %BB0
2791 %x = phi float [ %a, %BB0 ], [ %a, %BB1 ], [ %b, %BB2 ], [ %c, %BB3 ]
2792 br i1 %cond, label %BB0, label %BB5
2798 define i64 @wrong_gep_arg_into_phi(ptr noundef %ptr) {
2799 ; CHECK-LABEL: @wrong_gep_arg_into_phi(
2800 ; CHECK-NEXT: entry:
2801 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
2803 ; CHECK-NEXT: [[PTR_PN:%.*]] = phi ptr [ [[PTR:%.*]], [[ENTRY:%.*]] ], [ [[DOTPN:%.*]], [[FOR_COND]] ]
2804 ; CHECK-NEXT: [[DOTPN]] = getelementptr i8, ptr [[PTR_PN]], i64 1
2805 ; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[DOTPN]], align 1
2806 ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp eq i8 [[VAL]], 0
2807 ; CHECK-NEXT: br i1 [[COND_NOT]], label [[EXIT:%.*]], label [[FOR_COND]]
2809 ; CHECK-NEXT: ret i64 0
2812 %add.ptr = getelementptr i8, ptr %ptr, i64 1
2815 for.cond: ; preds = %for.cond, %entry
2816 %.pn = phi ptr [ %add.ptr, %entry ], [ %incdec.ptr, %for.cond ]
2817 %val = load i8, ptr %.pn, align 1
2818 %cond = icmp ne i8 %val, 0
2819 %incdec.ptr = getelementptr inbounds nuw i8, ptr %.pn, i64 1
2820 br i1 %cond, label %for.cond, label %exit
2822 exit: ; preds = %for.cond