xref: /llvm-project/llvm/test/Transforms/InstCombine/phi.ll (revision a8072a0b4ebd5cd1fb3958629cd453910691f6d3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target 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"
5
6define 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]]
14;
15BB0:
16  br i1 %b, label %BB1, label %BB2
17
18BB1:
19  ; Combine away one argument PHI nodes
20  %B = phi i32 [ %A, %BB0 ]
21  ret i32 %B
22
23BB2:
24  ret i32 %A
25}
26
27define 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:%.*]]
35;
36BB0:
37  br i1 %b, label %BB1, label %BB2
38
39BB1:
40  br label %BB2
41
42BB2:
43  ; Combine away PHI nodes with same values
44  %B = phi i32 [ %A, %BB0 ], [ %A, %BB1 ]
45  ret i32 %B
46}
47
48define 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:%.*]]
56;
57BB0:
58  br label %Loop
59
60Loop:
61  ; PHI has same value always.
62  %B = phi i32 [ %A, %BB0 ], [ %B, %Loop ]
63  br i1 %b, label %Loop, label %Exit
64
65Exit:
66  ret i32 %B
67}
68
69define 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]]
77;
78BB0:
79  ; Loop is unreachable
80  ret i32 7
81
82Loop:           ; 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
86
87L2:             ; preds = %Loop
88  br label %Loop
89}
90
91define 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]]
100;
101BB0:
102  br label %Loop
103
104Loop:           ; 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
108
109Exit:           ; preds = %Loop
110  ret i32 %B
111}
112
113define 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:%.*]]
121;
122BB0:
123  br label %Loop
124
125Loop:           ; 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
129
130Exit:           ; preds = %Loop
131  ret i32 %B
132}
133
134define 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]]
143;
144BB0:
145  %X = zext i16 %A to i32
146  br i1 %b, label %BB1, label %BB2
147
148BB1:
149  %Y = zext i16 %A to i32
150  br label %BB2
151
152BB2:
153  ;; Suck casts into phi
154  %c = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
155  ret i32 %c
156}
157
158define 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
166;
167BB0:
168  br label %Loop
169
170Loop:           ; 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
174
175Exit:           ; preds = %Loop
176  ret i32 0
177}
178
179define 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
187;
188BB0:
189  br label %Loop
190
191Loop:           ; preds = %Loop, %BB0
192  %B = phi double [ %A, %BB0 ], [ %C, %Loop ]
193  %C = fneg double %B
194  br i1 %cond, label %Loop, label %Exit
195
196Exit:           ; preds = %Loop
197  ret i32 0
198}
199
200define 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
211;
212BB0:
213  br label %Loop
214
215Loop:           ; 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
220
221Exit:           ; preds = %Loop
222  ret i32 0
223}
224
225declare i32 @llvm.uadd.sat.i32(i32, i32)
226
227define 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
237;
238BB0:
239  br label %Loop
240
241Loop:           ; 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
245
246Exit:           ; preds = %Loop
247  ret i32 0
248}
249
250define 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]]
259;
260BB0:
261  %X = getelementptr inbounds { i32, i32 }, ptr %A, i32 0, i32 1
262  br i1 %b, label %BB1, label %BB2
263
264BB1:
265  %Y = getelementptr { i32, i32 }, ptr %A, i32 0, i32 1
266  br label %BB2
267
268BB2:
269  ;; Suck GEPs into phi
270  %c = phi ptr [ %X, %BB0 ], [ %Y, %BB1 ]
271  ret ptr %c
272}
273
274define 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]]
287;
288entry:
289  %c = icmp eq ptr %A, null
290  br i1 %c, label %bb1, label %bb
291
292bb:
293  %C = load i32, ptr %B, align 1
294  br label %bb2
295
296bb1:
297  %D = load i32, ptr %A, align 1
298  br label %bb2
299
300bb2:
301  %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
302  ret i32 %E
303
304}
305
306define 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]]
319;
320entry:
321  %c = icmp eq ptr %A, null
322  br i1 %c, label %bb1, label %bb
323
324bb:
325  %C = load i32, ptr %B, align 16
326  br label %bb2
327
328bb1:
329  %D = load i32, ptr %A, align 32
330  br label %bb2
331
332bb2:
333  %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
334  ret i32 %E
335}
336
337
338; PR1777
339declare i1 @test11a()
340
341define 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]]
355;
356entry:
357  %a = alloca i32
358  %i = ptrtoint ptr %a to i64
359  %b = call i1 @test11a()
360  br i1 %b, label %one, label %two
361
362one:
363  %x = phi i64 [%i, %entry], [%y, %two]
364  %c = call i1 @test11a()
365  br i1 %c, label %two, label %end
366
367two:
368  %y = phi i64 [%i, %entry], [%x, %one]
369  %d = call i1 @test11a()
370  br i1 %d, label %one, label %end
371
372end:
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
380}
381
382
383define 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]]
394;
395entry:
396  %t41 = ptrtoint ptr %Ptr to i64
397  %t42 = zext i64 %t41 to i128
398  br i1 %cond, label %end, label %two
399
400two:
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
405
406end:
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]
411
412  %t2 = add i64 %t32, %t30
413  ret i64 %t2
414}
415
416declare void @test13f(double, i32)
417
418define 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
428;
429entry:
430  %t42 = zext i32 %V1 to i128
431  br i1 %cond, label %end, label %two
432
433two:
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
439
440end:
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
446
447  call void @test13f(double %t31, i32 %t32)
448  ret void
449}
450
451define 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]]
461;
462BB0:
463  %a = zext i320 %A to i640
464  %b = zext i320 %B to i640
465  br label %Loop
466
467Loop:
468  %C = phi i640 [ %a, %BB0 ], [ %b, %Loop ]
469  br i1 %b1, label %Loop, label %Exit
470
471Exit:           ; preds = %Loop
472  ret i640 %C
473}
474
475define 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]]
486;
487BB0:
488  %a = trunc i320 %pA to i160
489  %b = trunc i320 %pB to i160
490  br label %Loop
491
492Loop:
493  %C = phi i160 [ %a, %BB0 ], [ %b, %Loop ]
494  br i1 %b1, label %Loop, label %Exit
495
496Exit:           ; preds = %Loop
497  ret i160 %C
498}
499
500declare i64 @test15a(i64)
501
502define 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]]
518;
519entry:
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
524
525one:
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
532
533
534two:
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
541
542
543end:
544  %g = trunc i128 %y to i64
545  ret i64 %g
546}
547
548; PR6512 - Shouldn't merge loads from different addr spaces.
549define 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]]
574;
575nounwind {
576entry:
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
589
590return:                                           ; preds = %if.end
591  %t7 = load i32, ptr %retval                       ; <i32> [#uses=1]
592  ret i32 %t7
593
594if.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
598
599if.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
605
606if.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
612}
613
614; PR4413
615declare i32 @ext()
616define 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]]
626;
627entry:
628  br i1 %a, label %bb1, label %bb2
629
630bb1:        ; preds = %entry
631  %0 = tail call i32 @ext()        ; <i32> [#uses=1]
632  br label %bb2
633
634bb2:        ; 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
639}
640
641; Atomic and non-atomic loads should not be combined.
642define 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]]
653;
654entry:
655  %x = load i32, ptr %ptr, align 4
656  br i1 %c, label %if, label %end
657
658if:
659  %y = load atomic i32, ptr %atomic_ptr acquire, align 4
660  br label %end
661
662end:
663  %cond = phi i32 [ %x, %entry ], [ %y, %if ]
664  ret i32 %cond
665}
666
667define 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
676;
677  %zero = alloca i32
678  %one = alloca i32
679  br i1 %cond, label %true, label %false
680true:
681  br label %ret
682false:
683  br label %ret
684ret:
685  %ptr = phi ptr [ %zero, %true ] , [ %one, %false ]
686  %isnull = icmp eq ptr %ptr, null
687  ret i1 %isnull
688}
689
690define 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
699;
700  br i1 %cond, label %true, label %false
701true:
702  br label %ret
703false:
704  br label %ret
705ret:
706  %p = phi double [ %x, %true ], [ 0x7FF0000000000000, %false ]; RHS = +infty
707  %cmp = fcmp ule double %x, %p
708  ret i1 %cmp
709}
710
711define 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
720;
721  %a = alloca i32
722  %b = alloca i32
723  %c = alloca i32
724  br i1 %cond, label %true, label %false
725true:
726  br label %ret
727false:
728  br label %ret
729ret:
730  %p = phi ptr [ %a, %true ], [ %b, %false ]
731  %r = icmp eq ptr %p, %c
732  ret i1 %r
733}
734
735define 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
746;
747  %a = alloca i32
748  %b = alloca i32
749  %c = alloca i32
750  br i1 %c1, label %true, label %false
751true:
752  br label %loop
753false:
754  br label %loop
755loop:
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
759ret:
760  ret i1 %r
761}
762
763define 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
775;
776entry:
777  br label %loop
778loop:
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
784ret:
785  ret void
786}
787
788define 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]]
799;
800BB0:
801  br label %Loop
802
803Loop:           ; 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
809
810Exit:           ; preds = %Loop
811  %E = add i32 %B, 19
812  ret i32 %E
813}
814
815define 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]]
824;
825BB0:
826  %X = add nuw nsw i32 %A, 1
827  br i1 %cond, label %BB1, label %BB2
828
829BB1:
830  %Y = add nuw i32 %A, 1
831  br label %BB2
832
833BB2:
834  %C = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
835  ret i32 %C
836}
837
838; Same as test11, but used to be missed due to a bug.
839declare i1 @test25a()
840
841define 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]]
855;
856entry:
857  %a = alloca i32
858  %i = ptrtoint ptr %a to i64
859  %b = call i1 @test25a()
860  br i1 %b, label %one, label %two
861
862one:
863  %x = phi i64 [%y, %two], [%i, %entry]
864  %c = call i1 @test25a()
865  br i1 %c, label %two, label %end
866
867two:
868  %y = phi i64 [%x, %one], [%i, %entry]
869  %d = call i1 @test25a()
870  br i1 %d, label %one, label %end
871
872end:
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
880}
881
882; Same as above, but the input is also a phi
883define 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]]
904;
905entry:
906  br i1 %ci, label %then, label %else
907
908then:
909  br label %else
910
911else:
912  %i = phi i64 [ %ai, %entry ], [ %bi, %then ]
913  %b = call i1 @test25a()
914  br i1 %b, label %one, label %two
915
916one:
917  %x = phi i64 [%y, %two], [%i, %else]
918  %c = call i1 @test25a()
919  br i1 %c, label %two, label %end
920
921two:
922  %y = phi i64 [%x, %one], [%i, %else]
923  %d = call i1 @test25a()
924  br i1 %d, label %one, label %end
925
926end:
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
934}
935
936declare i1 @test26a()
937
938define 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]]
961;
962entry:
963  %a = alloca i32
964  %i = ptrtoint ptr %a to i64
965  %b = call i1 @test26a()
966  br label %one
967
968one:
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  ]
975
976two:
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  ]
983
984three:
985  %w = phi i64 [%y, %two], [%x, %one]
986  %e = call i1 @test26a()
987  br i1 %e, label %one, label %two
988
989end:
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
997}
998
999define 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
1005;
1006entry:
1007  br label %done
1008done:
1009  %y = phi i32 [ undef, %entry ]
1010  ret i32 %y
1011}
1012
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.
1016
1017define 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]]
1033;
1034entry:
1035  %conv = sext i8 %condition to i32
1036  switch i32 %conv, label %epilog [
1037  i32 0, label %sw1
1038  i32 1, label %sw2
1039  ]
1040
1041sw1:
1042  %cmp1 = icmp eq i8 %x1, %x2
1043  %frombool1 = zext i1 %cmp1 to i8
1044  br label %epilog
1045
1046sw2:
1047  %cmp2 = icmp sle i8 %x1, %x2
1048  %frombool2 = zext i1 %cmp2 to i8
1049  br label %epilog
1050
1051epilog:
1052  %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
1053  %tobool = icmp ne i8 %conditionMet, 0
1054  ret i1 %tobool
1055
1056}
1057
1058; Same as above (a phi with more than 2 operands), but no constants
1059
1060define 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]]
1076;
1077entry:
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  ]
1084
1085sw1:
1086  %cmp1 = icmp eq i8 %x1, %x2
1087  %frombool1 = zext i1 %cmp1 to i8
1088  br label %epilog
1089
1090sw2:
1091  %cmp2 = icmp sle i8 %x1, %x2
1092  %frombool2 = zext i1 %cmp2 to i8
1093  br label %epilog
1094
1095epilog:
1096  %conditionMet = phi i8 [ %frombool0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
1097  %tobool = icmp ne i8 %conditionMet, 0
1098  ret i1 %tobool
1099
1100}
1101
1102; Same as above (a phi with more than 2 operands), but two constants
1103
1104define 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]]
1119;
1120entry:
1121  %conv = sext i8 %condition to i32
1122  switch i32 %conv, label %epilog [
1123  i32 0, label %sw1
1124  i32 1, label %sw2
1125  ]
1126
1127sw1:
1128  %cmp1 = icmp eq i8 %x1, %x2
1129  %frombool1 = zext i1 %cmp1 to i8
1130  br label %epilog
1131
1132sw2:
1133  %cmp2 = icmp sle i8 %x1, %x2
1134  %frombool2 = zext i1 %cmp2 to i8
1135  br label %epilog
1136
1137epilog:
1138  %conditionMet = phi i8 [ 0, %entry ], [ 1, %sw2 ], [ %frombool1, %sw1 ]
1139  %tobool = icmp ne i8 %conditionMet, 0
1140  ret i1 %tobool
1141
1142}
1143
1144; Same as above (a phi with more than 2 operands), but two constants and two variables
1145
1146define 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]]
1165;
1166entry:
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  ]
1173
1174sw1:
1175  %cmp1 = icmp eq i8 %x1, %x2
1176  %frombool1 = zext i1 %cmp1 to i8
1177  br label %epilog
1178
1179sw2:
1180  %cmp2 = icmp sle i8 %x1, %x2
1181  %frombool2 = zext i1 %cmp2 to i8
1182  br label %epilog
1183
1184sw3:
1185  %cmp3 = icmp sge i8 %x1, %x2
1186  %frombool3 = zext i1 %cmp3 to i8
1187  br label %epilog
1188
1189epilog:
1190  %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ], [ 1, %sw3 ]
1191  %tobool = icmp ne i8 %conditionMet, 0
1192  ret i1 %tobool
1193
1194}
1195
1196define 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
1207;
1208entry:
1209  br i1 %c, label %if.then, label %if.else
1210
1211if.then:                                          ; preds = %entry
1212  br label %if.end
1213
1214if.else:                                          ; preds = %entry
1215  call void @dummy()
1216
1217  br label %if.end
1218
1219if.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
1224}
1225
1226define 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
1237;
1238entry:
1239  br i1 %c, label %if.then, label %if.else
1240
1241if.then:                                          ; preds = %entry
1242  br label %if.end
1243
1244if.else:                                          ; preds = %entry
1245  call void @dummy()
1246
1247  br label %if.end
1248
1249if.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
1253}
1254
1255declare void @dummy()
1256
1257define 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]]
1268;
1269entry:
1270  %tobool = icmp slt  i32 %n, %s
1271  br i1 %tobool, label %if.end, label %if.then
1272
1273if.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
1278
1279if.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
1283}
1284
1285define 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]]
1296;
1297entry:
1298  %tobool = icmp slt  i32 %n, %s
1299  br i1 %tobool, label %if.end, label %if.then
1300
1301if.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
1306
1307if.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
1311}
1312
1313define 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]]
1326;
1327entry:
1328  %tobool = icmp slt  i32 %n, %s
1329  br i1 %tobool, label %if.then, label %if.end
1330
1331if.then:
1332  %tobool2 = icmp slt  i32 %n, %s
1333  br i1 %tobool2, label %if.else, label %if.end
1334
1335if.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
1340
1341if.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
1345}
1346
1347define 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]]
1360;
1361entry:
1362  %tobool = icmp slt  i32 %n, %s
1363  br i1 %tobool, label %if.then, label %if.end
1364
1365if.then:
1366  %tobool2 = icmp slt  i32 %n, %s
1367  br i1 %tobool2, label %if.else, label %if.end
1368
1369if.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
1374
1375if.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
1379}
1380
1381define 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]]
1393;
1394entry:
1395  %tobool = icmp slt  i32 %n, %s
1396  br i1 %tobool, label %if.end, label %if.then
1397
1398if.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
1403
1404if.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
1409}
1410
1411define 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]]
1423;
1424entry:
1425  %tobool = icmp slt  i32 %n, %s
1426  br i1 %tobool, label %if.end, label %if.then
1427
1428if.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
1433
1434if.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
1439}
1440
1441define 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]]
1453;
1454entry:
1455  %tobool = icmp slt  i32 %n, %s
1456  br i1 %tobool, label %if.end, label %if.then
1457
1458if.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
1463
1464if.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
1469}
1470
1471define 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]]
1483;
1484entry:
1485  %tobool = icmp slt  i32 %n, %s
1486  br i1 %tobool, label %if.end, label %if.then
1487
1488if.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
1493
1494if.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
1499}
1500
1501define 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]]
1513;
1514entry:
1515  %tobool = icmp slt  i32 %n, %s
1516  br i1 %tobool, label %if.end, label %if.then
1517
1518if.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
1523
1524if.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
1529}
1530
1531define 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]]
1549;
1550entry:
1551  %tobool = icmp slt  i32 %n, %s
1552  br i1 %tobool, label %if.end, label %if.then
1553
1554if.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
1559
1560if.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
1565
1566next:
1567  %bool2 = icmp eq i32 %phi, 0
1568  br label %cleanup
1569
1570cleanup:
1571  %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1572  ret i1  %final
1573}
1574
1575define 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]]
1593;
1594entry:
1595  %tobool = icmp slt  i32 %n, %s
1596  br i1 %tobool, label %if.end, label %if.then
1597
1598if.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
1603
1604if.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
1609
1610next:
1611  %bool2 = icmp ne i32 %phi, 0
1612  br label %cleanup
1613
1614cleanup:
1615  %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1616  ret i1  %final
1617}
1618
1619define 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]]
1640;
1641entry:
1642  %tobool = icmp slt  i32 %n, %s
1643  br i1 %tobool, label %if.end, label %if.then
1644
1645if.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
1650
1651if.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
1656
1657next:
1658  %bool2 = icmp eq i32 %phi, 0
1659  br label %cleanup
1660
1661cleanup:
1662  %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1663  ret i1  %final
1664}
1665
1666define 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]]
1687;
1688entry:
1689  %tobool = icmp slt  i32 %n, %s
1690  br i1 %tobool, label %if.end, label %if.then
1691
1692if.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
1697
1698if.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
1703
1704next:
1705  %bool2 = icmp ne i32 %phi, 0
1706  br label %cleanup
1707
1708cleanup:
1709  %final =  phi i1 [ %cmp1,  %if.end ], [ %bool2, %next ]
1710  ret i1  %final
1711}
1712
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).
1716
1717define 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
1730;
1731entry:
1732  br label %for.cond
1733
1734for.cond:
1735  %p = phi double [ %conv, %g.exit ], [ undef, %entry ]
1736  br i1 %cond, label %for.end, label %for.body
1737
1738for.body:
1739  %conv = sitofp i16 %x to double
1740  unreachable
1741
1742g.exit:
1743  br label %for.cond
1744
1745for.end:
1746  store double %p, ptr undef
1747  ret void
1748}
1749
1750define 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 nuw 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]]
1768;
1769start:
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
1773
1774loop:
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
1785
1786exit:
1787  %res = phi i1 [ true, %start ], [ %and, %loop ]
1788  ret i1 %res
1789}
1790
1791declare void @use(i32)
1792declare i1 @get.i1()
1793
1794define 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]]
1804;
1805entry:
1806  br label %loop
1807
1808loop:
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
1814}
1815
1816define 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]]
1830;
1831entry:
1832  br label %loop
1833
1834loop:
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
1839
1840loop.latch:
1841  %c2 = call i1 @get.i1()
1842  br i1 %c2, label %exit, label %loop
1843
1844exit:
1845  ret i32 %or
1846}
1847
1848; Caused an infinite loop with D134954.
1849define 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]]
1863;
1864entry:
1865  br i1 %c, label %if, label %else
1866
1867if:
1868  %arg.ptr2.val = load i64, ptr %arg.ptr2, align 8
1869  br label %join
1870
1871else:
1872  %arg.int.ptr = ptrtoint ptr %arg.ptr to i64
1873  br label %join
1874
1875join:
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
1880}
1881
1882define 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 nuw 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
1903;
1904entry:
1905  %ptr.end = getelementptr inbounds i8, ptr %ptr.base, i64 %n
1906  br label %loop
1907
1908loop:
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
1914
1915if:
1916  %sel = select i1 %phi, i32 117, i32 100
1917  call void @use(i32 %sel)
1918  br label %latch
1919
1920latch:
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
1924
1925exit:
1926  ret void
1927}
1928
1929define 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]]
1938;
1939entry:
1940  br i1 %c, label %if.then, label %if.end
1941
1942if.then:
1943  br label %if.end
1944
1945if.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
1950}
1951
1952define 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]]
1963;
1964entry:
1965  br i1 %c, label %if.then, label %if.end
1966
1967if.then:
1968  br label %if.end
1969
1970if.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
1975}
1976
1977define 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]]
1986;
1987entry:
1988  br i1 %c, label %if.then, label %if.end
1989
1990if.then:
1991  br label %if.end
1992
1993if.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
1998}
1999
2000define 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]]
2009;
2010entry:
2011  br i1 %c, label %if.then, label %if.end
2012
2013if.then:
2014  br label %if.end
2015
2016if.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
2021}
2022
2023define 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]]
2032;
2033entry:
2034  br i1 %c, label %if.then, label %if.end
2035
2036if.then:
2037  br label %if.end
2038
2039if.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
2044}
2045
2046define 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]]
2055;
2056entry:
2057  br i1 %c, label %if.then, label %if.end
2058
2059if.then:
2060  br label %if.end
2061
2062if.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
2067}
2068
2069define 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]]
2080;
2081entry:
2082  br i1 %c, label %if.then, label %if.end
2083
2084if.then:
2085  br label %if.end
2086
2087if.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
2092}
2093
2094define 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 nuw 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]]
2107;
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
2113
2114sub_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
2119
2120join:
2121  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2122  %cmp = icmp eq i32 %8, 0
2123  ret i1 %cmp
2124}
2125
2126define 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 nuw 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 nuw 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]]
2144;
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
2150
2151sub_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
2158
2159sub_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
2164
2165join:
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
2169}
2170
2171define 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 nuw 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]]
2184;
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
2190
2191sub_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
2196
2197join:
2198  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2199  %cmp = icmp eq i32 %8, 0
2200  ret i1 %cmp
2201}
2202
2203
2204define 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 nuw 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 nuw 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]]
2222;
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
2228
2229sub_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
2236
2237sub_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
2242
2243join:
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
2247}
2248
2249define 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 nuw 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]]
2262;
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
2268
2269sub_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
2274
2275join:
2276  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2277  %cmp = icmp ne i32 %8, 0
2278  ret i1 %cmp
2279}
2280
2281define 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 nuw 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 nuw 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]]
2299;
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
2305
2306sub_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
2313
2314sub_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
2319
2320join:
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
2324}
2325
2326define 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 nuw 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]]
2339;
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
2345
2346sub_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
2351
2352join:
2353  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2354  %cmp = icmp ne i32 %8, 0
2355  ret i1 %cmp
2356}
2357
2358define 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 nuw 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 nuw 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]]
2376;
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
2382
2383sub_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
2390
2391sub_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
2396
2397join:
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
2401}
2402
2403define 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 nuw 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]]
2416;
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
2422
2423sub_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
2428
2429join:
2430  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2431  %cmp = icmp sgt i32 %8, 0
2432  ret i1 %cmp
2433}
2434
2435define 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 nuw 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 nuw 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]]
2453;
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
2459
2460sub_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
2467
2468sub_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
2473
2474join:
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
2478}
2479
2480define 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 nuw 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]]
2496;
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
2502
2503sub_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
2508
2509join:
2510  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2511  %cmp = icmp sgt i32 %8, 0
2512  ret i1 %cmp
2513}
2514
2515define 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 nuw 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 nuw 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]]
2538;
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
2544
2545sub_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
2552
2553sub_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
2558
2559join:
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
2563}
2564
2565define 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
2574;
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
2580
2581sub_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
2586
2587join:
2588  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2589  %cmp = icmp slt i32 %8, 0
2590  ret i1 %cmp
2591}
2592
2593define 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 nuw 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
2607;
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
2613
2614sub_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
2621
2622sub_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
2627
2628join:
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
2632}
2633
2634define 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 nuw 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]]
2650;
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
2656
2657sub_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
2662
2663join:
2664  %8 = phi i32 [ %3, %0 ], [ %7, %sub_is_zero ]
2665  %cmp = icmp slt i32 %8, 0
2666  ret i1 %cmp
2667}
2668
2669define 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 nuw 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 nuw 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]]
2692;
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
2698
2699sub_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
2706
2707sub_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
2712
2713join:
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
2717}
2718
2719define 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]]
2731;
2732  br label %loop
2733
2734loop:
2735  br i1 %c, label %if, label %loop.latch
2736
2737if:
2738  br label %loop.latch
2739
2740loop.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
2745}
2746
2747define 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
2767;
2768entry:
2769  br label %BB0
2770
2771BB0:                                              ; 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  ]
2778
2779BB1:                                              ; preds = %BB0
2780  br i1 %cond, label %BB2, label %BB4
2781
2782BB2:                                              ; preds = %BB1, %BB0
2783  %b = phi float [ 2.0, %BB0 ], [ %a, %BB1 ]
2784  br i1 %cond, label %BB3, label %BB4
2785
2786BB3:                                              ; preds = %BB2, %BB0
2787  %c = phi float [ 3.0, %BB0 ], [ %b, %BB2 ]
2788  br label %BB4
2789
2790BB4:                                             ; 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
2793
2794BB5:                                             ; preds = %BB4
2795  ret void
2796}
2797
2798define 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
2810;
2811entry:
2812  %add.ptr = getelementptr i8, ptr %ptr, i64 1
2813  br label %for.cond
2814
2815for.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
2821
2822exit:                                             ; preds = %for.cond
2823  ret i64 0
2824}
2825
2826define i1 @test_zext_icmp_eq_0(i1 %a, i1 %b, i32 %c) {
2827; CHECK-LABEL: @test_zext_icmp_eq_0(
2828; CHECK-NEXT:  entry:
2829; CHECK-NEXT:    br i1 [[A:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2830; CHECK:       if:
2831; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[B:%.*]], true
2832; CHECK-NEXT:    br label [[JOIN:%.*]]
2833; CHECK:       else:
2834; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[C:%.*]], 0
2835; CHECK-NEXT:    br label [[JOIN]]
2836; CHECK:       join:
2837; CHECK-NEXT:    [[CMP:%.*]] = phi i1 [ [[TMP0]], [[IF]] ], [ [[TMP1]], [[ELSE]] ]
2838; CHECK-NEXT:    ret i1 [[CMP]]
2839;
2840entry:
2841  br i1 %a, label %if, label %else
2842
2843if:
2844  %b.ext = zext i1 %b to i32
2845  br label %join
2846
2847else:
2848  br label %join
2849
2850join:
2851  %phi = phi i32 [ %b.ext, %if ], [ %c, %else ]
2852  %cmp = icmp eq i32 %phi, 0
2853  ret i1 %cmp
2854}
2855
2856define i1 @test_zext_icmp_ne_0(i1 %a, i1 %b, i32 %c) {
2857; CHECK-LABEL: @test_zext_icmp_ne_0(
2858; CHECK-NEXT:  entry:
2859; CHECK-NEXT:    br i1 [[A:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2860; CHECK:       if:
2861; CHECK-NEXT:    br label [[JOIN:%.*]]
2862; CHECK:       else:
2863; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i32 [[C:%.*]], 0
2864; CHECK-NEXT:    br label [[JOIN]]
2865; CHECK:       join:
2866; CHECK-NEXT:    [[PHI:%.*]] = phi i1 [ [[B:%.*]], [[IF]] ], [ [[TMP0]], [[ELSE]] ]
2867; CHECK-NEXT:    ret i1 [[PHI]]
2868;
2869entry:
2870  br i1 %a, label %if, label %else
2871
2872if:
2873  %b.ext = zext i1 %b to i32
2874  br label %join
2875
2876else:
2877  br label %join
2878
2879join:
2880  %phi = phi i32 [ %b.ext, %if ], [ %c, %else ]
2881  %cmp = icmp ne i32 %phi, 0
2882  ret i1 %cmp
2883}
2884
2885define i1 @test_zext_icmp_eq_1(i1 %a, i1 %b, i32 %c) {
2886; CHECK-LABEL: @test_zext_icmp_eq_1(
2887; CHECK-NEXT:  entry:
2888; CHECK-NEXT:    br i1 [[A:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2889; CHECK:       if:
2890; CHECK-NEXT:    br label [[JOIN:%.*]]
2891; CHECK:       else:
2892; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[C:%.*]], 1
2893; CHECK-NEXT:    br label [[JOIN]]
2894; CHECK:       join:
2895; CHECK-NEXT:    [[PHI:%.*]] = phi i1 [ [[B:%.*]], [[IF]] ], [ [[TMP0]], [[ELSE]] ]
2896; CHECK-NEXT:    ret i1 [[PHI]]
2897;
2898entry:
2899  br i1 %a, label %if, label %else
2900
2901if:
2902  %b.ext = zext i1 %b to i32
2903  br label %join
2904
2905else:
2906  br label %join
2907
2908join:
2909  %phi = phi i32 [ %b.ext, %if ], [ %c, %else ]
2910  %cmp = icmp eq i32 %phi, 1
2911  ret i1 %cmp
2912}
2913
2914define i1 @test_zext_icmp_eq_0_loop(i1 %c, i1 %b) {
2915; CHECK-LABEL: @test_zext_icmp_eq_0_loop(
2916; CHECK-NEXT:  entry:
2917; CHECK-NEXT:    br label [[LOOP:%.*]]
2918; CHECK:       loop:
2919; CHECK-NEXT:    [[X:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
2920; CHECK-NEXT:    [[Y:%.*]] = and i1 [[X]], [[B:%.*]]
2921; CHECK-NEXT:    [[TMP0]] = xor i1 [[Y]], true
2922; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]]
2923; CHECK:       exit:
2924; CHECK-NEXT:    ret i1 [[X]]
2925;
2926entry:
2927  br label %loop
2928
2929loop:
2930  %phi = phi i32 [ 1, %entry ], [ %ext, %loop ]
2931  %x = icmp eq i32 %phi, 0
2932  %y = and i1 %x, %b
2933  %ext = zext i1 %y to i32
2934  br i1 %c, label %loop, label %exit
2935
2936exit:
2937  ret i1 %x
2938}
2939
2940define i1 @test_zext_icmp_eq_0_multi_use(i1 %a, i1 %b, i32 %c) {
2941; CHECK-LABEL: @test_zext_icmp_eq_0_multi_use(
2942; CHECK-NEXT:  entry:
2943; CHECK-NEXT:    br i1 [[A:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2944; CHECK:       if:
2945; CHECK-NEXT:    [[B_EXT:%.*]] = zext i1 [[B:%.*]] to i32
2946; CHECK-NEXT:    call void @use(i32 [[B_EXT]])
2947; CHECK-NEXT:    br label [[JOIN:%.*]]
2948; CHECK:       else:
2949; CHECK-NEXT:    br label [[JOIN]]
2950; CHECK:       join:
2951; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[B_EXT]], [[IF]] ], [ [[C:%.*]], [[ELSE]] ]
2952; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[PHI]], 0
2953; CHECK-NEXT:    ret i1 [[CMP]]
2954;
2955entry:
2956  br i1 %a, label %if, label %else
2957
2958if:
2959  %b.ext = zext i1 %b to i32
2960  call void @use(i32 %b.ext)
2961  br label %join
2962
2963else:
2964  br label %join
2965
2966join:
2967  %phi = phi i32 [ %b.ext, %if ], [ %c, %else ]
2968  %cmp = icmp eq i32 %phi, 0
2969  ret i1 %cmp
2970}
2971
2972define i1 @test_zext_icmp_eq_0_not_bool(i1 %a, i2 %b, i32 %c) {
2973; CHECK-LABEL: @test_zext_icmp_eq_0_not_bool(
2974; CHECK-NEXT:  entry:
2975; CHECK-NEXT:    br i1 [[A:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2976; CHECK:       if:
2977; CHECK-NEXT:    [[B_EXT:%.*]] = zext i2 [[B:%.*]] to i32
2978; CHECK-NEXT:    br label [[JOIN:%.*]]
2979; CHECK:       else:
2980; CHECK-NEXT:    br label [[JOIN]]
2981; CHECK:       join:
2982; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[B_EXT]], [[IF]] ], [ [[C:%.*]], [[ELSE]] ]
2983; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[PHI]], 0
2984; CHECK-NEXT:    ret i1 [[CMP]]
2985;
2986entry:
2987  br i1 %a, label %if, label %else
2988
2989if:
2990  %b.ext = zext i2 %b to i32
2991  br label %join
2992
2993else:
2994  br label %join
2995
2996join:
2997  %phi = phi i32 [ %b.ext, %if ], [ %c, %else ]
2998  %cmp = icmp eq i32 %phi, 0
2999  ret i1 %cmp
3000}
3001