Revert "Reapply [InstCombine] Switch foldOpIntoPhi() to use InstSimplify"
[llvm-project.git] / llvm / test / Transforms / InstCombine / phi.ll
blob2d7331054ce90817abf9908294bdddc18f59c649
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128:n8:16:32:64"
6 define i32 @test1(i32 %A, i1 %b) {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:  BB0:
9 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
10 ; CHECK:       BB1:
11 ; CHECK-NEXT:    ret i32 [[A:%.*]]
12 ; CHECK:       BB2:
13 ; CHECK-NEXT:    ret i32 [[A]]
15 BB0:
16   br i1 %b, label %BB1, label %BB2
18 BB1:
19   ; Combine away one argument PHI nodes
20   %B = phi i32 [ %A, %BB0 ]
21   ret i32 %B
23 BB2:
24   ret i32 %A
27 define i32 @test2(i32 %A, i1 %b) {
28 ; CHECK-LABEL: @test2(
29 ; CHECK-NEXT:  BB0:
30 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
31 ; CHECK:       BB1:
32 ; CHECK-NEXT:    br label [[BB2]]
33 ; CHECK:       BB2:
34 ; CHECK-NEXT:    ret i32 [[A:%.*]]
36 BB0:
37   br i1 %b, label %BB1, label %BB2
39 BB1:
40   br label %BB2
42 BB2:
43   ; Combine away PHI nodes with same values
44   %B = phi i32 [ %A, %BB0 ], [ %A, %BB1 ]
45   ret i32 %B
48 define i32 @test3(i32 %A, i1 %b) {
49 ; CHECK-LABEL: @test3(
50 ; CHECK-NEXT:  BB0:
51 ; CHECK-NEXT:    br label [[LOOP:%.*]]
52 ; CHECK:       Loop:
53 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]]
54 ; CHECK:       Exit:
55 ; CHECK-NEXT:    ret i32 [[A:%.*]]
57 BB0:
58   br label %Loop
60 Loop:
61   ; PHI has same value always.
62   %B = phi i32 [ %A, %BB0 ], [ %B, %Loop ]
63   br i1 %b, label %Loop, label %Exit
65 Exit:
66   ret i32 %B
69 define i32 @test4(i1 %b) {
70 ; CHECK-LABEL: @test4(
71 ; CHECK-NEXT:  BB0:
72 ; CHECK-NEXT:    ret i32 7
73 ; CHECK:       Loop:
74 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[L2:%.*]], label [[LOOP:%.*]]
75 ; CHECK:       L2:
76 ; CHECK-NEXT:    br label [[LOOP]]
78 BB0:
79   ; Loop is unreachable
80   ret i32 7
82 Loop:           ; preds = %L2, %Loop
83   ; PHI has same value always.
84   %B = phi i32 [ %B, %L2 ], [ %B, %Loop ]
85   br i1 %b, label %L2, label %Loop
87 L2:             ; preds = %Loop
88   br label %Loop
91 define i32 @test5(i32 %A, i1 %b) {
92 ; CHECK-LABEL: @test5(
93 ; CHECK-NEXT:  BB0:
94 ; CHECK-NEXT:    br label [[LOOP:%.*]]
95 ; CHECK:       Loop:
96 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]]
97 ; CHECK:       Exit:
98 ; CHECK-NEXT:    ret i32 [[A:%.*]]
100 BB0:
101   br label %Loop
103 Loop:           ; preds = %Loop, %BB0
104   ; PHI has same value always.
105   %B = phi i32 [ %A, %BB0 ], [ undef, %Loop ]
106   br i1 %b, label %Loop, label %Exit
108 Exit:           ; preds = %Loop
109   ret i32 %B
112 define i32 @test6(i16 %A, i1 %b) {
113 ; CHECK-LABEL: @test6(
114 ; CHECK-NEXT:  BB0:
115 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
116 ; CHECK:       BB1:
117 ; CHECK-NEXT:    br label [[BB2]]
118 ; CHECK:       BB2:
119 ; CHECK-NEXT:    [[B:%.*]] = zext i16 [[A:%.*]] to i32
120 ; CHECK-NEXT:    ret i32 [[B]]
122 BB0:
123   %X = zext i16 %A to i32
124   br i1 %b, label %BB1, label %BB2
126 BB1:
127   %Y = zext i16 %A to i32
128   br label %BB2
130 BB2:
131   ;; Suck casts into phi
132   %B = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
133   ret i32 %B
136 define i32 @test7(i32 %A, i1 %b) {
137 ; CHECK-LABEL: @test7(
138 ; CHECK-NEXT:  BB0:
139 ; CHECK-NEXT:    br label [[LOOP:%.*]]
140 ; CHECK:       Loop:
141 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]]
142 ; CHECK:       Exit:
143 ; CHECK-NEXT:    ret i32 0
145 BB0:
146   br label %Loop
148 Loop:           ; preds = %Loop, %BB0
149   ; PHI is dead.
150   %B = phi i32 [ %A, %BB0 ], [ %C, %Loop ]
151   %C = add i32 %B, 123
152   br i1 %b, label %Loop, label %Exit
154 Exit:           ; preds = %Loop
155   ret i32 0
158 define ptr @test8(ptr %A, i1 %b) {
159 ; CHECK-LABEL: @test8(
160 ; CHECK-NEXT:  BB0:
161 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
162 ; CHECK:       BB1:
163 ; CHECK-NEXT:    br label [[BB2]]
164 ; CHECK:       BB2:
165 ; CHECK-NEXT:    [[B:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 0, i32 1
166 ; CHECK-NEXT:    ret ptr [[B]]
168 BB0:
169   %X = getelementptr inbounds { i32, i32 }, ptr %A, i32 0, i32 1
170   br i1 %b, label %BB1, label %BB2
172 BB1:
173   %Y = getelementptr { i32, i32 }, ptr %A, i32 0, i32 1
174   br label %BB2
176 BB2:
177   ;; Suck GEPs into phi
178   %B = phi ptr [ %X, %BB0 ], [ %Y, %BB1 ]
179   ret ptr %B
182 define i32 @test9(ptr %A, ptr %B) {
183 ; CHECK-LABEL: @test9(
184 ; CHECK-NEXT:  entry:
185 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[A:%.*]], null
186 ; CHECK-NEXT:    br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]]
187 ; CHECK:       bb:
188 ; CHECK-NEXT:    br label [[BB2:%.*]]
189 ; CHECK:       bb1:
190 ; CHECK-NEXT:    br label [[BB2]]
191 ; CHECK:       bb2:
192 ; CHECK-NEXT:    [[E_IN:%.*]] = phi ptr [ [[B:%.*]], [[BB]] ], [ [[A]], [[BB1]] ]
193 ; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[E_IN]], align 1
194 ; CHECK-NEXT:    ret i32 [[E]]
196 entry:
197   %c = icmp eq ptr %A, null
198   br i1 %c, label %bb1, label %bb
201   %C = load i32, ptr %B, align 1
202   br label %bb2
204 bb1:
205   %D = load i32, ptr %A, align 1
206   br label %bb2
208 bb2:
209   %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
210   ret i32 %E
214 define i32 @test10(ptr %A, ptr %B) {
215 ; CHECK-LABEL: @test10(
216 ; CHECK-NEXT:  entry:
217 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[A:%.*]], null
218 ; CHECK-NEXT:    br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]]
219 ; CHECK:       bb:
220 ; CHECK-NEXT:    br label [[BB2:%.*]]
221 ; CHECK:       bb1:
222 ; CHECK-NEXT:    br label [[BB2]]
223 ; CHECK:       bb2:
224 ; CHECK-NEXT:    [[E_IN:%.*]] = phi ptr [ [[B:%.*]], [[BB]] ], [ [[A]], [[BB1]] ]
225 ; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[E_IN]], align 16
226 ; CHECK-NEXT:    ret i32 [[E]]
228 entry:
229   %c = icmp eq ptr %A, null
230   br i1 %c, label %bb1, label %bb
233   %C = load i32, ptr %B, align 16
234   br label %bb2
236 bb1:
237   %D = load i32, ptr %A, align 32
238   br label %bb2
240 bb2:
241   %E = phi i32 [ %C, %bb ], [ %D, %bb1 ]
242   ret i32 %E
246 ; PR1777
247 declare i1 @test11a()
249 define i1 @test11() {
250 ; CHECK-LABEL: @test11(
251 ; CHECK-NEXT:  entry:
252 ; CHECK-NEXT:    [[B:%.*]] = call i1 @test11a()
253 ; CHECK-NEXT:    br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
254 ; CHECK:       one:
255 ; CHECK-NEXT:    [[C:%.*]] = call i1 @test11a()
256 ; CHECK-NEXT:    br i1 [[C]], label [[TWO]], label [[END:%.*]]
257 ; CHECK:       two:
258 ; CHECK-NEXT:    [[D:%.*]] = call i1 @test11a()
259 ; CHECK-NEXT:    br i1 [[D]], label [[ONE]], label [[END]]
260 ; CHECK:       end:
261 ; CHECK-NEXT:    [[Z:%.*]] = call i1 @test11a()
262 ; CHECK-NEXT:    ret i1 [[Z]]
264 entry:
265   %a = alloca i32
266   %i = ptrtoint ptr %a to i64
267   %b = call i1 @test11a()
268   br i1 %b, label %one, label %two
270 one:
271   %x = phi i64 [%i, %entry], [%y, %two]
272   %c = call i1 @test11a()
273   br i1 %c, label %two, label %end
275 two:
276   %y = phi i64 [%i, %entry], [%x, %one]
277   %d = call i1 @test11a()
278   br i1 %d, label %one, label %end
280 end:
281   %f = phi i64 [ %x, %one], [%y, %two]
282   ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
283   ; even though %f must equal %i at this point
284   %g = inttoptr i64 %f to ptr
285   store i32 10, ptr %g
286   %z = call i1 @test11a()
287   ret i1 %z
291 define i64 @test12(i1 %cond, ptr %Ptr, i64 %Val) {
292 ; CHECK-LABEL: @test12(
293 ; CHECK-NEXT:  entry:
294 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]]
295 ; CHECK:       two:
296 ; CHECK-NEXT:    br label [[END]]
297 ; CHECK:       end:
298 ; CHECK-NEXT:    [[T869_0_OFF64:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[VAL:%.*]], [[TWO]] ]
299 ; CHECK-NEXT:    [[T41:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
300 ; CHECK-NEXT:    [[T2:%.*]] = add i64 [[T869_0_OFF64]], [[T41]]
301 ; CHECK-NEXT:    ret i64 [[T2]]
303 entry:
304   %t41 = ptrtoint ptr %Ptr to i64
305   %t42 = zext i64 %t41 to i128
306   br i1 %cond, label %end, label %two
308 two:
309   %t36 = zext i64 %Val to i128            ; <i128> [#uses=1]
310   %t37 = shl i128 %t36, 64                    ; <i128> [#uses=1]
311   %ins39 = or i128 %t42, %t37                 ; <i128> [#uses=1]
312   br label %end
314 end:
315   %t869.0 = phi i128 [ %t42, %entry ], [ %ins39, %two ]
316   %t32 = trunc i128 %t869.0 to i64            ; <i64> [#uses=1]
317   %t29 = lshr i128 %t869.0, 64                ; <i128> [#uses=1]
318   %t30 = trunc i128 %t29 to i64               ; <i64> [#uses=1]
320   %t2 = add i64 %t32, %t30
321   ret i64 %t2
324 declare void @test13f(double, i32)
326 define void @test13(i1 %cond, i32 %V1, double %Vald) {
327 ; CHECK-LABEL: @test13(
328 ; CHECK-NEXT:  entry:
329 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]]
330 ; CHECK:       two:
331 ; CHECK-NEXT:    br label [[END]]
332 ; CHECK:       end:
333 ; CHECK-NEXT:    [[TMP0:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[VALD:%.*]], [[TWO]] ]
334 ; CHECK-NEXT:    call void @test13f(double [[TMP0]], i32 [[V1:%.*]])
335 ; CHECK-NEXT:    ret void
337 entry:
338   %t42 = zext i32 %V1 to i128
339   br i1 %cond, label %end, label %two
341 two:
342   %Val = bitcast double %Vald to i64
343   %t36 = zext i64 %Val to i128            ; <i128> [#uses=1]
344   %t37 = shl i128 %t36, 64                    ; <i128> [#uses=1]
345   %ins39 = or i128 %t42, %t37                 ; <i128> [#uses=1]
346   br label %end
348 end:
349   %t869.0 = phi i128 [ %t42, %entry ], [ %ins39, %two ]
350   %t32 = trunc i128 %t869.0 to i32
351   %t29 = lshr i128 %t869.0, 64                ; <i128> [#uses=1]
352   %t30 = trunc i128 %t29 to i64               ; <i64> [#uses=1]
353   %t31 = bitcast i64 %t30 to double
355   call void @test13f(double %t31, i32 %t32)
356   ret void
359 define i640 @test14a(i320 %A, i320 %B, i1 %b1) {
360 ; CHECK-LABEL: @test14a(
361 ; CHECK-NEXT:  BB0:
362 ; CHECK-NEXT:    br label [[LOOP:%.*]]
363 ; CHECK:       Loop:
364 ; CHECK-NEXT:    [[C_IN:%.*]] = phi i320 [ [[A:%.*]], [[BB0:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
365 ; CHECK-NEXT:    br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
366 ; CHECK:       Exit:
367 ; CHECK-NEXT:    [[C:%.*]] = zext i320 [[C_IN]] to i640
368 ; CHECK-NEXT:    ret i640 [[C]]
370 BB0:
371   %a = zext i320 %A to i640
372   %b = zext i320 %B to i640
373   br label %Loop
375 Loop:
376   %C = phi i640 [ %a, %BB0 ], [ %b, %Loop ]
377   br i1 %b1, label %Loop, label %Exit
379 Exit:           ; preds = %Loop
380   ret i640 %C
383 define i160 @test14b(i320 %pA, i320 %pB, i1 %b1) {
384 ; CHECK-LABEL: @test14b(
385 ; CHECK-NEXT:  BB0:
386 ; CHECK-NEXT:    [[A:%.*]] = trunc i320 [[PA:%.*]] to i160
387 ; CHECK-NEXT:    [[B:%.*]] = trunc i320 [[PB:%.*]] to i160
388 ; CHECK-NEXT:    br label [[LOOP:%.*]]
389 ; CHECK:       Loop:
390 ; CHECK-NEXT:    [[C:%.*]] = phi i160 [ [[A]], [[BB0:%.*]] ], [ [[B]], [[LOOP]] ]
391 ; CHECK-NEXT:    br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
392 ; CHECK:       Exit:
393 ; CHECK-NEXT:    ret i160 [[C]]
395 BB0:
396   %a = trunc i320 %pA to i160
397   %b = trunc i320 %pB to i160
398   br label %Loop
400 Loop:
401   %C = phi i160 [ %a, %BB0 ], [ %b, %Loop ]
402   br i1 %b1, label %Loop, label %Exit
404 Exit:           ; preds = %Loop
405   ret i160 %C
408 declare i64 @test15a(i64)
410 define i64 @test15b(i64 %A, i1 %b) {
411 ; CHECK-LABEL: @test15b(
412 ; CHECK-NEXT:  entry:
413 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[ONE:%.*]], label [[TWO:%.*]]
414 ; CHECK:       one:
415 ; CHECK-NEXT:    [[X_OFF64:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[Y_OFF64:%.*]], [[TWO]] ]
416 ; CHECK-NEXT:    [[C:%.*]] = call i64 @test15a(i64 [[X_OFF64]])
417 ; CHECK-NEXT:    br label [[TWO]]
418 ; CHECK:       two:
419 ; CHECK-NEXT:    [[Y_OFF0:%.*]] = phi i64 [ [[A]], [[ENTRY]] ], [ [[C]], [[ONE]] ]
420 ; CHECK-NEXT:    [[Y_OFF64]] = phi i64 [ [[A]], [[ENTRY]] ], [ 0, [[ONE]] ]
421 ; CHECK-NEXT:    [[D:%.*]] = call i64 @test15a(i64 [[Y_OFF64]])
422 ; CHECK-NEXT:    [[TMP0:%.*]] = and i64 [[D]], 1
423 ; CHECK-NEXT:    [[D1_NOT:%.*]] = icmp eq i64 [[TMP0]], 0
424 ; CHECK-NEXT:    br i1 [[D1_NOT]], label [[END:%.*]], label [[ONE]]
425 ; CHECK:       end:
426 ; CHECK-NEXT:    ret i64 [[Y_OFF0]]
428 entry:
429   %i0 = zext i64 %A to i128
430   %i1 = shl i128 %i0, 64
431   %i = or i128 %i1, %i0
432   br i1 %b, label %one, label %two
434 one:
435   %x = phi i128 [%i, %entry], [%y, %two]
436   %x1 = lshr i128 %x, 64
437   %x2 = trunc i128 %x1 to i64
438   %c = call i64 @test15a(i64 %x2)
439   %c1 = zext i64 %c to i128
440   br label %two
443 two:
444   %y = phi i128 [%i, %entry], [%c1, %one]
445   %y1 = lshr i128 %y, 64
446   %y2 = trunc i128 %y1 to i64
447   %d = call i64 @test15a(i64 %y2)
448   %d1 = trunc i64 %d to i1
449   br i1 %d1, label %one, label %end
452 end:
453   %g = trunc i128 %y to i64
454   ret i64 %g
457 ; PR6512 - Shouldn't merge loads from different addr spaces.
458 define i32 @test16(ptr addrspace(1) %pointer1, i32 %flag, ptr %pointer2)
459 ; CHECK-LABEL: @test16(
460 ; CHECK-NEXT:  entry:
461 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
462 ; CHECK-NEXT:    [[POINTER1_ADDR:%.*]] = alloca ptr addrspace(1), align 8
463 ; CHECK-NEXT:    [[POINTER2_ADDR:%.*]] = alloca ptr, align 8
464 ; CHECK-NEXT:    store ptr addrspace(1) [[POINTER1:%.*]], ptr [[POINTER1_ADDR]], align 8
465 ; CHECK-NEXT:    store ptr [[POINTER2:%.*]], ptr [[POINTER2_ADDR]], align 8
466 ; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[FLAG:%.*]], 0
467 ; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
468 ; CHECK:       return:
469 ; CHECK-NEXT:    [[T7:%.*]] = load i32, ptr [[RETVAL]], align 4
470 ; CHECK-NEXT:    ret i32 [[T7]]
471 ; CHECK:       if.end:
472 ; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[T5:%.*]], [[IF_ELSE]] ], [ [[T2:%.*]], [[IF_THEN]] ]
473 ; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[RETVAL]], align 4
474 ; CHECK-NEXT:    br label [[RETURN:%.*]]
475 ; CHECK:       if.then:
476 ; CHECK-NEXT:    [[T1:%.*]] = load ptr addrspace(1), ptr [[POINTER1_ADDR]], align 8
477 ; CHECK-NEXT:    [[T2]] = load i32, ptr addrspace(1) [[T1]], align 4
478 ; CHECK-NEXT:    br label [[IF_END:%.*]]
479 ; CHECK:       if.else:
480 ; CHECK-NEXT:    [[T3:%.*]] = load ptr, ptr [[POINTER2_ADDR]], align 8
481 ; CHECK-NEXT:    [[T5]] = load i32, ptr [[T3]], align 4
482 ; CHECK-NEXT:    br label [[IF_END]]
484 nounwind {
485 entry:
486   %retval = alloca i32, align 4                   ; <ptr> [#uses=2]
487   %pointer1.addr = alloca ptr addrspace(1), align 4 ; <ptr>
488   %flag.addr = alloca i32, align 4                ; <ptr> [#uses=2]
489   %pointer2.addr = alloca ptr, align 4           ; <ptr> [#uses=2]
490   %res = alloca i32, align 4                      ; <ptr> [#uses=4]
491   store ptr addrspace(1) %pointer1, ptr %pointer1.addr
492   store i32 %flag, ptr %flag.addr
493   store ptr %pointer2, ptr %pointer2.addr
494   store i32 10, ptr %res
495   %t = load i32, ptr %flag.addr                     ; <i32> [#uses=1]
496   %tobool = icmp ne i32 %t, 0                   ; <i1> [#uses=1]
497   br i1 %tobool, label %if.then, label %if.else
499 return:                                           ; preds = %if.end
500   %t7 = load i32, ptr %retval                       ; <i32> [#uses=1]
501   ret i32 %t7
503 if.end:                                           ; preds = %if.else, %if.then
504   %t6 = load i32, ptr %res                          ; <i32> [#uses=1]
505   store i32 %t6, ptr %retval
506   br label %return
508 if.then:                                          ; preds = %entry
509   %t1 = load ptr addrspace(1), ptr %pointer1.addr  ; <ptr addrspace(1)>
510   %arrayidx = getelementptr i32, ptr addrspace(1) %t1, i32 0 ; <ptr addrspace(1)> [#uses=1]
511   %t2 = load i32, ptr addrspace(1) %arrayidx        ; <i32> [#uses=1]
512   store i32 %t2, ptr %res
513   br label %if.end
515 if.else:                                          ; preds = %entry
516   %t3 = load ptr, ptr %pointer2.addr               ; <ptr> [#uses=1]
517   %arrayidx4 = getelementptr i32, ptr %t3, i32 0    ; <ptr> [#uses=1]
518   %t5 = load i32, ptr %arrayidx4                    ; <i32> [#uses=1]
519   store i32 %t5, ptr %res
520   br label %if.end
523 ; PR4413
524 declare i32 @ext()
525 define i32 @test17(i1 %a) {
526 ; CHECK-LABEL: @test17(
527 ; CHECK-NEXT:  entry:
528 ; CHECK-NEXT:    br i1 [[A:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
529 ; CHECK:       bb1:
530 ; CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @ext()
531 ; CHECK-NEXT:    br label [[BB2]]
532 ; CHECK:       bb2:
533 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[TMP0]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]
534 ; CHECK-NEXT:    ret i32 [[RES]]
536 entry:
537   br i1 %a, label %bb1, label %bb2
539 bb1:        ; preds = %entry
540   %0 = tail call i32 @ext()        ; <i32> [#uses=1]
541   br label %bb2
543 bb2:        ; preds = %bb1, %entry
544   %cond = phi i1 [ true, %bb1 ], [ false, %entry ]        ; <i1> [#uses=1]
545   %val = phi i32 [ %0, %bb1 ], [ 0, %entry ]        ; <i32> [#uses=1]
546   %res = select i1 %cond, i32 %val, i32 0        ; <i32> [#uses=1]
547   ret i32 %res
550 ; Atomic and non-atomic loads should not be combined.
551 define i32 @PR51435(ptr %ptr, ptr %atomic_ptr, i1 %c) {
552 ; CHECK-LABEL: @PR51435(
553 ; CHECK-NEXT:  entry:
554 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[PTR:%.*]], align 4
555 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]
556 ; CHECK:       if:
557 ; CHECK-NEXT:    [[Y:%.*]] = load atomic i32, ptr [[ATOMIC_PTR:%.*]] acquire, align 4
558 ; CHECK-NEXT:    br label [[END]]
559 ; CHECK:       end:
560 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[X]], [[ENTRY:%.*]] ], [ [[Y]], [[IF]] ]
561 ; CHECK-NEXT:    ret i32 [[COND]]
563 entry:
564   %x = load i32, ptr %ptr, align 4
565   br i1 %c, label %if, label %end
568   %y = load atomic i32, ptr %atomic_ptr acquire, align 4
569   br label %end
571 end:
572   %cond = phi i32 [ %x, %entry ], [ %y, %if ]
573   ret i32 %cond
576 define i1 @test18(i1 %cond) {
577 ; CHECK-LABEL: @test18(
578 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
579 ; CHECK:       true:
580 ; CHECK-NEXT:    br label [[RET:%.*]]
581 ; CHECK:       false:
582 ; CHECK-NEXT:    br label [[RET]]
583 ; CHECK:       ret:
584 ; CHECK-NEXT:    ret i1 false
586   %zero = alloca i32
587   %one = alloca i32
588   br i1 %cond, label %true, label %false
589 true:
590   br label %ret
591 false:
592   br label %ret
593 ret:
594   %ptr = phi ptr [ %zero, %true ] , [ %one, %false ]
595   %isnull = icmp eq ptr %ptr, null
596   ret i1 %isnull
599 define i1 @test19(i1 %cond, double %x) {
600 ; CHECK-LABEL: @test19(
601 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
602 ; CHECK:       true:
603 ; CHECK-NEXT:    br label [[RET:%.*]]
604 ; CHECK:       false:
605 ; CHECK-NEXT:    br label [[RET]]
606 ; CHECK:       ret:
607 ; CHECK-NEXT:    ret i1 true
609   br i1 %cond, label %true, label %false
610 true:
611   br label %ret
612 false:
613   br label %ret
614 ret:
615   %p = phi double [ %x, %true ], [ 0x7FF0000000000000, %false ]; RHS = +infty
616   %cmp = fcmp ule double %x, %p
617   ret i1 %cmp
620 define i1 @test20(i1 %cond) {
621 ; CHECK-LABEL: @test20(
622 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
623 ; CHECK:       true:
624 ; CHECK-NEXT:    br label [[RET:%.*]]
625 ; CHECK:       false:
626 ; CHECK-NEXT:    br label [[RET]]
627 ; CHECK:       ret:
628 ; CHECK-NEXT:    ret i1 false
630   %a = alloca i32
631   %b = alloca i32
632   %c = alloca i32
633   br i1 %cond, label %true, label %false
634 true:
635   br label %ret
636 false:
637   br label %ret
638 ret:
639   %p = phi ptr [ %a, %true ], [ %b, %false ]
640   %r = icmp eq ptr %p, %c
641   ret i1 %r
644 define i1 @test21(i1 %c1, i1 %c2) {
645 ; CHECK-LABEL: @test21(
646 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
647 ; CHECK:       true:
648 ; CHECK-NEXT:    br label [[LOOP:%.*]]
649 ; CHECK:       false:
650 ; CHECK-NEXT:    br label [[LOOP]]
651 ; CHECK:       loop:
652 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[RET:%.*]], label [[LOOP]]
653 ; CHECK:       ret:
654 ; CHECK-NEXT:    ret i1 false
656   %a = alloca i32
657   %b = alloca i32
658   %c = alloca i32
659   br i1 %c1, label %true, label %false
660 true:
661   br label %loop
662 false:
663   br label %loop
664 loop:
665   %p = phi ptr [ %a, %true ], [ %b, %false ], [ %p, %loop ]
666   %r = icmp eq ptr %p, %c
667   br i1 %c2, label %ret, label %loop
668 ret:
669   ret i1 %r
672 define void @test22() {
673 ; CHECK-LABEL: @test22(
674 ; CHECK-NEXT:  entry:
675 ; CHECK-NEXT:    br label [[LOOP:%.*]]
676 ; CHECK:       loop:
677 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y:%.*]], [[LOOP]] ]
678 ; CHECK-NEXT:    [[Y]] = add i32 [[PHI]], 1
679 ; CHECK-NEXT:    [[O:%.*]] = or i32 [[Y]], [[PHI]]
680 ; CHECK-NEXT:    [[E:%.*]] = icmp eq i32 [[O]], [[Y]]
681 ; CHECK-NEXT:    br i1 [[E]], label [[LOOP]], label [[RET:%.*]]
682 ; CHECK:       ret:
683 ; CHECK-NEXT:    ret void
685 entry:
686   br label %loop
687 loop:
688   %phi = phi i32 [ 0, %entry ], [ %y, %loop ]
689   %y = add i32 %phi, 1
690   %o = or i32 %y, %phi
691   %e = icmp eq i32 %o, %y
692   br i1 %e, label %loop, label %ret
693 ret:
694   ret void
697 define i32 @test23(i32 %A, i1 %pb, ptr %P) {
698 ; CHECK-LABEL: @test23(
699 ; CHECK-NEXT:  BB0:
700 ; CHECK-NEXT:    [[PHI_BO:%.*]] = add i32 [[A:%.*]], 19
701 ; CHECK-NEXT:    br label [[LOOP:%.*]]
702 ; CHECK:       Loop:
703 ; CHECK-NEXT:    [[B:%.*]] = phi i32 [ [[PHI_BO]], [[BB0:%.*]] ], [ 61, [[LOOP]] ]
704 ; CHECK-NEXT:    store i32 [[B]], ptr [[P:%.*]], align 4
705 ; CHECK-NEXT:    br i1 [[PB:%.*]], label [[LOOP]], label [[EXIT:%.*]]
706 ; CHECK:       Exit:
707 ; CHECK-NEXT:    ret i32 [[B]]
709 BB0:
710   br label %Loop
712 Loop:           ; preds = %Loop, %BB0
713   ; PHI has same value always.
714   %B = phi i32 [ %A, %BB0 ], [ 42, %Loop ]
715   %D = add i32 %B, 19
716   store i32 %D, ptr %P
717   br i1 %pb, label %Loop, label %Exit
719 Exit:           ; preds = %Loop
720   %E = add i32 %B, 19
721   ret i32 %E
724 define i32 @test24(i32 %A, i1 %cond) {
725 ; CHECK-LABEL: @test24(
726 ; CHECK-NEXT:  BB0:
727 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
728 ; CHECK:       BB1:
729 ; CHECK-NEXT:    br label [[BB2]]
730 ; CHECK:       BB2:
731 ; CHECK-NEXT:    [[C:%.*]] = add nuw i32 [[A:%.*]], 1
732 ; CHECK-NEXT:    ret i32 [[C]]
734 BB0:
735   %X = add nuw nsw i32 %A, 1
736   br i1 %cond, label %BB1, label %BB2
738 BB1:
739   %Y = add nuw i32 %A, 1
740   br label %BB2
742 BB2:
743   %C = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ]
744   ret i32 %C
747 ; Same as test11, but used to be missed due to a bug.
748 declare i1 @test25a()
750 define i1 @test25() {
751 ; CHECK-LABEL: @test25(
752 ; CHECK-NEXT:  entry:
753 ; CHECK-NEXT:    [[B:%.*]] = call i1 @test25a()
754 ; CHECK-NEXT:    br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
755 ; CHECK:       one:
756 ; CHECK-NEXT:    [[C:%.*]] = call i1 @test25a()
757 ; CHECK-NEXT:    br i1 [[C]], label [[TWO]], label [[END:%.*]]
758 ; CHECK:       two:
759 ; CHECK-NEXT:    [[D:%.*]] = call i1 @test25a()
760 ; CHECK-NEXT:    br i1 [[D]], label [[ONE]], label [[END]]
761 ; CHECK:       end:
762 ; CHECK-NEXT:    [[Z:%.*]] = call i1 @test25a()
763 ; CHECK-NEXT:    ret i1 [[Z]]
765 entry:
766   %a = alloca i32
767   %i = ptrtoint ptr %a to i64
768   %b = call i1 @test25a()
769   br i1 %b, label %one, label %two
771 one:
772   %x = phi i64 [%y, %two], [%i, %entry]
773   %c = call i1 @test25a()
774   br i1 %c, label %two, label %end
776 two:
777   %y = phi i64 [%x, %one], [%i, %entry]
778   %d = call i1 @test25a()
779   br i1 %d, label %one, label %end
781 end:
782   %f = phi i64 [ %x, %one], [%y, %two]
783   ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
784   ; even though %f must equal %i at this point
785   %g = inttoptr i64 %f to ptr
786   store i32 10, ptr %g
787   %z = call i1 @test25a()
788   ret i1 %z
791 declare i1 @test26a()
793 define i1 @test26(i32 %n) {
794 ; CHECK-LABEL: @test26(
795 ; CHECK-NEXT:  entry:
796 ; CHECK-NEXT:    [[B:%.*]] = call i1 @test26a()
797 ; CHECK-NEXT:    br label [[ONE:%.*]]
798 ; CHECK:       one:
799 ; CHECK-NEXT:    [[C:%.*]] = call i1 @test26a()
800 ; CHECK-NEXT:    switch i32 [[N:%.*]], label [[END:%.*]] [
801 ; CHECK-NEXT:    i32 2, label [[TWO:%.*]]
802 ; CHECK-NEXT:    i32 3, label [[THREE:%.*]]
803 ; CHECK-NEXT:    ]
804 ; CHECK:       two:
805 ; CHECK-NEXT:    [[D:%.*]] = call i1 @test26a()
806 ; CHECK-NEXT:    switch i32 [[N]], label [[END]] [
807 ; CHECK-NEXT:    i32 10, label [[ONE]]
808 ; CHECK-NEXT:    i32 30, label [[THREE]]
809 ; CHECK-NEXT:    ]
810 ; CHECK:       three:
811 ; CHECK-NEXT:    [[E:%.*]] = call i1 @test26a()
812 ; CHECK-NEXT:    br i1 [[E]], label [[ONE]], label [[TWO]]
813 ; CHECK:       end:
814 ; CHECK-NEXT:    [[Z:%.*]] = call i1 @test26a()
815 ; CHECK-NEXT:    ret i1 [[Z]]
817 entry:
818   %a = alloca i32
819   %i = ptrtoint ptr %a to i64
820   %b = call i1 @test26a()
821   br label %one
823 one:
824   %x = phi i64 [%y, %two], [%w, %three], [%i, %entry]
825   %c = call i1 @test26a()
826   switch i32 %n, label %end [
827   i32 2, label %two
828   i32 3, label %three
829   ]
831 two:
832   %y = phi i64 [%x, %one], [%w, %three]
833   %d = call i1 @test26a()
834   switch i32 %n, label %end [
835   i32 10, label %one
836   i32 30, label %three
837   ]
839 three:
840   %w = phi i64 [%y, %two], [%x, %one]
841   %e = call i1 @test26a()
842   br i1 %e, label %one, label %two
844 end:
845   %f = phi i64 [ %x, %one], [%y, %two]
846   ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
847   ; even though %f must equal %i at this point
848   %g = inttoptr i64 %f to ptr
849   store i32 10, ptr %g
850   %z = call i1 @test26a()
851   ret i1 %z
854 define i32 @test27(i1 %b) {
855 ; CHECK-LABEL: @test27(
856 ; CHECK-NEXT:  entry:
857 ; CHECK-NEXT:    br label [[DONE:%.*]]
858 ; CHECK:       done:
859 ; CHECK-NEXT:    ret i32 undef
861 entry:
862   br label %done
863 done:
864   %y = phi i32 [ undef, %entry ]
865   ret i32 %y
868 ; We should be able to fold the zexts to the other side of the phi
869 ; even though there's a constant value input to the phi. This is
870 ; because we can shrink that constant to the smaller phi type.
872 define i1 @PR24766(i8 %x1, i8 %x2, i8 %condition) {
873 ; CHECK-LABEL: @PR24766(
874 ; CHECK-NEXT:  entry:
875 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
876 ; CHECK-NEXT:    switch i32 [[CONV]], label [[EPILOG:%.*]] [
877 ; CHECK-NEXT:    i32 0, label [[SW1:%.*]]
878 ; CHECK-NEXT:    i32 1, label [[SW2:%.*]]
879 ; CHECK-NEXT:    ]
880 ; CHECK:       sw1:
881 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
882 ; CHECK-NEXT:    br label [[EPILOG]]
883 ; CHECK:       sw2:
884 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
885 ; CHECK-NEXT:    br label [[EPILOG]]
886 ; CHECK:       epilog:
887 ; CHECK-NEXT:    [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ]
888 ; CHECK-NEXT:    ret i1 [[CONDITIONMET_SHRUNK]]
890 entry:
891   %conv = sext i8 %condition to i32
892   switch i32 %conv, label %epilog [
893   i32 0, label %sw1
894   i32 1, label %sw2
895   ]
897 sw1:
898   %cmp1 = icmp eq i8 %x1, %x2
899   %frombool1 = zext i1 %cmp1 to i8
900   br label %epilog
902 sw2:
903   %cmp2 = icmp sle i8 %x1, %x2
904   %frombool2 = zext i1 %cmp2 to i8
905   br label %epilog
907 epilog:
908   %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
909   %tobool = icmp ne i8 %conditionMet, 0
910   ret i1 %tobool
914 ; Same as above (a phi with more than 2 operands), but no constants
916 define i1 @PR24766_no_constants(i8 %x1, i8 %x2, i8 %condition, i1 %another_condition) {
917 ; CHECK-LABEL: @PR24766_no_constants(
918 ; CHECK-NEXT:  entry:
919 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
920 ; CHECK-NEXT:    switch i32 [[CONV]], label [[EPILOG:%.*]] [
921 ; CHECK-NEXT:    i32 0, label [[SW1:%.*]]
922 ; CHECK-NEXT:    i32 1, label [[SW2:%.*]]
923 ; CHECK-NEXT:    ]
924 ; CHECK:       sw1:
925 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
926 ; CHECK-NEXT:    br label [[EPILOG]]
927 ; CHECK:       sw2:
928 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
929 ; CHECK-NEXT:    br label [[EPILOG]]
930 ; CHECK:       epilog:
931 ; CHECK-NEXT:    [[CONDITIONMET_IN:%.*]] = phi i1 [ [[ANOTHER_CONDITION:%.*]], [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ]
932 ; CHECK-NEXT:    ret i1 [[CONDITIONMET_IN]]
934 entry:
935   %frombool0 = zext i1 %another_condition to i8
936   %conv = sext i8 %condition to i32
937   switch i32 %conv, label %epilog [
938   i32 0, label %sw1
939   i32 1, label %sw2
940   ]
942 sw1:
943   %cmp1 = icmp eq i8 %x1, %x2
944   %frombool1 = zext i1 %cmp1 to i8
945   br label %epilog
947 sw2:
948   %cmp2 = icmp sle i8 %x1, %x2
949   %frombool2 = zext i1 %cmp2 to i8
950   br label %epilog
952 epilog:
953   %conditionMet = phi i8 [ %frombool0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ]
954   %tobool = icmp ne i8 %conditionMet, 0
955   ret i1 %tobool
959 ; Same as above (a phi with more than 2 operands), but two constants
961 define i1 @PR24766_two_constants(i8 %x1, i8 %x2, i8 %condition) {
962 ; CHECK-LABEL: @PR24766_two_constants(
963 ; CHECK-NEXT:  entry:
964 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
965 ; CHECK-NEXT:    switch i32 [[CONV]], label [[EPILOG:%.*]] [
966 ; CHECK-NEXT:    i32 0, label [[SW1:%.*]]
967 ; CHECK-NEXT:    i32 1, label [[SW2:%.*]]
968 ; CHECK-NEXT:    ]
969 ; CHECK:       sw1:
970 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
971 ; CHECK-NEXT:    br label [[EPILOG]]
972 ; CHECK:       sw2:
973 ; CHECK-NEXT:    br label [[EPILOG]]
974 ; CHECK:       epilog:
975 ; CHECK-NEXT:    [[CONDITIONMET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[SW2]] ], [ [[CMP1]], [[SW1]] ]
976 ; CHECK-NEXT:    ret i1 [[CONDITIONMET]]
978 entry:
979   %conv = sext i8 %condition to i32
980   switch i32 %conv, label %epilog [
981   i32 0, label %sw1
982   i32 1, label %sw2
983   ]
985 sw1:
986   %cmp1 = icmp eq i8 %x1, %x2
987   %frombool1 = zext i1 %cmp1 to i8
988   br label %epilog
990 sw2:
991   %cmp2 = icmp sle i8 %x1, %x2
992   %frombool2 = zext i1 %cmp2 to i8
993   br label %epilog
995 epilog:
996   %conditionMet = phi i8 [ 0, %entry ], [ 1, %sw2 ], [ %frombool1, %sw1 ]
997   %tobool = icmp ne i8 %conditionMet, 0
998   ret i1 %tobool
1002 ; Same as above (a phi with more than 2 operands), but two constants and two variables
1004 define i1 @PR24766_two_constants_two_var(i8 %x1, i8 %x2, i8 %condition) {
1005 ; CHECK-LABEL: @PR24766_two_constants_two_var(
1006 ; CHECK-NEXT:  entry:
1007 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32
1008 ; CHECK-NEXT:    switch i32 [[CONV]], label [[EPILOG:%.*]] [
1009 ; CHECK-NEXT:    i32 0, label [[SW1:%.*]]
1010 ; CHECK-NEXT:    i32 1, label [[SW2:%.*]]
1011 ; CHECK-NEXT:    i32 2, label [[SW3:%.*]]
1012 ; CHECK-NEXT:    ]
1013 ; CHECK:       sw1:
1014 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]]
1015 ; CHECK-NEXT:    br label [[EPILOG]]
1016 ; CHECK:       sw2:
1017 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]]
1018 ; CHECK-NEXT:    br label [[EPILOG]]
1019 ; CHECK:       sw3:
1020 ; CHECK-NEXT:    br label [[EPILOG]]
1021 ; CHECK:       epilog:
1022 ; CHECK-NEXT:    [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ], [ true, [[SW3]] ]
1023 ; CHECK-NEXT:    ret i1 [[CONDITIONMET_SHRUNK]]
1025 entry:
1026   %conv = sext i8 %condition to i32
1027   switch i32 %conv, label %epilog [
1028   i32 0, label %sw1
1029   i32 1, label %sw2
1030   i32 2, label %sw3
1031   ]
1033 sw1:
1034   %cmp1 = icmp eq i8 %x1, %x2
1035   %frombool1 = zext i1 %cmp1 to i8
1036   br label %epilog
1038 sw2:
1039   %cmp2 = icmp sle i8 %x1, %x2
1040   %frombool2 = zext i1 %cmp2 to i8
1041   br label %epilog
1043 sw3:
1044   %cmp3 = icmp sge i8 %x1, %x2
1045   %frombool3 = zext i1 %cmp3 to i8
1046   br label %epilog
1048 epilog:
1049   %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ], [ 1, %sw3 ]
1050   %tobool = icmp ne i8 %conditionMet, 0
1051   ret i1 %tobool
1055 define i1 @phi_allnonzeroconstant(i1 %c, i32 %a, i32 %b) {
1056 ; CHECK-LABEL: @phi_allnonzeroconstant(
1057 ; CHECK-NEXT:  entry:
1058 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1059 ; CHECK:       if.then:
1060 ; CHECK-NEXT:    br label [[IF_END:%.*]]
1061 ; CHECK:       if.else:
1062 ; CHECK-NEXT:    call void @dummy()
1063 ; CHECK-NEXT:    br label [[IF_END]]
1064 ; CHECK:       if.end:
1065 ; CHECK-NEXT:    ret i1 false
1067 entry:
1068   br i1 %c, label %if.then, label %if.else
1070 if.then:                                          ; preds = %entry
1071   br label %if.end
1073 if.else:                                          ; preds = %entry
1074   call void @dummy()
1076   br label %if.end
1078 if.end:                                           ; preds = %if.else, %if.then
1079   %x.0 = phi i32 [ 1, %if.then ], [ 2, %if.else ]
1080   %or = or i32 %x.0, %a
1081   %cmp1 = icmp eq i32 %or, 0
1082   ret i1 %cmp1
1085 define i1 @phi_allnonzerononconstant(i1 %c, i32 %a, ptr nonnull %b1, ptr nonnull %b2) {
1086 ; CHECK-LABEL: @phi_allnonzerononconstant(
1087 ; CHECK-NEXT:  entry:
1088 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1089 ; CHECK:       if.then:
1090 ; CHECK-NEXT:    br label [[IF_END:%.*]]
1091 ; CHECK:       if.else:
1092 ; CHECK-NEXT:    call void @dummy()
1093 ; CHECK-NEXT:    br label [[IF_END]]
1094 ; CHECK:       if.end:
1095 ; CHECK-NEXT:    ret i1 false
1097 entry:
1098   br i1 %c, label %if.then, label %if.else
1100 if.then:                                          ; preds = %entry
1101   br label %if.end
1103 if.else:                                          ; preds = %entry
1104   call void @dummy()
1106   br label %if.end
1108 if.end:                                           ; preds = %if.else, %if.then
1109   %x.0 = phi ptr [ %b1, %if.then ], [ %b2, %if.else ]
1110   %cmp1 = icmp eq ptr %x.0, null
1111   ret i1 %cmp1
1114 declare void @dummy()
1116 define i1 @phi_knownnonzero_eq(i32 %n, i32 %s, ptr nocapture readonly %P) {
1117 ; CHECK-LABEL: @phi_knownnonzero_eq(
1118 ; CHECK-NEXT:  entry:
1119 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1120 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1121 ; CHECK:       if.then:
1122 ; CHECK-NEXT:    br label [[IF_END]]
1123 ; CHECK:       if.end:
1124 ; CHECK-NEXT:    [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1125 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0
1126 ; CHECK-NEXT:    ret i1 [[CMP1]]
1128 entry:
1129   %tobool = icmp slt  i32 %n, %s
1130   br i1 %tobool, label %if.end, label %if.then
1132 if.then:                                          ; preds = %entry
1133   %0 = load i32, ptr %P
1134   %cmp = icmp eq i32 %n, %0
1135   %1 = select i1 %cmp, i32 1, i32 2
1136   br label %if.end
1138 if.end:                                           ; preds = %entry, %if.then
1139   %a.0 = phi i32 [ %1,  %if.then ], [ %n, %entry ]
1140   %cmp1 = icmp eq i32 %a.0, 0
1141   ret i1  %cmp1
1144 define i1 @phi_knownnonzero_ne(i32 %n, i32 %s, ptr nocapture readonly %P) {
1145 ; CHECK-LABEL: @phi_knownnonzero_ne(
1146 ; CHECK-NEXT:  entry:
1147 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1148 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1149 ; CHECK:       if.then:
1150 ; CHECK-NEXT:    br label [[IF_END]]
1151 ; CHECK:       if.end:
1152 ; CHECK-NEXT:    [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1153 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0
1154 ; CHECK-NEXT:    ret i1 [[CMP1]]
1156 entry:
1157   %tobool = icmp slt  i32 %n, %s
1158   br i1 %tobool, label %if.end, label %if.then
1160 if.then:                                          ; preds = %entry
1161   %0 = load i32, ptr %P
1162   %cmp = icmp eq i32 %n, %0
1163   %1 = select i1 %cmp, i32 1, i32 2
1164   br label %if.end
1166 if.end:                                           ; preds = %entry, %if.then
1167   %a.0 = phi i32 [ %1,  %if.then ], [ %n, %entry ]
1168   %cmp1 = icmp ne i32 %a.0, 0
1169   ret i1  %cmp1
1172 define i1 @phi_knownnonzero_eq_2(i32 %n, i32 %s, ptr nocapture readonly %P) {
1173 ; CHECK-LABEL: @phi_knownnonzero_eq_2(
1174 ; CHECK-NEXT:  entry:
1175 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1176 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1177 ; CHECK:       if.then:
1178 ; CHECK-NEXT:    br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]]
1179 ; CHECK:       if.else:
1180 ; CHECK-NEXT:    br label [[IF_END]]
1181 ; CHECK:       if.end:
1182 ; CHECK-NEXT:    [[A_0:%.*]] = phi i32 [ 2, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ]
1183 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0
1184 ; CHECK-NEXT:    ret i1 [[CMP1]]
1186 entry:
1187   %tobool = icmp slt  i32 %n, %s
1188   br i1 %tobool, label %if.then, label %if.end
1190 if.then:
1191   %tobool2 = icmp slt  i32 %n, %s
1192   br i1 %tobool2, label %if.else, label %if.end
1194 if.else:                                          ; preds = %entry
1195   %0 = load i32, ptr %P
1196   %cmp = icmp eq i32 %n, %0
1197   %1 = select i1 %cmp, i32 1, i32 2
1198   br label %if.end
1200 if.end:                                           ; preds = %entry, %if.then
1201   %a.0 = phi i32 [ %1,  %if.else], [ %n, %entry ], [2, %if.then]
1202   %cmp1 = icmp eq i32 %a.0, 0
1203   ret i1  %cmp1
1206 define i1 @phi_knownnonzero_ne_2(i32 %n, i32 %s, ptr nocapture readonly %P) {
1207 ; CHECK-LABEL: @phi_knownnonzero_ne_2(
1208 ; CHECK-NEXT:  entry:
1209 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]]
1210 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
1211 ; CHECK:       if.then:
1212 ; CHECK-NEXT:    br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]]
1213 ; CHECK:       if.else:
1214 ; CHECK-NEXT:    br label [[IF_END]]
1215 ; CHECK:       if.end:
1216 ; CHECK-NEXT:    [[A_0:%.*]] = phi i32 [ 2, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ]
1217 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0
1218 ; CHECK-NEXT:    ret i1 [[CMP1]]
1220 entry:
1221   %tobool = icmp slt  i32 %n, %s
1222   br i1 %tobool, label %if.then, label %if.end
1224 if.then:
1225   %tobool2 = icmp slt  i32 %n, %s
1226   br i1 %tobool2, label %if.else, label %if.end
1228 if.else:                                          ; preds = %entry
1229   %0 = load i32, ptr %P
1230   %cmp = icmp eq i32 %n, %0
1231   %1 = select i1 %cmp, i32 1, i32 2
1232   br label %if.end
1234 if.end:                                           ; preds = %entry, %if.then
1235   %a.0 = phi i32 [ %1,  %if.else], [ %n, %entry ], [2, %if.then]
1236   %cmp1 = icmp ne i32 %a.0, 0
1237   ret i1  %cmp1
1240 ; This would crash trying to delete an instruction (conv)
1241 ; that still had uses because the user (the phi) was not
1242 ; updated to remove a use from an unreachable block (g.exit).
1244 define void @main(i1 %cond, i16 %x) {
1245 ; CHECK-LABEL: @main(
1246 ; CHECK-NEXT:  entry:
1247 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
1248 ; CHECK:       for.cond:
1249 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]]
1250 ; CHECK:       for.body:
1251 ; CHECK-NEXT:    unreachable
1252 ; CHECK:       g.exit:
1253 ; CHECK-NEXT:    br label [[FOR_COND]]
1254 ; CHECK:       for.end:
1255 ; CHECK-NEXT:    ret void
1257 entry:
1258   br label %for.cond
1260 for.cond:
1261   %p = phi double [ %conv, %g.exit ], [ undef, %entry ]
1262   br i1 %cond, label %for.end, label %for.body
1264 for.body:
1265   %conv = sitofp i16 %x to double
1266   unreachable
1268 g.exit:
1269   br label %for.cond
1271 for.end:
1272   store double %p, ptr undef
1273   ret void
1276 define i1 @pr57488_icmp_of_phi(ptr %ptr.base, i64 %len) {
1277 ; CHECK-LABEL: @pr57488_icmp_of_phi(
1278 ; CHECK-NEXT:  start:
1279 ; CHECK-NEXT:    [[END:%.*]] = getelementptr inbounds i64, ptr [[PTR_BASE:%.*]], i64 [[LEN:%.*]]
1280 ; CHECK-NEXT:    [[LEN_ZERO:%.*]] = icmp eq i64 [[LEN]], 0
1281 ; CHECK-NEXT:    br i1 [[LEN_ZERO]], label [[EXIT:%.*]], label [[LOOP:%.*]]
1282 ; CHECK:       loop:
1283 ; CHECK-NEXT:    [[ACCUM:%.*]] = phi i8 [ [[ACCUM_NEXT:%.*]], [[LOOP]] ], [ 1, [[START:%.*]] ]
1284 ; CHECK-NEXT:    [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], [[LOOP]] ], [ [[PTR_BASE]], [[START]] ]
1285 ; CHECK-NEXT:    [[PTR_NEXT]] = getelementptr inbounds i64, ptr [[PTR]], i64 1
1286 ; CHECK-NEXT:    [[ACCUM_BOOL:%.*]] = icmp ne i8 [[ACCUM]], 0
1287 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR]], align 8
1288 ; CHECK-NEXT:    [[VAL_ZERO:%.*]] = icmp eq i64 [[VAL]], 0
1289 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ACCUM_BOOL]], [[VAL_ZERO]]
1290 ; CHECK-NEXT:    [[ACCUM_NEXT]] = zext i1 [[AND]] to i8
1291 ; CHECK-NEXT:    [[EXIT_COND:%.*]] = icmp eq ptr [[PTR_NEXT]], [[END]]
1292 ; CHECK-NEXT:    br i1 [[EXIT_COND]], label [[EXIT]], label [[LOOP]]
1293 ; CHECK:       exit:
1294 ; CHECK-NEXT:    [[RES:%.*]] = phi i1 [ true, [[START]] ], [ [[AND]], [[LOOP]] ]
1295 ; CHECK-NEXT:    ret i1 [[RES]]
1297 start:
1298   %end = getelementptr inbounds i64, ptr %ptr.base, i64 %len
1299   %len.zero = icmp eq i64 %len, 0
1300   br i1 %len.zero, label %exit, label %loop
1302 loop:
1303   %accum = phi i8 [ %accum.next, %loop ], [ 1, %start ]
1304   %ptr = phi ptr [ %ptr.next, %loop ], [ %ptr.base, %start ]
1305   %ptr.next = getelementptr inbounds i64, ptr %ptr, i64 1
1306   %accum.bool = icmp ne i8 %accum, 0
1307   %val = load i64, ptr %ptr, align 8
1308   %val.zero = icmp eq i64 %val, 0
1309   %and = and i1 %accum.bool, %val.zero
1310   %accum.next = zext i1 %and to i8
1311   %exit.cond = icmp eq ptr %ptr.next, %end
1312   br i1 %exit.cond, label %exit, label %loop
1314 exit:
1315   %res = phi i1 [ true, %start ], [ %and, %loop ]
1316   ret i1 %res
1319 declare void @use(i32)
1321 define i32 @phi_op_self_simplify() {
1322 ; CHECK-LABEL: @phi_op_self_simplify(
1323 ; CHECK-NEXT:  entry:
1324 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1325 ; CHECK:       loop:
1326 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_ADD2:%.*]], [[LOOP]] ]
1327 ; CHECK-NEXT:    [[IV_ADD:%.*]] = xor i32 [[IV]], -1
1328 ; CHECK-NEXT:    call void @use(i32 [[IV_ADD]])
1329 ; CHECK-NEXT:    [[IV_ADD2]] = xor i32 [[IV]], -1
1330 ; CHECK-NEXT:    br label [[LOOP]]
1332 entry:
1333   br label %loop
1335 loop:
1336   %iv = phi i32 [ 1, %entry ], [ %iv.add2, %loop ]
1337   %iv.add = xor i32 %iv, -1
1338   call void @use(i32 %iv.add)
1339   %iv.add2 = xor i32 %iv, -1
1340   br label %loop
1343 ; Caused an infinite loop with D134954.
1344 define i64 @inttoptr_of_phi(i1 %c, ptr %arg.ptr, ptr %arg.ptr2) {
1345 ; CHECK-LABEL: @inttoptr_of_phi(
1346 ; CHECK-NEXT:  entry:
1347 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1348 ; CHECK:       if:
1349 ; CHECK-NEXT:    [[ARG_PTR2_VAL:%.*]] = load i64, ptr [[ARG_PTR2:%.*]], align 8
1350 ; CHECK-NEXT:    [[ARG_PTR2_VAL_PTR:%.*]] = inttoptr i64 [[ARG_PTR2_VAL]] to ptr
1351 ; CHECK-NEXT:    br label [[JOIN:%.*]]
1352 ; CHECK:       else:
1353 ; CHECK-NEXT:    br label [[JOIN]]
1354 ; CHECK:       join:
1355 ; CHECK-NEXT:    [[INT_PTR_PTR:%.*]] = phi ptr [ [[ARG_PTR2_VAL_PTR]], [[IF]] ], [ [[ARG_PTR:%.*]], [[ELSE]] ]
1356 ; CHECK-NEXT:    [[V:%.*]] = load i64, ptr [[INT_PTR_PTR]], align 8
1357 ; CHECK-NEXT:    ret i64 [[V]]
1359 entry:
1360   br i1 %c, label %if, label %else
1363   %arg.ptr2.val = load i64, ptr %arg.ptr2, align 8
1364   br label %join
1366 else:
1367   %arg.int.ptr = ptrtoint ptr %arg.ptr to i64
1368   br label %join
1370 join:
1371   %int.ptr = phi i64 [ %arg.ptr2.val, %if ], [ %arg.int.ptr, %else ]
1372   %ptr = inttoptr i64 %int.ptr to ptr
1373   %v = load i64, ptr %ptr, align 8
1374   ret i64 %v