[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / phi.ll
blobc3548590d7f57a191f11fb7fa9aad4c5c2e4aebd
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) {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:  BB0:
9 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
10 ; CHECK:       BB1:
11 ; CHECK-NEXT:    ret i32 [[A:%.*]]
12 ; CHECK:       BB2:
13 ; CHECK-NEXT:    ret i32 [[A]]
15 BB0:
16   br i1 %b, label %BB1, label %BB2
18 BB1:
19   ; Combine away one argument PHI nodes
20   %B = phi i32 [ %A, %BB0 ]
21   ret i32 %B
23 BB2:
24   ret i32 %A
27 define i32 @test2(i32 %A, i1 %b) {
28 ; CHECK-LABEL: @test2(
29 ; CHECK-NEXT:  BB0:
30 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
31 ; CHECK:       BB1:
32 ; CHECK-NEXT:    br label [[BB2]]
33 ; CHECK:       BB2:
34 ; CHECK-NEXT:    ret i32 [[A:%.*]]
36 BB0:
37   br i1 %b, label %BB1, label %BB2
39 BB1:
40   br label %BB2
42 BB2:
43   ; Combine away PHI nodes with same values
44   %B = phi i32 [ %A, %BB0 ], [ %A, %BB1 ]
45   ret i32 %B
48 define i32 @test3(i32 %A, i1 %b) {
49 ; CHECK-LABEL: @test3(
50 ; CHECK-NEXT:  BB0:
51 ; CHECK-NEXT:    br label [[LOOP:%.*]]
52 ; CHECK:       Loop:
53 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]]
54 ; CHECK:       Exit:
55 ; CHECK-NEXT:    ret i32 [[A:%.*]]
57 BB0:
58   br label %Loop
60 Loop:
61   ; PHI has same value always.
62   %B = phi i32 [ %A, %BB0 ], [ %B, %Loop ]
63   br i1 %b, label %Loop, label %Exit
65 Exit:
66   ret i32 %B
69 define i32 @test4(i1 %b) {
70 ; CHECK-LABEL: @test4(
71 ; CHECK-NEXT:  BB0:
72 ; CHECK-NEXT:    ret i32 7
73 ; CHECK:       Loop:
74 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[L2:%.*]], label [[LOOP:%.*]]
75 ; CHECK:       L2:
76 ; CHECK-NEXT:    br label [[LOOP]]
78 BB0:
79   ; Loop is unreachable
80   ret i32 7
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
87 L2:             ; preds = %Loop
88   br label %Loop
91 define i32 @test5_undef(i32 %A, i1 %cond) {
92 ; CHECK-LABEL: @test5_undef(
93 ; CHECK-NEXT:  BB0:
94 ; CHECK-NEXT:    br label [[LOOP:%.*]]
95 ; CHECK:       Loop:
96 ; CHECK-NEXT:    [[B:%.*]] = phi i32 [ [[A:%.*]], [[BB0:%.*]] ], [ undef, [[LOOP]] ]
97 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
98 ; CHECK:       Exit:
99 ; CHECK-NEXT:    ret i32 [[B]]
101 BB0:
102   br label %Loop
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
110   ret i32 %B
113 define i32 @test5_poison(i32 %A, i1 %cond) {
114 ; CHECK-LABEL: @test5_poison(
115 ; CHECK-NEXT:  BB0:
116 ; CHECK-NEXT:    br label [[LOOP:%.*]]
117 ; CHECK:       Loop:
118 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
119 ; CHECK:       Exit:
120 ; CHECK-NEXT:    ret i32 [[A:%.*]]
122 BB0:
123   br label %Loop
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
131   ret i32 %B
134 define i32 @test6(i16 %A, i1 %b) {
135 ; CHECK-LABEL: @test6(
136 ; CHECK-NEXT:  BB0:
137 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
138 ; CHECK:       BB1:
139 ; CHECK-NEXT:    br label [[BB2]]
140 ; CHECK:       BB2:
141 ; CHECK-NEXT:    [[C:%.*]] = zext i16 [[A:%.*]] to i32
142 ; CHECK-NEXT:    ret i32 [[C]]
144 BB0:
145   %X = zext i16 %A to i32
146   br i1 %b, label %BB1, label %BB2
148 BB1:
149   %Y = zext i16 %A to i32
150   br label %BB2
152 BB2:
153   ;; Suck casts into phi
154   %c = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
155   ret i32 %c
158 define i32 @test_dead_cycle(i32 %A, i1 %cond) {
159 ; CHECK-LABEL: @test_dead_cycle(
160 ; CHECK-NEXT:  BB0:
161 ; CHECK-NEXT:    br label [[LOOP:%.*]]
162 ; CHECK:       Loop:
163 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
164 ; CHECK:       Exit:
165 ; CHECK-NEXT:    ret i32 0
167 BB0:
168   br label %Loop
170 Loop:           ; preds = %Loop, %BB0
171   %B = phi i32 [ %A, %BB0 ], [ %C, %Loop ]
172   %C = add i32 %B, 123
173   br i1 %cond, label %Loop, label %Exit
175 Exit:           ; preds = %Loop
176   ret i32 0
179 define i32 @test_dead_UnaryOp_cycle(double %A, i1 %cond) {
180 ; CHECK-LABEL: @test_dead_UnaryOp_cycle(
181 ; CHECK-NEXT:  BB0:
182 ; CHECK-NEXT:    br label [[LOOP:%.*]]
183 ; CHECK:       Loop:
184 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP]], label [[EXIT:%.*]]
185 ; CHECK:       Exit:
186 ; CHECK-NEXT:    ret i32 0
188 BB0:
189   br label %Loop
191 Loop:           ; preds = %Loop, %BB0
192   %B = phi double [ %A, %BB0 ], [ %C, %Loop ]
193   %C = fneg double %B
194   br i1 %cond, label %Loop, label %Exit
196 Exit:           ; preds = %Loop
197   ret i32 0
200 define i32 @test_dead_cycle_two_insts(i32 %A, i1 %cond) {
201 ; CHECK-LABEL: @test_dead_cycle_two_insts(
202 ; CHECK-NEXT:  BB0:
203 ; CHECK-NEXT:    br label [[LOOP:%.*]]
204 ; CHECK:       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:%.*]]
209 ; CHECK:       Exit:
210 ; CHECK-NEXT:    ret i32 0
212 BB0:
213   br label %Loop
215 Loop:           ; preds = %Loop, %BB0
216   %B = phi i32 [ %A, %BB0 ], [ %D, %Loop ]
217   %C = add i32 %B, 123
218   %D = lshr i32 %C, 1
219   br i1 %cond, label %Loop, label %Exit
221 Exit:           ; preds = %Loop
222   ret i32 0
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(
229 ; CHECK-NEXT:  BB0:
230 ; CHECK-NEXT:    br label [[LOOP:%.*]]
231 ; CHECK:       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:%.*]]
235 ; CHECK:       Exit:
236 ; CHECK-NEXT:    ret i32 0
238 BB0:
239   br label %Loop
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
247   ret i32 0
250 define ptr @test8(ptr %A, i1 %b) {
251 ; CHECK-LABEL: @test8(
252 ; CHECK-NEXT:  BB0:
253 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
254 ; CHECK:       BB1:
255 ; CHECK-NEXT:    br label [[BB2]]
256 ; CHECK:       BB2:
257 ; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4
258 ; CHECK-NEXT:    ret ptr [[C]]
260 BB0:
261   %X = getelementptr inbounds { i32, i32 }, ptr %A, i32 0, i32 1
262   br i1 %b, label %BB1, label %BB2
264 BB1:
265   %Y = getelementptr { i32, i32 }, ptr %A, i32 0, i32 1
266   br label %BB2
268 BB2:
269   ;; Suck GEPs into phi
270   %c = phi ptr [ %X, %BB0 ], [ %Y, %BB1 ]
271   ret ptr %c
274 define i32 @test9(ptr %A, ptr %B) {
275 ; CHECK-LABEL: @test9(
276 ; CHECK-NEXT:  entry:
277 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[A:%.*]], null
278 ; CHECK-NEXT:    br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]]
279 ; CHECK:       bb:
280 ; CHECK-NEXT:    br label [[BB2:%.*]]
281 ; CHECK:       bb1:
282 ; CHECK-NEXT:    br label [[BB2]]
283 ; CHECK:       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]]
288 entry:
289   %c = icmp eq ptr %A, null
290   br i1 %c, label %bb1, label %bb
293   %C = load i32, ptr %B, align 1
294   br label %bb2
296 bb1:
297   %D = load i32, ptr %A, align 1
298   br label %bb2
300 bb2:
301   %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
302   ret i32 %E
306 define i32 @test10(ptr %A, ptr %B) {
307 ; CHECK-LABEL: @test10(
308 ; CHECK-NEXT:  entry:
309 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[A:%.*]], null
310 ; CHECK-NEXT:    br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]]
311 ; CHECK:       bb:
312 ; CHECK-NEXT:    br label [[BB2:%.*]]
313 ; CHECK:       bb1:
314 ; CHECK-NEXT:    br label [[BB2]]
315 ; CHECK:       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]]
320 entry:
321   %c = icmp eq ptr %A, null
322   br i1 %c, label %bb1, label %bb
325   %C = load i32, ptr %B, align 16
326   br label %bb2
328 bb1:
329   %D = load i32, ptr %A, align 32
330   br label %bb2
332 bb2:
333   %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
334   ret i32 %E
338 ; PR1777
339 declare i1 @test11a()
341 define i1 @test11() {
342 ; CHECK-LABEL: @test11(
343 ; CHECK-NEXT:  entry:
344 ; CHECK-NEXT:    [[B:%.*]] = call i1 @test11a()
345 ; CHECK-NEXT:    br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
346 ; CHECK:       one:
347 ; CHECK-NEXT:    [[C:%.*]] = call i1 @test11a()
348 ; CHECK-NEXT:    br i1 [[C]], label [[TWO]], label [[END:%.*]]
349 ; CHECK:       two:
350 ; CHECK-NEXT:    [[D:%.*]] = call i1 @test11a()
351 ; CHECK-NEXT:    br i1 [[D]], label [[ONE]], label [[END]]
352 ; CHECK:       end:
353 ; CHECK-NEXT:    [[Z:%.*]] = call i1 @test11a()
354 ; CHECK-NEXT:    ret i1 [[Z]]
356 entry:
357   %a = alloca i32
358   %i = ptrtoint ptr %a to i64
359   %b = call i1 @test11a()
360   br i1 %b, label %one, label %two
362 one:
363   %x = phi i64 [%i, %entry], [%y, %two]
364   %c = call i1 @test11a()
365   br i1 %c, label %two, label %end
367 two:
368   %y = phi i64 [%i, %entry], [%x, %one]
369   %d = call i1 @test11a()
370   br i1 %d, label %one, label %end
372 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
377   store i32 10, ptr %g
378   %z = call i1 @test11a()
379   ret i1 %z
383 define i64 @test12(i1 %cond, ptr %Ptr, i64 %Val) {
384 ; CHECK-LABEL: @test12(
385 ; CHECK-NEXT:  entry:
386 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]]
387 ; CHECK:       two:
388 ; CHECK-NEXT:    br label [[END]]
389 ; CHECK:       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]]
395 entry:
396   %t41 = ptrtoint ptr %Ptr to i64
397   %t42 = zext i64 %t41 to i128
398   br i1 %cond, label %end, label %two
400 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]
404   br label %end
406 end:
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
413   ret i64 %t2
416 declare void @test13f(double, i32)
418 define void @test13(i1 %cond, i32 %V1, double %Vald) {
419 ; CHECK-LABEL: @test13(
420 ; CHECK-NEXT:  entry:
421 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]]
422 ; CHECK:       two:
423 ; CHECK-NEXT:    br label [[END]]
424 ; CHECK:       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
429 entry:
430   %t42 = zext i32 %V1 to i128
431   br i1 %cond, label %end, label %two
433 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]
438   br label %end
440 end:
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)
448   ret void
451 define i640 @test14a(i320 %A, i320 %B, i1 %b1) {
452 ; CHECK-LABEL: @test14a(
453 ; CHECK-NEXT:  BB0:
454 ; CHECK-NEXT:    br label [[LOOP:%.*]]
455 ; CHECK:       Loop:
456 ; CHECK-NEXT:    [[C_IN:%.*]] = phi i320 [ [[A:%.*]], [[BB0:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
457 ; CHECK-NEXT:    br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
458 ; CHECK:       Exit:
459 ; CHECK-NEXT:    [[C:%.*]] = zext i320 [[C_IN]] to i640
460 ; CHECK-NEXT:    ret i640 [[C]]
462 BB0:
463   %a = zext i320 %A to i640
464   %b = zext i320 %B to i640
465   br label %Loop
467 Loop:
468   %C = phi i640 [ %a, %BB0 ], [ %b, %Loop ]
469   br i1 %b1, label %Loop, label %Exit
471 Exit:           ; preds = %Loop
472   ret i640 %C
475 define i160 @test14b(i320 %pA, i320 %pB, i1 %b1) {
476 ; CHECK-LABEL: @test14b(
477 ; CHECK-NEXT:  BB0:
478 ; CHECK-NEXT:    [[A:%.*]] = trunc i320 [[PA:%.*]] to i160
479 ; CHECK-NEXT:    [[B:%.*]] = trunc i320 [[PB:%.*]] to i160
480 ; CHECK-NEXT:    br label [[LOOP:%.*]]
481 ; CHECK:       Loop:
482 ; CHECK-NEXT:    [[C:%.*]] = phi i160 [ [[A]], [[BB0:%.*]] ], [ [[B]], [[LOOP]] ]
483 ; CHECK-NEXT:    br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
484 ; CHECK:       Exit:
485 ; CHECK-NEXT:    ret i160 [[C]]
487 BB0:
488   %a = trunc i320 %pA to i160
489   %b = trunc i320 %pB to i160
490   br label %Loop
492 Loop:
493   %C = phi i160 [ %a, %BB0 ], [ %b, %Loop ]
494   br i1 %b1, label %Loop, label %Exit
496 Exit:           ; preds = %Loop
497   ret i160 %C
500 declare i64 @test15a(i64)
502 define i64 @test15b(i64 %A, i1 %b) {
503 ; CHECK-LABEL: @test15b(
504 ; CHECK-NEXT:  entry:
505 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[ONE:%.*]], label [[TWO:%.*]]
506 ; CHECK:       one:
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]]
510 ; CHECK:       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:%.*]]
516 ; CHECK:       end:
517 ; CHECK-NEXT:    ret i64 [[Y_OFF0]]
519 entry:
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
525 one:
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
531   br label %two
534 two:
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
543 end:
544   %g = trunc i128 %y to i64
545   ret i64 %g
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(
551 ; CHECK-NEXT:  entry:
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:%.*]]
559 ; CHECK:       return:
560 ; CHECK-NEXT:    [[T7:%.*]] = load i32, ptr [[RETVAL]], align 4
561 ; CHECK-NEXT:    ret i32 [[T7]]
562 ; CHECK:       if.end:
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:%.*]]
566 ; CHECK:       if.then:
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:%.*]]
570 ; CHECK:       if.else:
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]]
575 nounwind {
576 entry:
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]
592   ret i32 %t7
594 if.end:                                           ; preds = %if.else, %if.then
595   %t6 = load i32, ptr %res                          ; <i32> [#uses=1]
596   store i32 %t6, ptr %retval
597   br label %return
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
604   br label %if.end
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
611   br label %if.end
614 ; PR4413
615 declare i32 @ext()
616 define i32 @test17(i1 %a) {
617 ; CHECK-LABEL: @test17(
618 ; CHECK-NEXT:  entry:
619 ; CHECK-NEXT:    br i1 [[A:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
620 ; CHECK:       bb1:
621 ; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @ext()
622 ; CHECK-NEXT:    br label [[BB2]]
623 ; CHECK:       bb2:
624 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[TMP0]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]
625 ; CHECK-NEXT:    ret i32 [[RES]]
627 entry:
628   br i1 %a, label %bb1, label %bb2
630 bb1:        ; preds = %entry
631   %0 = tail call i32 @ext()        ; <i32> [#uses=1]
632   br label %bb2
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]
638   ret i32 %res
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(
644 ; CHECK-NEXT:  entry:
645 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[PTR:%.*]], align 4
646 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]
647 ; CHECK:       if:
648 ; CHECK-NEXT:    [[Y:%.*]] = load atomic i32, ptr [[ATOMIC_PTR:%.*]] acquire, align 4
649 ; CHECK-NEXT:    br label [[END]]
650 ; CHECK:       end:
651 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[X]], [[ENTRY:%.*]] ], [ [[Y]], [[IF]] ]
652 ; CHECK-NEXT:    ret i32 [[COND]]
654 entry:
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
660   br label %end
662 end:
663   %cond = phi i32 [ %x, %entry ], [ %y, %if ]
664   ret i32 %cond
667 define i1 @test18(i1 %cond) {
668 ; CHECK-LABEL: @test18(
669 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
670 ; CHECK:       true:
671 ; CHECK-NEXT:    br label [[RET:%.*]]
672 ; CHECK:       false:
673 ; CHECK-NEXT:    br label [[RET]]
674 ; CHECK:       ret:
675 ; CHECK-NEXT:    ret i1 false
677   %zero = alloca i32
678   %one = alloca i32
679   br i1 %cond, label %true, label %false
680 true:
681   br label %ret
682 false:
683   br label %ret
684 ret:
685   %ptr = phi ptr [ %zero, %true ] , [ %one, %false ]
686   %isnull = icmp eq ptr %ptr, null
687   ret i1 %isnull
690 define i1 @test19(i1 %cond, double %x) {
691 ; CHECK-LABEL: @test19(
692 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
693 ; CHECK:       true:
694 ; CHECK-NEXT:    br label [[RET:%.*]]
695 ; CHECK:       false:
696 ; CHECK-NEXT:    br label [[RET]]
697 ; CHECK:       ret:
698 ; CHECK-NEXT:    ret i1 true
700   br i1 %cond, label %true, label %false
701 true:
702   br label %ret
703 false:
704   br label %ret
705 ret:
706   %p = phi double [ %x, %true ], [ 0x7FF0000000000000, %false ]; RHS = +infty
707   %cmp = fcmp ule double %x, %p
708   ret i1 %cmp
711 define i1 @test20(i1 %cond) {
712 ; CHECK-LABEL: @test20(
713 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
714 ; CHECK:       true:
715 ; CHECK-NEXT:    br label [[RET:%.*]]
716 ; CHECK:       false:
717 ; CHECK-NEXT:    br label [[RET]]
718 ; CHECK:       ret:
719 ; CHECK-NEXT:    ret i1 false
721   %a = alloca i32
722   %b = alloca i32
723   %c = alloca i32
724   br i1 %cond, label %true, label %false
725 true:
726   br label %ret
727 false:
728   br label %ret
729 ret:
730   %p = phi ptr [ %a, %true ], [ %b, %false ]
731   %r = icmp eq ptr %p, %c
732   ret i1 %r
735 define i1 @test21(i1 %c1, i1 %c2) {
736 ; CHECK-LABEL: @test21(
737 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
738 ; CHECK:       true:
739 ; CHECK-NEXT:    br label [[LOOP:%.*]]
740 ; CHECK:       false:
741 ; CHECK-NEXT:    br label [[LOOP]]
742 ; CHECK:       loop:
743 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[RET:%.*]], label [[LOOP]]
744 ; CHECK:       ret:
745 ; CHECK-NEXT:    ret i1 false
747   %a = alloca i32
748   %b = alloca i32
749   %c = alloca i32
750   br i1 %c1, label %true, label %false
751 true:
752   br label %loop
753 false:
754   br label %loop
755 loop:
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
759 ret:
760   ret i1 %r
763 define void @test22() {
764 ; CHECK-LABEL: @test22(
765 ; CHECK-NEXT:  entry:
766 ; CHECK-NEXT:    br label [[LOOP:%.*]]
767 ; CHECK:       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:%.*]]
773 ; CHECK:       ret:
774 ; CHECK-NEXT:    ret void
776 entry:
777   br label %loop
778 loop:
779   %phi = phi i32 [ 0, %entry ], [ %y, %loop ]
780   %y = add i32 %phi, 1
781   %o = or i32 %y, %phi
782   %e = icmp eq i32 %o, %y
783   br i1 %e, label %loop, label %ret
784 ret:
785   ret void
788 define i32 @test23(i32 %A, i1 %pb, ptr %P) {
789 ; CHECK-LABEL: @test23(
790 ; CHECK-NEXT:  BB0:
791 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[A:%.*]], 19
792 ; CHECK-NEXT:    br label [[LOOP:%.*]]
793 ; CHECK:       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:%.*]]
797 ; CHECK:       Exit:
798 ; CHECK-NEXT:    ret i32 [[B]]
800 BB0:
801   br label %Loop
803 Loop:           ; preds = %Loop, %BB0
804   ; PHI has same value always.
805   %B = phi i32 [ %A, %BB0 ], [ 42, %Loop ]
806   %D = add i32 %B, 19
807   store i32 %D, ptr %P
808   br i1 %pb, label %Loop, label %Exit
810 Exit:           ; preds = %Loop
811   %E = add i32 %B, 19
812   ret i32 %E
815 define i32 @test24(i32 %A, i1 %cond) {
816 ; CHECK-LABEL: @test24(
817 ; CHECK-NEXT:  BB0:
818 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
819 ; CHECK:       BB1:
820 ; CHECK-NEXT:    br label [[BB2]]
821 ; CHECK:       BB2:
822 ; CHECK-NEXT:    [[C:%.*]] = add nuw i32 [[A:%.*]], 1
823 ; CHECK-NEXT:    ret i32 [[C]]
825 BB0:
826   %X = add nuw nsw i32 %A, 1
827   br i1 %cond, label %BB1, label %BB2
829 BB1:
830   %Y = add nuw i32 %A, 1
831   br label %BB2
833 BB2:
834   %C = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
835   ret i32 %C
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(
843 ; CHECK-NEXT:  entry:
844 ; CHECK-NEXT:    [[B:%.*]] = call i1 @test25a()
845 ; CHECK-NEXT:    br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
846 ; CHECK:       one:
847 ; CHECK-NEXT:    [[C:%.*]] = call i1 @test25a()
848 ; CHECK-NEXT:    br i1 [[C]], label [[TWO]], label [[END:%.*]]
849 ; CHECK:       two:
850 ; CHECK-NEXT:    [[D:%.*]] = call i1 @test25a()
851 ; CHECK-NEXT:    br i1 [[D]], label [[ONE]], label [[END]]
852 ; CHECK:       end:
853 ; CHECK-NEXT:    [[Z:%.*]] = call i1 @test25a()
854 ; CHECK-NEXT:    ret i1 [[Z]]
856 entry:
857   %a = alloca i32
858   %i = ptrtoint ptr %a to i64
859   %b = call i1 @test25a()
860   br i1 %b, label %one, label %two
862 one:
863   %x = phi i64 [%y, %two], [%i, %entry]
864   %c = call i1 @test25a()
865   br i1 %c, label %two, label %end
867 two:
868   %y = phi i64 [%x, %one], [%i, %entry]
869   %d = call i1 @test25a()
870   br i1 %d, label %one, label %end
872 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
877   store i32 10, ptr %g
878   %z = call i1 @test25a()
879   ret i1 %z
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(
885 ; CHECK-NEXT:  entry:
886 ; CHECK-NEXT:    br i1 [[CI:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
887 ; CHECK:       then:
888 ; CHECK-NEXT:    br label [[ELSE]]
889 ; CHECK:       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:%.*]]
893 ; CHECK:       one:
894 ; CHECK-NEXT:    [[C:%.*]] = call i1 @test25a()
895 ; CHECK-NEXT:    br i1 [[C]], label [[TWO]], label [[END:%.*]]
896 ; CHECK:       two:
897 ; CHECK-NEXT:    [[D:%.*]] = call i1 @test25a()
898 ; CHECK-NEXT:    br i1 [[D]], label [[ONE]], label [[END]]
899 ; CHECK:       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]]
905 entry:
906   br i1 %ci, label %then, label %else
908 then:
909   br label %else
911 else:
912   %i = phi i64 [ %ai, %entry ], [ %bi, %then ]
913   %b = call i1 @test25a()
914   br i1 %b, label %one, label %two
916 one:
917   %x = phi i64 [%y, %two], [%i, %else]
918   %c = call i1 @test25a()
919   br i1 %c, label %two, label %end
921 two:
922   %y = phi i64 [%x, %one], [%i, %else]
923   %d = call i1 @test25a()
924   br i1 %d, label %one, label %end
926 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
931   store i32 10, ptr %g
932   %z = call i1 @test25a()
933   ret i1 %z
936 declare i1 @test26a()
938 define i1 @test26(i32 %n) {
939 ; CHECK-LABEL: @test26(
940 ; CHECK-NEXT:  entry:
941 ; CHECK-NEXT:    [[B:%.*]] = call i1 @test26a()
942 ; CHECK-NEXT:    br label [[ONE:%.*]]
943 ; CHECK:       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:%.*]]
948 ; CHECK-NEXT:    ]
949 ; CHECK:       two:
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]]
954 ; CHECK-NEXT:    ]
955 ; CHECK:       three:
956 ; CHECK-NEXT:    [[E:%.*]] = call i1 @test26a()
957 ; CHECK-NEXT:    br i1 [[E]], label [[ONE]], label [[TWO]]
958 ; CHECK:       end:
959 ; CHECK-NEXT:    [[Z:%.*]] = call i1 @test26a()
960 ; CHECK-NEXT:    ret i1 [[Z]]
962 entry:
963   %a = alloca i32
964   %i = ptrtoint ptr %a to i64
965   %b = call i1 @test26a()
966   br label %one
968 one:
969   %x = phi i64 [%y, %two], [%w, %three], [%i, %entry]
970   %c = call i1 @test26a()
971   switch i32 %n, label %end [
972   i32 2, label %two
973   i32 3, label %three
974   ]
976 two:
977   %y = phi i64 [%x, %one], [%w, %three]
978   %d = call i1 @test26a()
979   switch i32 %n, label %end [
980   i32 10, label %one
981   i32 30, label %three
982   ]
984 three:
985   %w = phi i64 [%y, %two], [%x, %one]
986   %e = call i1 @test26a()
987   br i1 %e, label %one, label %two
989 end:
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
994   store i32 10, ptr %g
995   %z = call i1 @test26a()
996   ret i1 %z
999 define i32 @test27(i1 %b) {
1000 ; CHECK-LABEL: @test27(
1001 ; CHECK-NEXT:  entry:
1002 ; CHECK-NEXT:    br label [[DONE:%.*]]
1003 ; CHECK:       done:
1004 ; CHECK-NEXT:    ret i32 undef
1006 entry:
1007   br label %done
1008 done:
1009   %y = phi i32 [ undef, %entry ]
1010   ret i32 %y
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:%.*]]
1023 ; CHECK-NEXT:    ]
1024 ; CHECK:       sw1:
1025 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1026 ; CHECK-NEXT:    br label [[EPILOG]]
1027 ; CHECK:       sw2:
1028 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1029 ; CHECK-NEXT:    br label [[EPILOG]]
1030 ; CHECK:       epilog:
1031 ; CHECK-NEXT:    [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ]
1032 ; CHECK-NEXT:    ret i1 [[CONDITIONMET_SHRUNK]]
1034 entry:
1035   %conv = sext i8 %condition to i32
1036   switch i32 %conv, label %epilog [
1037   i32 0, label %sw1
1038   i32 1, label %sw2
1039   ]
1041 sw1:
1042   %cmp1 = icmp eq i8 %x1, %x2
1043   %frombool1 = zext i1 %cmp1 to i8
1044   br label %epilog
1046 sw2:
1047   %cmp2 = icmp sle i8 %x1, %x2
1048   %frombool2 = zext i1 %cmp2 to i8
1049   br label %epilog
1051 epilog:
1052   %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
1053   %tobool = icmp ne i8 %conditionMet, 0
1054   ret i1 %tobool
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:%.*]]
1066 ; CHECK-NEXT:    ]
1067 ; CHECK:       sw1:
1068 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1069 ; CHECK-NEXT:    br label [[EPILOG]]
1070 ; CHECK:       sw2:
1071 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1072 ; CHECK-NEXT:    br label [[EPILOG]]
1073 ; CHECK:       epilog:
1074 ; CHECK-NEXT:    [[CONDITIONMET_IN:%.*]] = phi i1 [ [[ANOTHER_CONDITION:%.*]], [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ]
1075 ; CHECK-NEXT:    ret i1 [[CONDITIONMET_IN]]
1077 entry:
1078   %frombool0 = zext i1 %another_condition to i8
1079   %conv = sext i8 %condition to i32
1080   switch i32 %conv, label %epilog [
1081   i32 0, label %sw1
1082   i32 1, label %sw2
1083   ]
1085 sw1:
1086   %cmp1 = icmp eq i8 %x1, %x2
1087   %frombool1 = zext i1 %cmp1 to i8
1088   br label %epilog
1090 sw2:
1091   %cmp2 = icmp sle i8 %x1, %x2
1092   %frombool2 = zext i1 %cmp2 to i8
1093   br label %epilog
1095 epilog:
1096   %conditionMet = phi i8 [ %frombool0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
1097   %tobool = icmp ne i8 %conditionMet, 0
1098   ret i1 %tobool
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:%.*]]
1110 ; CHECK-NEXT:    ]
1111 ; CHECK:       sw1:
1112 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1113 ; CHECK-NEXT:    br label [[EPILOG]]
1114 ; CHECK:       sw2:
1115 ; CHECK-NEXT:    br label [[EPILOG]]
1116 ; CHECK:       epilog:
1117 ; CHECK-NEXT:    [[CONDITIONMET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[SW2]] ], [ [[CMP1]], [[SW1]] ]
1118 ; CHECK-NEXT:    ret i1 [[CONDITIONMET]]
1120 entry:
1121   %conv = sext i8 %condition to i32
1122   switch i32 %conv, label %epilog [
1123   i32 0, label %sw1
1124   i32 1, label %sw2
1125   ]
1127 sw1:
1128   %cmp1 = icmp eq i8 %x1, %x2
1129   %frombool1 = zext i1 %cmp1 to i8
1130   br label %epilog
1132 sw2:
1133   %cmp2 = icmp sle i8 %x1, %x2
1134   %frombool2 = zext i1 %cmp2 to i8
1135   br label %epilog
1137 epilog:
1138   %conditionMet = phi i8 [ 0, %entry ], [ 1, %sw2 ], [ %frombool1, %sw1 ]
1139   %tobool = icmp ne i8 %conditionMet, 0
1140   ret i1 %tobool
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:%.*]]
1153 ; CHECK-NEXT:    ]
1154 ; CHECK:       sw1:
1155 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1156 ; CHECK-NEXT:    br label [[EPILOG]]
1157 ; CHECK:       sw2:
1158 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1159 ; CHECK-NEXT:    br label [[EPILOG]]
1160 ; CHECK:       sw3:
1161 ; CHECK-NEXT:    br label [[EPILOG]]
1162 ; CHECK:       epilog:
1163 ; CHECK-NEXT:    [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ], [ true, [[SW3]] ]
1164 ; CHECK-NEXT:    ret i1 [[CONDITIONMET_SHRUNK]]
1166 entry:
1167   %conv = sext i8 %condition to i32
1168   switch i32 %conv, label %epilog [
1169   i32 0, label %sw1
1170   i32 1, label %sw2
1171   i32 2, label %sw3
1172   ]
1174 sw1:
1175   %cmp1 = icmp eq i8 %x1, %x2
1176   %frombool1 = zext i1 %cmp1 to i8
1177   br label %epilog
1179 sw2:
1180   %cmp2 = icmp sle i8 %x1, %x2
1181   %frombool2 = zext i1 %cmp2 to i8
1182   br label %epilog
1184 sw3:
1185   %cmp3 = icmp sge i8 %x1, %x2
1186   %frombool3 = zext i1 %cmp3 to i8
1187   br label %epilog
1189 epilog:
1190   %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ], [ 1, %sw3 ]
1191   %tobool = icmp ne i8 %conditionMet, 0
1192   ret i1 %tobool
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:%.*]]
1200 ; CHECK:       if.then:
1201 ; CHECK-NEXT:    br label [[IF_END:%.*]]
1202 ; CHECK:       if.else:
1203 ; CHECK-NEXT:    call void @dummy()
1204 ; CHECK-NEXT:    br label [[IF_END]]
1205 ; CHECK:       if.end:
1206 ; CHECK-NEXT:    ret i1 false
1208 entry:
1209   br i1 %c, label %if.then, label %if.else
1211 if.then:                                          ; preds = %entry
1212   br label %if.end
1214 if.else:                                          ; preds = %entry
1215   call void @dummy()
1217   br label %if.end
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
1223   ret i1 %cmp1
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:%.*]]
1230 ; CHECK:       if.then:
1231 ; CHECK-NEXT:    br label [[IF_END:%.*]]
1232 ; CHECK:       if.else:
1233 ; CHECK-NEXT:    call void @dummy()
1234 ; CHECK-NEXT:    br label [[IF_END]]
1235 ; CHECK:       if.end:
1236 ; CHECK-NEXT:    ret i1 false
1238 entry:
1239   br i1 %c, label %if.then, label %if.else
1241 if.then:                                          ; preds = %entry
1242   br label %if.end
1244 if.else:                                          ; preds = %entry
1245   call void @dummy()
1247   br label %if.end
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
1252   ret i1 %cmp1
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:%.*]]
1262 ; CHECK:       if.then:
1263 ; CHECK-NEXT:    br label [[IF_END]]
1264 ; CHECK:       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]]
1269 entry:
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
1277   br label %if.end
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
1282   ret i1  %cmp1
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:%.*]]
1290 ; CHECK:       if.then:
1291 ; CHECK-NEXT:    br label [[IF_END]]
1292 ; CHECK:       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]]
1297 entry:
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
1305   br label %if.end
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
1310   ret i1  %cmp1
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:%.*]]
1318 ; CHECK:       if.then:
1319 ; CHECK-NEXT:    br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]]
1320 ; CHECK:       if.else:
1321 ; CHECK-NEXT:    br label [[IF_END]]
1322 ; CHECK:       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]]
1327 entry:
1328   %tobool = icmp slt  i32 %n, %s
1329   br i1 %tobool, label %if.then, label %if.end
1331 if.then:
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
1339   br label %if.end
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
1344   ret i1  %cmp1
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:%.*]]
1352 ; CHECK:       if.then:
1353 ; CHECK-NEXT:    br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]]
1354 ; CHECK:       if.else:
1355 ; CHECK-NEXT:    br label [[IF_END]]
1356 ; CHECK:       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]]
1361 entry:
1362   %tobool = icmp slt  i32 %n, %s
1363   br i1 %tobool, label %if.then, label %if.end
1365 if.then:
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
1373   br label %if.end
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
1378   ret i1  %cmp1
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:%.*]]
1386 ; CHECK:       if.then:
1387 ; CHECK-NEXT:    br label [[IF_END]]
1388 ; CHECK:       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]]
1394 entry:
1395   %tobool = icmp slt  i32 %n, %s
1396   br i1 %tobool, label %if.end, label %if.then
1398 if.then:
1399   %load = load i32, ptr %P
1400   %cmp = icmp eq i32 %n, %load
1401   %sel = select i1 %cmp, i32 1, i32 2
1402   br label %if.end
1404 if.end:
1405   %phi = phi i32 [ %sel,  %if.then ], [ %n, %entry ]
1406   %orphi = or i32 %phi, %val
1407   %cmp1 = icmp eq i32 %orphi, 0
1408   ret i1  %cmp1
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:%.*]]
1416 ; CHECK:       if.then:
1417 ; CHECK-NEXT:    br label [[IF_END]]
1418 ; CHECK:       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]]
1424 entry:
1425   %tobool = icmp slt  i32 %n, %s
1426   br i1 %tobool, label %if.end, label %if.then
1428 if.then:
1429   %load = load i32, ptr %P
1430   %cmp = icmp eq i32 %n, %load
1431   %sel = select i1 %cmp, i32 1, i32 2
1432   br label %if.end
1434 if.end:
1435   %phi = phi i32 [ %sel,  %if.then ], [ %n, %entry ]
1436   %orphi = or i32 %val, %phi
1437   %cmp1 = icmp eq i32 %orphi, 0
1438   ret i1  %cmp1
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:%.*]]
1446 ; CHECK:       if.then:
1447 ; CHECK-NEXT:    br label [[IF_END]]
1448 ; CHECK:       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]]
1454 entry:
1455   %tobool = icmp slt  i32 %n, %s
1456   br i1 %tobool, label %if.end, label %if.then
1458 if.then:
1459   %load = load i32, ptr %P
1460   %cmp = icmp eq i32 %n, %load
1461   %sel = select i1 %cmp, i32 1, i32 2
1462   br label %if.end
1464 if.end:
1465   %phi = phi i32 [ %sel,  %if.then ], [ %n, %entry ]
1466   %orphi = or disjoint i32 %phi, %val
1467   %cmp1 = icmp eq i32 %orphi, 0
1468   ret i1  %cmp1
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:%.*]]
1476 ; CHECK:       if.then:
1477 ; CHECK-NEXT:    br label [[IF_END]]
1478 ; CHECK:       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]]
1484 entry:
1485   %tobool = icmp slt  i32 %n, %s
1486   br i1 %tobool, label %if.end, label %if.then
1488 if.then:
1489   %load = load i32, ptr %P
1490   %cmp = icmp eq i32 %n, %load
1491   %sel = select i1 %cmp, i32 1, i32 2
1492   br label %if.end
1494 if.end:
1495   %phi = phi i32 [ %sel,  %if.then ], [ %n, %entry ]
1496   %orphi = or i32 %phi, %val
1497   %cmp1 = icmp ne i32 %orphi, 0
1498   ret i1  %cmp1
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:%.*]]
1506 ; CHECK:       if.then:
1507 ; CHECK-NEXT:    br label [[IF_END]]
1508 ; CHECK:       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]]
1514 entry:
1515   %tobool = icmp slt  i32 %n, %s
1516   br i1 %tobool, label %if.end, label %if.then
1518 if.then:
1519   %load = load i32, ptr %P
1520   %cmp = icmp eq i32 %n, %load
1521   %sel = select i1 %cmp, i32 1, i32 2
1522   br label %if.end
1524 if.end:
1525   %phi = phi i32 [ %sel,  %if.then ], [ %n, %entry ]
1526   %orphi = or i32 %val, %phi
1527   %cmp1 = icmp ne i32 %orphi, 0
1528   ret i1  %cmp1
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:%.*]]
1536 ; CHECK:       if.then:
1537 ; CHECK-NEXT:    br label [[IF_END]]
1538 ; CHECK:       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:%.*]]
1543 ; CHECK:       next:
1544 ; CHECK-NEXT:    [[BOOL2:%.*]] = icmp eq i32 [[PHI]], 0
1545 ; CHECK-NEXT:    br label [[CLEANUP]]
1546 ; CHECK:       cleanup:
1547 ; CHECK-NEXT:    [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1548 ; CHECK-NEXT:    ret i1 [[FINAL]]
1550 entry:
1551   %tobool = icmp slt  i32 %n, %s
1552   br i1 %tobool, label %if.end, label %if.then
1554 if.then:
1555   %load = load i32, ptr %P
1556   %cmp = icmp eq i32 %n, %load
1557   %sel = select i1 %cmp, i32 1, i32 2
1558   br label %if.end
1560 if.end:
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
1566 next:
1567   %bool2 = icmp eq i32 %phi, 0
1568   br label %cleanup
1570 cleanup:
1571   %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1572   ret i1  %final
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:%.*]]
1580 ; CHECK:       if.then:
1581 ; CHECK-NEXT:    br label [[IF_END]]
1582 ; CHECK:       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:%.*]]
1587 ; CHECK:       next:
1588 ; CHECK-NEXT:    [[BOOL2:%.*]] = icmp ne i32 [[PHI]], 0
1589 ; CHECK-NEXT:    br label [[CLEANUP]]
1590 ; CHECK:       cleanup:
1591 ; CHECK-NEXT:    [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1592 ; CHECK-NEXT:    ret i1 [[FINAL]]
1594 entry:
1595   %tobool = icmp slt  i32 %n, %s
1596   br i1 %tobool, label %if.end, label %if.then
1598 if.then:
1599   %load = load i32, ptr %P
1600   %cmp = icmp eq i32 %n, %load
1601   %sel = select i1 %cmp, i32 1, i32 2
1602   br label %if.end
1604 if.end:
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
1610 next:
1611   %bool2 = icmp ne i32 %phi, 0
1612   br label %cleanup
1614 cleanup:
1615   %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1616   ret i1  %final
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:%.*]]
1624 ; CHECK:       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]]
1629 ; CHECK:       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:%.*]]
1634 ; CHECK:       next:
1635 ; CHECK-NEXT:    [[BOOL2:%.*]] = icmp eq i32 [[PHI]], 0
1636 ; CHECK-NEXT:    br label [[CLEANUP]]
1637 ; CHECK:       cleanup:
1638 ; CHECK-NEXT:    [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1639 ; CHECK-NEXT:    ret i1 [[FINAL]]
1641 entry:
1642   %tobool = icmp slt  i32 %n, %s
1643   br i1 %tobool, label %if.end, label %if.then
1645 if.then:
1646   %load = load i32, ptr %P
1647   %cmp = icmp eq i32 %n, %load
1648   %sel = select i1 %cmp, i32 1, i32 2
1649   br label %if.end
1651 if.end:
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
1657 next:
1658   %bool2 = icmp eq i32 %phi, 0
1659   br label %cleanup
1661 cleanup:
1662   %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1663   ret i1  %final
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:%.*]]
1671 ; CHECK:       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]]
1676 ; CHECK:       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:%.*]]
1681 ; CHECK:       next:
1682 ; CHECK-NEXT:    [[BOOL2:%.*]] = icmp ne i32 [[PHI]], 0
1683 ; CHECK-NEXT:    br label [[CLEANUP]]
1684 ; CHECK:       cleanup:
1685 ; CHECK-NEXT:    [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1686 ; CHECK-NEXT:    ret i1 [[FINAL]]
1688 entry:
1689   %tobool = icmp slt  i32 %n, %s
1690   br i1 %tobool, label %if.end, label %if.then
1692 if.then:
1693   %load = load i32, ptr %P
1694   %cmp = icmp eq i32 %n, %load
1695   %sel = select i1 %cmp, i32 1, i32 2
1696   br label %if.end
1698 if.end:
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
1704 next:
1705   %bool2 = icmp ne i32 %phi, 0
1706   br label %cleanup
1708 cleanup:
1709   %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1710   ret i1  %final
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:%.*]]
1721 ; CHECK:       for.cond:
1722 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]]
1723 ; CHECK:       for.body:
1724 ; CHECK-NEXT:    unreachable
1725 ; CHECK:       g.exit:
1726 ; CHECK-NEXT:    br label [[FOR_COND]]
1727 ; CHECK:       for.end:
1728 ; CHECK-NEXT:    store double undef, ptr undef, align 8
1729 ; CHECK-NEXT:    ret void
1731 entry:
1732   br label %for.cond
1734 for.cond:
1735   %p = phi double [ %conv, %g.exit ], [ undef, %entry ]
1736   br i1 %cond, label %for.end, label %for.body
1738 for.body:
1739   %conv = sitofp i16 %x to double
1740   unreachable
1742 g.exit:
1743   br label %for.cond
1745 for.end:
1746   store double %p, ptr undef
1747   ret void
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:%.*]]
1756 ; CHECK:       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]]
1765 ; CHECK:       exit:
1766 ; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ true, [[START]] ], [ [[AND]], [[LOOP]] ]
1767 ; CHECK-NEXT:    ret i1 [[RES]]
1769 start:
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
1774 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
1786 exit:
1787   %res = phi i1 [ true, %start ], [ %and, %loop ]
1788   ret i1 %res
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:%.*]]
1798 ; CHECK:       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]]
1805 entry:
1806   br label %loop
1808 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
1813   br label %loop
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:%.*]]
1821 ; CHECK:       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]]
1828 ; CHECK:       exit:
1829 ; CHECK-NEXT:    ret i32 [[PHI]]
1831 entry:
1832   br label %loop
1834 loop:
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
1840 loop.latch:
1841   %c2 = call i1 @get.i1()
1842   br i1 %c2, label %exit, label %loop
1844 exit:
1845   ret i32 %or
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:%.*]]
1853 ; CHECK:       if:
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:%.*]]
1857 ; CHECK:       else:
1858 ; CHECK-NEXT:    br label [[JOIN]]
1859 ; CHECK:       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]]
1864 entry:
1865   br i1 %c, label %if, label %else
1868   %arg.ptr2.val = load i64, ptr %arg.ptr2, align 8
1869   br label %join
1871 else:
1872   %arg.int.ptr = ptrtoint ptr %arg.ptr to i64
1873   br label %join
1875 join:
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
1879   ret i64 %v
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:%.*]]
1887 ; CHECK:       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:%.*]]
1893 ; CHECK:       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]]
1897 ; CHECK:       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]]
1901 ; CHECK:       exit:
1902 ; CHECK-NEXT:    ret void
1904 entry:
1905   %ptr.end = getelementptr inbounds i8, ptr %ptr.base, i64 %n
1906   br label %loop
1908 loop:
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)
1918   br label %latch
1920 latch:
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
1925 exit:
1926   ret void
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:%.*]]
1933 ; CHECK:       if.then:
1934 ; CHECK-NEXT:    br label [[IF_END]]
1935 ; CHECK:       if.end:
1936 ; CHECK-NEXT:    [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
1937 ; CHECK-NEXT:    ret i32 [[ADD]]
1939 entry:
1940   br i1 %c, label %if.then, label %if.end
1942 if.then:
1943   br label %if.end
1945 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
1949   ret i32 %add
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:%.*]]
1956 ; CHECK:       if.then:
1957 ; CHECK-NEXT:    br label [[IF_END]]
1958 ; CHECK:       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]]
1964 entry:
1965   br i1 %c, label %if.then, label %if.end
1967 if.then:
1968   br label %if.end
1970 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
1974   ret i32 %add
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:%.*]]
1981 ; CHECK:       if.then:
1982 ; CHECK-NEXT:    br label [[IF_END]]
1983 ; CHECK:       if.end:
1984 ; CHECK-NEXT:    [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
1985 ; CHECK-NEXT:    ret i32 [[ADD]]
1987 entry:
1988   br i1 %c, label %if.then, label %if.end
1990 if.then:
1991   br label %if.end
1993 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
1997   ret i32 %add
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:%.*]]
2004 ; CHECK:       if.then:
2005 ; CHECK-NEXT:    br label [[IF_END]]
2006 ; CHECK:       if.end:
2007 ; CHECK-NEXT:    [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2008 ; CHECK-NEXT:    ret i32 [[ADD]]
2010 entry:
2011   br i1 %c, label %if.then, label %if.end
2013 if.then:
2014   br label %if.end
2016 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
2020   ret i32 %add
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:%.*]]
2027 ; CHECK:       if.then:
2028 ; CHECK-NEXT:    br label [[IF_END]]
2029 ; CHECK:       if.end:
2030 ; CHECK-NEXT:    [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2031 ; CHECK-NEXT:    ret i32 [[ADD]]
2033 entry:
2034   br i1 %c, label %if.then, label %if.end
2036 if.then:
2037   br label %if.end
2039 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
2043   ret i32 %add
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:%.*]]
2050 ; CHECK:       if.then:
2051 ; CHECK-NEXT:    br label [[IF_END]]
2052 ; CHECK:       if.end:
2053 ; CHECK-NEXT:    [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
2054 ; CHECK-NEXT:    ret i32 [[ADD]]
2056 entry:
2057   br i1 %c, label %if.then, label %if.end
2059 if.then:
2060   br label %if.end
2062 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
2066   ret i32 %add
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:%.*]]
2073 ; CHECK:       if.then:
2074 ; CHECK-NEXT:    br label [[IF_END]]
2075 ; CHECK:       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]]
2081 entry:
2082   br i1 %c, label %if.then, label %if.end
2084 if.then:
2085   br label %if.end
2087 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
2091   ret i32 %add
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]]
2104 ; CHECK:       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
2114 sub_is_zero:
2115   %5 = getelementptr inbounds i8, ptr %C, i64 1
2116   %6 = load i8, ptr %5, align 1
2117   %7 = zext i8 %6 to i32
2118   br label %join
2120 join:
2121   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2122   %cmp = icmp eq i32 %8, 0
2123   ret i1 %cmp
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]]
2141 ; CHECK:       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
2151 sub_is_zero:
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
2159 sub_is_zero1:
2160   %10 = getelementptr inbounds i8, ptr %C, i64 2
2161   %11 = load i8, ptr %10, align 1
2162   %12 = zext i8 %11 to i32
2163   br label %join
2165 join:
2166   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2167   %cmp = icmp eq i32 %13, 0
2168   ret i1 %cmp
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]]
2181 ; CHECK:       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
2191 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
2195   br label %join
2197 join:
2198   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2199   %cmp = icmp eq i32 %8, 0
2200   ret i1 %cmp
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]]
2219 ; CHECK:       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
2229 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
2237 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
2241   br label %join
2243 join:
2244   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2245   %cmp = icmp eq i32 %13, 0
2246   ret i1 %cmp
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]]
2259 ; CHECK:       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
2269 sub_is_zero:
2270   %5 = getelementptr inbounds i8, ptr %C, i64 1
2271   %6 = load i8, ptr %5, align 1
2272   %7 = zext i8 %6 to i32
2273   br label %join
2275 join:
2276   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2277   %cmp = icmp ne i32 %8, 0
2278   ret i1 %cmp
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]]
2296 ; CHECK:       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
2314 sub_is_zero1:
2315   %10 = getelementptr inbounds i8, ptr %C, i64 2
2316   %11 = load i8, ptr %10, align 1
2317   %12 = zext i8 %11 to i32
2318   br label %join
2320 join:
2321   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2322   %cmp = icmp ne i32 %13, 0
2323   ret i1 %cmp
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]]
2336 ; CHECK:       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
2346 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
2350   br label %join
2352 join:
2353   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2354   %cmp = icmp ne i32 %8, 0
2355   ret i1 %cmp
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]]
2373 ; CHECK:       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
2391 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
2395   br label %join
2397 join:
2398   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2399   %cmp = icmp ne i32 %13, 0
2400   ret i1 %cmp
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]]
2413 ; CHECK:       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
2423 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
2427   br label %join
2429 join:
2430   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2431   %cmp = icmp sgt i32 %8, 0
2432   ret i1 %cmp
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]]
2450 ; CHECK:       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
2460 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
2468 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
2472   br label %join
2474 join:
2475   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2476   %cmp = icmp sgt i32 %13, 0
2477   ret i1 %cmp
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]]
2492 ; CHECK:       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
2503 sub_is_zero:
2504   %5 = getelementptr inbounds i8, ptr %C, i64 1
2505   %6 = load i8, ptr %5, align 1
2506   %7 = zext i8 %6 to i32
2507   br label %join
2509 join:
2510   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2511   %cmp = icmp sgt i32 %8, 0
2512   ret i1 %cmp
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]]
2534 ; CHECK:       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
2545 sub_is_zero:
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
2553 sub_is_zero1:
2554   %10 = getelementptr inbounds i8, ptr %C, i64 2
2555   %11 = load i8, ptr %10, align 1
2556   %12 = zext i8 %11 to i32
2557   br label %join
2559 join:
2560   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2561   %cmp = icmp sgt i32 %13, 0
2562   ret i1 %cmp
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]]
2572 ; CHECK:       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
2581 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
2585   br label %join
2587 join:
2588   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2589   %cmp = icmp slt i32 %8, 0
2590   ret i1 %cmp
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]]
2605 ; CHECK:       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
2614 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
2622 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
2626   br label %join
2628 join:
2629   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2630   %cmp = icmp slt i32 %13, 0
2631   ret i1 %cmp
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]]
2646 ; CHECK:       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
2657 sub_is_zero:
2658   %5 = getelementptr inbounds i8, ptr %C, i64 1
2659   %6 = load i8, ptr %5, align 1
2660   %7 = zext i8 %6 to i32
2661   br label %join
2663 join:
2664   %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2665   %cmp = icmp slt i32 %8, 0
2666   ret i1 %cmp
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]]
2688 ; CHECK:       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
2699 sub_is_zero:
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
2707 sub_is_zero1:
2708   %10 = getelementptr inbounds i8, ptr %C, i64 2
2709   %11 = load i8, ptr %10, align 1
2710   %12 = zext i8 %11 to i32
2711   br label %join
2713 join:
2714   %13 = phi i32 [ %3, %0 ], [ %8, %sub_is_zero ], [ %12, %sub_is_zero1 ]
2715   %cmp = icmp slt i32 %13, 0
2716   ret i1 %cmp
2719 define void @phi_op_in_loop(i1 %c, i32 %x) {
2720 ; CHECK-LABEL: @phi_op_in_loop(
2721 ; CHECK-NEXT:    br label [[LOOP:%.*]]
2722 ; CHECK:       loop:
2723 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]
2724 ; CHECK:       if:
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]]
2732   br label %loop
2734 loop:
2735   br i1 %c, label %if, label %loop.latch
2738   br label %loop.latch
2740 loop.latch:
2741   %phi = phi i32 [ %x, %if ], [ 0, %loop ]
2742   %and = and i32 %phi, 1
2743   call void @use(i32 %and)
2744   br label %loop
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:%.*]]
2751 ; CHECK:       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:%.*]]
2756 ; CHECK-NEXT:    ]
2757 ; CHECK:       BB1:
2758 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2]], label [[BB4]]
2759 ; CHECK:       BB2:
2760 ; CHECK-NEXT:    br i1 [[COND]], label [[BB3]], label [[BB4]]
2761 ; CHECK:       BB3:
2762 ; CHECK-NEXT:    br label [[BB4]]
2763 ; CHECK:       BB4:
2764 ; CHECK-NEXT:    br i1 [[COND]], label [[BB0]], label [[BB5:%.*]]
2765 ; CHECK:       BB5:
2766 ; CHECK-NEXT:    ret void
2768 entry:
2769   br label %BB0
2771 BB0:                                              ; preds = %BB4, %entry
2772   %a = phi float [ 0.0, %entry ], [ %x, %BB4 ]
2773   switch i64 %index, label %BB4 [
2774   i64 0, label %BB1
2775   i64 1, label %BB2
2776   i64 2, label %BB3
2777   ]
2779 BB1:                                              ; preds = %BB0
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 ]
2788   br label %BB4
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
2794 BB5:                                             ; preds = %BB4
2795   ret void
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:%.*]]
2802 ; CHECK:       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]]
2808 ; CHECK:       exit:
2809 ; CHECK-NEXT:    ret i64 0
2811 entry:
2812   %add.ptr = getelementptr i8, ptr %ptr, i64 1
2813   br label %for.cond
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
2823   ret i64 0