1 ; RUN: opt -S -passes=licm < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
2 ; RUN: opt -S -passes=licm -licm-control-flow-hoisting=1 < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED
3 ; RUN: opt -S -passes=licm -licm-control-flow-hoisting=0 < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
4 ; RUN: opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
6 ; RUN: opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -licm-control-flow-hoisting=1 -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED
7 ; Enable run below when adding promotion. e.g. "store i32 %phi, ptr %p" is promoted to phi.lcssa.
8 ; opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -licm-control-flow-hoisting=0 -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED
11 ; CHECK-LABEL: @triangle_phi
12 define void @triangle_phi(i32 %x, ptr %p) {
14 ; CHECK: %cmp1 = icmp sgt i32 %x, 0
15 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
19 ; CHECK-ENABLED: [[IF_LICM]]:
20 ; CHECK: %add = add i32 %x, 1
21 ; CHECK-ENABLED: br label %[[THEN_LICM]]
23 ; CHECK-ENABLED: [[THEN_LICM]]:
24 ; CHECK-ENABLED: phi i32 [ %add, %[[IF_LICM]] ], [ %x, %entry ]
25 ; CHECK-ENABLED: store i32 %phi, ptr %p
26 ; CHECK-ENABLED: %cmp2 = icmp ne i32 %phi, 0
27 ; CHECK: br label %loop
30 %cmp1 = icmp sgt i32 %x, 0
31 br i1 %cmp1, label %if, label %then
38 ; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %x, %loop ]
39 ; CHECK-DISABLED: %cmp2 = icmp ne i32 %phi, 0
41 %phi = phi i32 [ %add, %if ], [ %x, %loop ]
42 store i32 %phi, ptr %p
43 %cmp2 = icmp ne i32 %phi, 0
44 br i1 %cmp2, label %loop, label %end
47 ; CHECK-DISABLED: %[[PHI_LCSSA:.*]] = phi i32 [ %phi, %then ]
48 ; CHECK-DISABLED: store i32 %[[PHI_LCSSA]], ptr %p
53 ; CHECK-LABEL: @diamond_phi
54 define void @diamond_phi(i32 %x, ptr %p) {
56 ; CHECK: %cmp1 = icmp sgt i32 %x, 0
57 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]
61 ; CHECK-ENABLED: [[IF_LICM]]:
62 ; CHECK-DAG: %add = add i32 %x, 1
63 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
65 ; CHECK-ENABLED: [[ELSE_LICM]]:
66 ; CHECK-DAG: %sub = sub i32 %x, 1
67 ; CHECK-ENABLED: br label %[[THEN_LICM]]
69 ; CHECK-ENABLED: [[THEN_LICM]]
70 ; CHECK-ENABLED: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]
71 ; CHECK-ENABLED: store i32 %phi, ptr %p
72 ; CHECK-ENABLED: %cmp2 = icmp ne i32 %phi, 0
73 ; CHECK: br label %loop
76 %cmp1 = icmp sgt i32 %x, 0
77 br i1 %cmp1, label %if, label %else
88 ; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %sub, %else ]
89 ; CHECK-DISABLED: %cmp2 = icmp ne i32 %phi, 0
91 %phi = phi i32 [ %add, %if ], [ %sub, %else ]
92 store i32 %phi, ptr %p
93 %cmp2 = icmp ne i32 %phi, 0
94 br i1 %cmp2, label %loop, label %end
97 ; CHECK-DISABLED: %[[PHI_LCSSA:.*]] = phi i32 [ %phi, %then ]
98 ; CHECK-DISABLED: store i32 %[[PHI_LCSSA]], ptr %p
103 ; TODO: This is currently too complicated for us to be able to hoist the phi.
104 ; CHECK-LABEL: @three_way_phi
105 define void @three_way_phi(i32 %x, ptr %p) {
106 ; CHECK-LABEL: entry:
107 ; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0
108 ; CHECK-DAG: %add = add i32 %x, 1
109 ; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0
110 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]
112 ; CHECK-ENABLED: [[IF_LICM]]:
113 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
115 ; CHECK-ENABLED: [[THEN_LICM]]:
116 ; CHECK: %sub = sub i32 %x, 1
117 ; CHECK: br label %loop
123 %cmp1 = icmp sgt i32 %x, 0
124 br i1 %cmp1, label %if, label %then
128 %cmp2 = icmp sgt i32 %add, 0
129 br i1 %cmp2, label %if.if, label %then
136 %phi = phi i32 [ 0, %loop ], [ %add, %if ], [ %sub, %if.if ]
137 store i32 %phi, ptr %p
138 %cmp3 = icmp ne i32 %phi, 0
139 br i1 %cmp3, label %loop, label %end
145 ; TODO: This is currently too complicated for us to be able to hoist the phi.
146 ; CHECK-LABEL: @tree_phi
147 define void @tree_phi(i32 %x, ptr %p) {
148 ; CHECK-LABEL: entry:
149 ; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0
150 ; CHECK-DAG: %add = add i32 %x, 1
151 ; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0
152 ; CHECK-DAG: %sub = sub i32 %x, 1
153 ; CHECK: br label %loop
159 %cmp1 = icmp sgt i32 %x, 0
160 br i1 %cmp1, label %if, label %else
164 %cmp2 = icmp sgt i32 %add, 0
165 br i1 %cmp2, label %if.if, label %if.else
178 %phi = phi i32 [ %add, %if.if ], [ 0, %if.else ], [ %sub, %else ]
179 store i32 %phi, ptr %p
180 %cmp3 = icmp ne i32 %phi, 0
181 br i1 %cmp3, label %loop, label %end
187 ; TODO: We can hoist the first phi, but not the second.
188 ; CHECK-LABEL: @phi_phi
189 define void @phi_phi(i32 %x, ptr %p) {
190 ; CHECK-LABEL: entry:
191 ; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0
192 ; CHECK-DAG: %add = add i32 %x, 1
193 ; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0
194 ; CHECK-DAG: %sub = sub i32 %x, 1
195 ; CHECK-ENABLED: br i1 %cmp2, label %[[IF_IF_LICM:.*]], label %[[IF_ELSE_LICM:.*]]
197 ; CHECK-ENABLED: [[IF_IF_LICM]]:
198 ; CHECK-ENABLED: br label %[[IF_THEN_LICM:.*]]
200 ; CHECK-ENABLED: [[IF_ELSE_LICM]]:
201 ; CHECK-ENABLED: br label %[[IF_THEN_LICM]]
203 ; CHECK-ENABLED: [[IF_THEN_LICM]]:
204 ; CHECK-ENABLED: %phi1 = phi i32 [ %add, %[[IF_IF_LICM]] ], [ 0, %[[IF_ELSE_LICM]] ]
205 ; CHECK: br label %loop
211 %cmp1 = icmp sgt i32 %x, 0
212 br i1 %cmp1, label %if, label %else
216 %cmp2 = icmp sgt i32 %add, 0
217 br i1 %cmp2, label %if.if, label %if.else
225 ; CHECK-LABEL: if.then:
226 ; CHECK-DISABLED: %phi1 = phi i32 [ %add, %if.if ], [ 0, %if.else ]
228 %phi1 = phi i32 [ %add, %if.if ], [ 0, %if.else ]
236 ; CHECK: %phi2 = phi i32 [ %phi1, %if.then ], [ %sub, %else ]
238 %phi2 = phi i32 [ %phi1, %if.then ], [ %sub, %else ]
239 store i32 %phi2, ptr %p
240 %cmp3 = icmp ne i32 %phi2, 0
241 br i1 %cmp3, label %loop, label %end
247 ; Check that we correctly duplicate empty control flow.
248 ; CHECK-LABEL: @empty_triangle_phi
249 define i8 @empty_triangle_phi(i32 %x, i32 %y) {
250 ; CHECK-LABEL: entry:
251 ; CHECK: %cmp1 = icmp eq i32 %x, 0
252 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
256 ; CHECK-ENABLED: [[IF_LICM]]:
257 ; CHECK-ENABLED: br label %[[THEN_LICM]]
259 ; CHECK-ENABLED: [[THEN_LICM]]:
260 ; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]
261 ; CHECK: %cmp2 = icmp eq i32 %y, 0
262 ; CHECK: br label %loop
265 %cmp1 = icmp eq i32 %x, 0
266 br i1 %cmp1, label %if, label %then
272 ; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %loop ]
274 %phi = phi i8 [ 0, %if ], [ 1, %loop ]
275 %cmp2 = icmp eq i32 %y, 0
276 br i1 %cmp2, label %end, label %loop
282 ; CHECK-LABEL: @empty_diamond_phi
283 define i8 @empty_diamond_phi(i32 %x, i32 %y) {
284 ; CHECK-LABEL: entry:
285 ; CHECK: %cmp1 = icmp eq i32 %x, 0
286 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]
290 ; CHECK-ENABLED: [[IF_LICM]]:
291 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
293 ; CHECK-ENABLED: [[ELSE_LICM]]:
294 ; CHECK-ENABLED: br label %[[THEN_LICM]]
296 ; CHECK-ENABLED: [[THEN_LICM]]:
297 ; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]
298 ; CHECK: %cmp2 = icmp eq i32 %y, 0
299 ; CHECK: br label %loop
302 %cmp1 = icmp eq i32 %x, 0
303 br i1 %cmp1, label %if, label %else
312 ; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %else ]
314 %phi = phi i8 [ 0, %if ], [ 1, %else ]
315 %cmp2 = icmp eq i32 %y, 0
316 br i1 %cmp2, label %end, label %loop
322 ; Check that we correctly handle the case that the first thing we try to hoist is a phi.
323 ; CHECK-LABEL: @empty_triangle_phi_first
324 define i8 @empty_triangle_phi_first(i32 %x, i1 %cond) {
325 ; CHECK-LABEL: entry:
326 ; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
330 ; CHECK-ENABLED: [[IF_LICM]]:
331 ; CHECK-ENABLED: br label %[[THEN_LICM]]
333 ; CHECK-ENABLED: [[THEN_LICM]]:
334 ; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]
335 ; CHECK: %cmp = icmp eq i32 %x, 0
336 ; CHECK: br label %loop
339 br i1 %cond, label %if, label %then
345 ; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %loop ]
347 %phi = phi i8 [ 0, %if ], [ 1, %loop ]
348 %cmp = icmp eq i32 %x, 0
349 br i1 %cmp, label %end, label %loop
355 ; CHECK-LABEL: @empty_diamond_phi
356 define i8 @empty_diamond_phi_first(i32 %x, i1 %cond) {
357 ; CHECK-LABEL: entry:
358 ; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]
362 ; CHECK-ENABLED: [[IF_LICM]]:
363 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
365 ; CHECK-ENABLED: [[ELSE_LICM]]:
366 ; CHECK-ENABLED: br label %[[THEN_LICM]]
368 ; CHECK-ENABLED: [[THEN_LICM]]:
369 ; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]
370 ; CHECK: %cmp = icmp eq i32 %x, 0
371 ; CHECK: br label %loop
374 br i1 %cond, label %if, label %else
383 ; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %else ]
385 %phi = phi i8 [ 0, %if ], [ 1, %else ]
386 %cmp = icmp eq i32 %x, 0
387 br i1 %cmp, label %end, label %loop
393 ; CHECK-LABEL: @empty_triangle_phi_first
394 define i8 @empty_triangle_phi_first_empty_loop_head(i32 %x, i1 %cond) {
395 ; CHECK-LABEL: entry:
396 ; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
400 ; CHECK-ENABLED: [[IF_LICM]]:
401 ; CHECK-ENABLED: br label %[[THEN_LICM]]
403 ; CHECK-ENABLED: [[THEN_LICM]]:
404 ; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]
405 ; CHECK: %cmp = icmp eq i32 %x, 0
406 ; CHECK: br label %loop
412 br i1 %cond, label %if, label %then
418 ; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %test ]
420 %phi = phi i8 [ 0, %if ], [ 1, %test ]
421 %cmp = icmp eq i32 %x, 0
422 br i1 %cmp, label %end, label %loop
428 ; CHECK-LABEL: @empty_diamond_phi_first_empty_loop_head
429 define i8 @empty_diamond_phi_first_empty_loop_head(i32 %x, i1 %cond) {
430 ; CHECK-LABEL: entry:
431 ; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]
435 ; CHECK-ENABLED: [[IF_LICM]]:
436 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
438 ; CHECK-ENABLED: [[ELSE_LICM]]:
439 ; CHECK-ENABLED: br label %[[THEN_LICM]]
441 ; CHECK-ENABLED: [[THEN_LICM]]:
442 ; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]
443 ; CHECK: %cmp = icmp eq i32 %x, 0
444 ; CHECK: br label %loop
450 br i1 %cond, label %if, label %else
459 ; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %else ]
461 %phi = phi i8 [ 0, %if ], [ 1, %else ]
462 %cmp = icmp eq i32 %x, 0
463 br i1 %cmp, label %end, label %loop
469 ; The phi is on one branch of a diamond while simultaneously at the end of a
470 ; triangle. Check that we duplicate the triangle and not the diamond.
471 ; CHECK-LABEL: @triangle_diamond
472 define void @triangle_diamond(ptr %ptr, i32 %x, i32 %y) {
473 ; CHECK-LABEL: entry:
474 ; CHECK-DAG: %cmp1 = icmp ne i32 %x, 0
475 ; CHECK-DAG: %cmp2 = icmp ne i32 %y, 0
476 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
480 ; CHECK-ENABLED: [[IF_LICM]]:
481 ; CHECK-ENABLED: br label %[[THEN_LICM]]
483 ; CHECK-ENABLED: [[THEN_LICM]]:
484 ; CHECK-ENABLED: %phi = phi i32 [ 0, %[[IF_LICM]] ], [ 127, %entry ]
485 ; CHECK: br label %loop
488 %cmp1 = icmp ne i32 %x, 0
489 br i1 %cmp1, label %if, label %then
492 %cmp2 = icmp ne i32 %y, 0
493 br i1 %cmp2, label %if.then, label %then
496 ; CHECK-DISABLED: %phi = phi i32 [ 0, %if ], [ 127, %loop ]
498 %phi = phi i32 [ 0, %if ], [ 127, %loop ]
499 store i32 %phi, ptr %ptr
509 ; As the previous, but the end of the diamond is the head of the loop.
510 ; CHECK-LABEL: @triangle_diamond_backedge
511 define void @triangle_diamond_backedge(ptr %ptr, i32 %x, i32 %y) {
512 ; CHECK-LABEL: entry:
513 ; CHECK-DAG: %cmp1 = icmp ne i32 %x, 0
514 ; CHECK-DAG: %cmp2 = icmp ne i32 %y, 0
515 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
519 ; CHECK-ENABLED: [[IF_LICM]]:
520 ; CHECK-ENABLED: br label %[[THEN_LICM]]
522 ; CHECK-ENABLED: [[THEN_LICM]]:
523 ; CHECK-ENABLED: %phi = phi i32 [ 0, %[[IF_LICM]] ], [ 127, %entry ]
524 ; CHECK: br label %loop
527 %cmp1 = icmp ne i32 %x, 0
528 br i1 %cmp1, label %if, label %then
531 %cmp2 = icmp ne i32 %y, 0
532 br i1 %cmp2, label %backedge, label %then
535 ; CHECK-DISABLED: %phi = phi i32 [ 0, %if ], [ 127, %loop ]
537 %phi = phi i32 [ 0, %if ], [ 127, %loop ]
538 store i32 %phi, ptr %ptr
545 ; TODO: The inner diamonds can be hoisted, but not currently the outer diamond
546 ; CHECK-LABEL: @diamonds_inside_diamond
547 define void @diamonds_inside_diamond(i32 %x, ptr %p) {
548 ; CHECK-LABEL: entry:
549 ; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0
550 ; CHECK-DAG: %cmp3 = icmp slt i32 %x, -10
551 ; CHECK-ENABLED: br i1 %cmp3, label %[[ELSE_IF_LICM:.*]], label %[[ELSE_ELSE_LICM:.*]]
555 ; CHECK-ENABLED: [[ELSE_IF_LICM]]:
556 ; CHECK-ENABLED: br label %[[ELSE_THEN_LICM:.*]]
558 ; CHECK-ENABLED: [[ELSE_ELSE_LICM]]:
559 ; CHECK-ENABLED: br label %[[ELSE_THEN_LICM]]
561 ; CHECK-ENABLED: [[ELSE_THEN_LICM]]:
562 ; CHECK-ENABLED: %phi2 = phi i32 [ 2, %[[ELSE_IF_LICM]] ], [ 3, %[[ELSE_ELSE_LICM]] ]
563 ; CHECK: %cmp2 = icmp sgt i32 %x, 10
564 ; CHECK-ENABLED: br i1 %cmp2, label %[[IF_IF_LICM:.*]], label %[[IF_ELSE_LICM:.*]]
566 ; CHECK-ENABLED: [[IF_IF_LICM]]:
567 ; CHECK-ENABLED: br label %[[IF_THEN_LICM:.*]]
569 ; CHECK-ENABLED: [[IF_ELSE_LICM]]:
570 ; CHECK-ENABLED: br label %[[IF_THEN_LICM]]
572 ; CHECK-ENABLED: [[IF_THEN_LICM]]:
573 ; CHECK-ENABLED: %phi1 = phi i32 [ 0, %[[IF_IF_LICM]] ], [ 1, %[[IF_ELSE_LICM]] ]
574 ; CHECK: br label %loop
577 %cmp1 = icmp sgt i32 %x, 0
578 br i1 %cmp1, label %if, label %else
581 %cmp2 = icmp sgt i32 %x, 10
582 br i1 %cmp2, label %if.if, label %if.else
590 ; CHECK-LABEL: if.then:
591 ; CHECK-DISABLED: %phi1 = phi i32 [ 0, %if.if ], [ 1, %if.else ]
593 %phi1 = phi i32 [ 0, %if.if ], [ 1, %if.else ]
597 %cmp3 = icmp slt i32 %x, -10
598 br i1 %cmp3, label %else.if, label %else.else
606 ; CHECK-LABEL: else.then:
607 ; CHECK-DISABLED: %phi2 = phi i32 [ 2, %else.if ], [ 3, %else.else ]
609 %phi2 = phi i32 [ 2, %else.if ], [ 3, %else.else ]
613 ; CHECK: %phi3 = phi i32 [ %phi1, %if.then ], [ %phi2, %else.then ]
614 ; CHECK: %cmp4 = icmp ne i32 %phi3, 0
616 %phi3 = phi i32 [ %phi1, %if.then ], [ %phi2, %else.then ]
617 store i32 %phi3, ptr %p
618 %cmp4 = icmp ne i32 %phi3, 0
619 br i1 %cmp4, label %loop, label %end
625 ; We can hoist blocks that contain an edge that exits the loop by ignoring that
626 ; edge in the hoisted block.
627 define void @triangle_phi_loopexit(i32 %x, ptr %p) {
628 ; CHECK-DISABLED-LABEL: @triangle_phi_loopexit(
629 ; CHECK-DISABLED-NEXT: entry:
630 ; CHECK-DISABLED-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1
631 ; CHECK-DISABLED-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], 0
632 ; CHECK-DISABLED-NEXT: [[CMP2:%.*]] = icmp sgt i32 10, [[ADD]]
633 ; CHECK-DISABLED-NEXT: br label [[LOOP:%.*]]
634 ; CHECK-DISABLED: loop:
635 ; CHECK-DISABLED-NEXT: br i1 [[CMP1]], label [[IF:%.*]], label [[THEN:%.*]]
636 ; CHECK-DISABLED: if:
637 ; CHECK-DISABLED-NEXT: br i1 [[CMP2]], label [[THEN]], label [[END:%.*]]
638 ; CHECK-DISABLED: then:
639 ; CHECK-DISABLED-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD]], [[IF]] ], [ [[X]], [[LOOP]] ]
640 ; CHECK-DISABLED-NEXT: store i32 [[PHI]], ptr [[P:%.*]], align 4
641 ; CHECK-DISABLED-NEXT: [[CMP3:%.*]] = icmp ne i32 [[PHI]], 0
642 ; CHECK-DISABLED-NEXT: br i1 [[CMP3]], label [[LOOP]], label [[END]]
643 ; CHECK-DISABLED: end:
644 ; CHECK-DISABLED-NEXT: ret void
646 ; CHECK-ENABLED-LABEL: @triangle_phi_loopexit(
647 ; CHECK-ENABLED-NEXT: entry:
648 ; CHECK-ENABLED-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1
649 ; CHECK-ENABLED-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], 0
650 ; CHECK-ENABLED-NEXT: [[CMP2:%.*]] = icmp sgt i32 10, [[ADD]]
651 ; CHECK-ENABLED-NEXT: br i1 [[CMP1]], label [[IF_LICM:%.*]], label [[THEN_LICM:%.*]]
652 ; CHECK-ENABLED: if.licm:
653 ; CHECK-ENABLED-NEXT: br label [[THEN_LICM]]
654 ; CHECK-ENABLED: then.licm:
655 ; CHECK-ENABLED-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD]], [[IF_LICM]] ], [ [[X]], [[ENTRY:%.*]] ]
656 ; CHECK-ENABLED-NEXT: [[CMP3:%.*]] = icmp ne i32 [[PHI]], 0
657 ; CHECK-ENABLED-NEXT: br label [[LOOP:%.*]]
658 ; CHECK-ENABLED: loop:
659 ; CHECK-ENABLED-NEXT: br i1 [[CMP1]], label [[IF:%.*]], label [[THEN:%.*]]
661 ; CHECK-ENABLED-NEXT: br i1 [[CMP2]], label [[THEN]], label [[END:%.*]]
662 ; CHECK-ENABLED: then:
663 ; CHECK-ENABLED-NEXT: store i32 [[PHI]], ptr [[P:%.*]], align 4
664 ; CHECK-ENABLED-NEXT: br i1 [[CMP3]], label [[LOOP]], label [[END]]
665 ; CHECK-ENABLED: end:
666 ; CHECK-ENABLED-NEXT: ret void
672 %cmp1 = icmp sgt i32 %x, 0
673 br i1 %cmp1, label %if, label %then
677 %cmp2 = icmp sgt i32 10, %add
678 br i1 %cmp2, label %then, label %end
681 %phi = phi i32 [ %add, %if ], [ %x, %loop ]
682 store i32 %phi, ptr %p
683 %cmp3 = icmp ne i32 %phi, 0
684 br i1 %cmp3, label %loop, label %end
690 ; CHECK-LABEL: @diamond_phi_oneloopexit
691 define void @diamond_phi_oneloopexit(i32 %x, ptr %p) {
692 ; CHECK-LABEL: entry:
693 ; CHECK-DAG: %add = add i32 %x, 1
694 ; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0
695 ; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add
696 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
700 ; CHECK-ENABLED: [[IF_LICM]]:
701 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
703 ; CHECK-ENABLED: [[ELSE_LICM]]:
704 ; CHECK-DAG: %sub = sub i32 %x, 1
705 ; CHECK-ENABLED: br label %[[THEN_LICM]]
707 ; CHECK-ENABLED: [[THEN_LICM]]
708 ; CHECK-ENABLED: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]
709 ; CHECK-ENABLED: %cmp3 = icmp ne i32 %phi, 0
710 ; CHECK: br label %loop
713 %cmp1 = icmp sgt i32 %x, 0
714 br i1 %cmp1, label %if, label %else
718 %cmp2 = icmp sgt i32 10, %add
719 br i1 %cmp2, label %then, label %end
726 ; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %sub, %else ]
728 %phi = phi i32 [ %add, %if ], [ %sub, %else ]
729 store i32 %phi, ptr %p
730 %cmp3 = icmp ne i32 %phi, 0
731 br i1 %cmp3, label %loop, label %end
737 ; CHECK-LABEL: @diamond_phi_twoloopexit
738 define void @diamond_phi_twoloopexit(i32 %x, ptr %p) {
739 ; CHECK-LABEL: entry:
740 ; CHECK-DAG: %sub = sub i32 %x, 1
741 ; CHECK-DAG: %add = add i32 %x, 1
742 ; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0
743 ; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add
744 ; CHECK-DAG: %cmp3 = icmp sgt i32 10, %sub
745 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
749 ; CHECK-ENABLED: [[IF_LICM]]:
750 ; CHECK-ENABLED: br label %[[THEN_LICM:.*]]
752 ; CHECK-ENABLED: [[ELSE_LICM]]:
753 ; CHECK-ENABLED: br label %[[THEN_LICM]]
755 ; CHECK-ENABLED: [[THEN_LICM]]
756 ; CHECK-ENABLED: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]
757 ; CHECK-ENABLED: %cmp4 = icmp ne i32 %phi, 0
758 ; CHECK: br label %loop
761 %cmp1 = icmp sgt i32 %x, 0
762 br i1 %cmp1, label %if, label %else
766 %cmp2 = icmp sgt i32 10, %add
767 br i1 %cmp2, label %then, label %end
771 %cmp3 = icmp sgt i32 10, %sub
772 br i1 %cmp3, label %then, label %end
775 ; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %sub, %else ]
776 ; CHECK-DISABLED: %cmp4 = icmp ne i32 %phi, 0
778 %phi = phi i32 [ %add, %if ], [ %sub, %else ]
779 store i32 %phi, ptr %p
780 %cmp4 = icmp ne i32 %phi, 0
781 br i1 %cmp4, label %loop, label %end
787 ; The store cannot be hoisted, so add and shr cannot be hoisted into a
789 ; CHECK-LABEL: @conditional_use
790 define void @conditional_use(i32 %x, ptr %p) {
791 ; CHECK-LABEL: entry:
792 ; CHECK-DAG: %cond = icmp ugt i32 %x, 0
793 ; CHECK-DAG: %add = add i32 %x, 5
794 ; CHECK-DAG: %shr = ashr i32 %add, 1
795 ; CHECK: br label %loop
800 %cond = icmp ugt i32 %x, 0
801 br i1 %cond, label %if, label %else
804 ; CHECK: store i32 %shr, ptr %p, align 4
807 %shr = ashr i32 %add, 1
808 store i32 %shr, ptr %p, align 4
818 ; A diamond with two triangles on the left and one on the right. This test is
819 ; to check that we have a unique loop preheader when we hoist the store (and so
820 ; don't fail an assertion).
821 ; CHECK-LABEL: @triangles_in_diamond
822 define void @triangles_in_diamond(ptr %ptr, i1 %arg) {
823 ; CHECK-LABEL: entry:
824 ; CHECK: store i32 0, ptr %ptr, align 4
825 ; CHECK: br label %loop
830 br i1 %arg, label %left_triangle_1, label %right_triangle
833 br i1 %arg, label %left_triangle_1_if, label %left_triangle_2
836 br label %left_triangle_2
839 br i1 %arg, label %left_triangle_2_if, label %left_triangle_2_then
842 br label %left_triangle_2_then
844 left_triangle_2_then:
848 br i1 %arg, label %right_triangle.if, label %right_triangle.then
851 br label %right_triangle.then
857 store i32 0, ptr %ptr, align 4
861 ; %cmp dominates its used after being hoisted, but not after %brmerge is rehoisted
862 ; CHECK-LABEL: @rehoist
863 define void @rehoist(ptr %this, i32 %x, i1 %arg) {
864 ; CHECK-LABEL: entry:
865 ; CHECK-DAG: %sub = add nsw i32 %x, -1
866 ; CHECK-DAG: %cmp = icmp eq i32 0, %sub
867 ; CHECK-DAG: %brmerge = or i1 %cmp, true
869 %sub = add nsw i32 %x, -1
873 br i1 %arg, label %if1, label %else1
876 call void %this(ptr %this)
883 %cmp = icmp eq i32 0, %sub
884 br i1 %cmp, label %end, label %else2
887 %brmerge = or i1 %cmp, true
888 br i1 %brmerge, label %if3, label %end
897 ; A test case that uses empty blocks in a way that can cause control flow
898 ; hoisting to get confused.
899 ; CHECK-LABEL: @empty_blocks_multiple_conditional_branches
900 define void @empty_blocks_multiple_conditional_branches(float %arg, ptr %ptr, i1 %arg2) {
902 ; CHECK-DAG: %div1 = fmul float %arg, 4.000000e+00
903 ; CHECK-DAG: %div2 = fmul float %arg, 2.000000e+00
907 ; The exact path to the phi isn't checked here, because it depends on whether
908 ; cond2 or cond3 is hoisted first
909 ; CHECK-ENABLED: %phi = phi float [ 0.000000e+00, %{{.*}} ], [ %div1, %{{.*}} ]
910 ; CHECK: br label %loop
913 br i1 %arg2, label %backedge2, label %cond1
916 br i1 %arg2, label %cond1.if, label %cond1.else
922 br label %cond1.if.next
928 %div1 = fmul float %arg, 4.000000e+00
929 br i1 %arg2, label %cond2.if, label %cond2.then
934 ; CHECK-LABEL: cond2.then:
935 ; CHECK-DISABLED: %phi = phi float [ 0.000000e+00, %cond2 ], [ %div1, %cond2.if ]
937 %phi = phi float [ 0.000000e+00, %cond2 ], [ %div1, %cond2.if ]
938 store float %phi, ptr %ptr
942 br i1 %arg2, label %cond3.then, label %cond3.if
945 %div2 = fmul float %arg, 2.000000e+00
946 store float %div2, ptr %ptr
956 ; We can't do much here, so mainly just check that we don't crash.
957 ; CHECK-LABEL: @many_path_phi
958 define void @many_path_phi(ptr %ptr1, ptr %ptr2, i1 %arg) {
959 ; CHECK-LABEL: entry:
960 ; CHECK-DAG: %gep3 = getelementptr inbounds i32, ptr %ptr2, i32 2
961 ; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr2, i32 2
962 ; CHECK: br label %loop
967 %phi1 = phi i32 [ 0, %entry ], [ %phi2, %end ]
968 %cmp1 = icmp ugt i32 %phi1, 3
969 br i1 %cmp1, label %cond2, label %cond1
972 br i1 %arg, label %end, label %cond1.else
975 %gep2 = getelementptr inbounds i32, ptr %ptr2, i32 2
976 %val2 = load i32, ptr %gep2, align 4
977 %cmp2 = icmp eq i32 %val2, 13
978 br i1 %cmp2, label %cond1.end, label %end
984 br i1 %arg, label %end, label %cond2.else
987 %gep3 = getelementptr inbounds i32, ptr %ptr2, i32 2
988 %val3 = load i32, ptr %gep3, align 4
989 %cmp3 = icmp eq i32 %val3, 13
990 br i1 %cmp3, label %cond2.end, label %end
996 %phi2 = phi i32 [ 1, %cond1 ], [ 2, %cond1.else ], [ 3, %cond1.end ], [ 4, %cond2 ], [ 5, %cond2.else ], [ 6, %cond2.end ]
1000 ; Check that we correctly handle the hoisting of %gep when theres a critical
1001 ; edge that branches to the preheader.
1002 ; CHECK-LABEL: @crit_edge
1003 define void @crit_edge(ptr %ptr, i32 %idx, i1 %cond1, i1 %cond2, i1 %arg) {
1004 ; CHECK-LABEL: entry:
1005 ; CHECK: %gep = getelementptr inbounds i32, ptr %ptr, i32 %idx
1006 ; CHECK: br label %preheader
1014 br i1 %cond1, label %then, label %if
1017 %gep = getelementptr inbounds i32, ptr %ptr, i32 %idx
1018 %val = load i32, ptr %gep
1022 %phi = phi i32 [ %val, %if ], [ 0, %loop ]
1023 store i32 %phi, ptr %ptr
1024 br i1 %cond2, label %loop, label %crit_edge
1030 ; Check that the conditional sub is correctly hoisted from the inner loop to the
1031 ; preheader of the outer loop.
1032 ; CHECK-LABEL: @hoist_from_innermost_loop
1033 define void @hoist_from_innermost_loop(i32 %nx, ptr %ptr, i1 %arg) {
1034 ; CHECK-LABEL: entry:
1035 ; CHECK-DAG: %sub = sub nsw i32 0, %nx
1036 ; CHECK: br label %outer_loop
1038 br label %outer_loop
1041 br label %middle_loop
1044 br label %inner_loop
1047 br i1 %arg, label %inner_loop_end, label %if
1050 %sub = sub nsw i32 0, %nx
1051 store i32 %sub, ptr %ptr, align 4
1052 br label %inner_loop_end
1055 br i1 %arg, label %inner_loop, label %middle_loop_end
1058 br i1 %arg, label %middle_loop, label %outer_loop_end
1061 br label %outer_loop
1064 ; We have a diamond starting from %if, but %if.if is also reachable from %loop,
1065 ; so %gep should not be conditionally hoisted.
1066 ; CHECK-LABEL: @diamond_with_extra_in_edge
1067 define void @diamond_with_extra_in_edge(ptr %ptr1, ptr %ptr2, i32 %arg) {
1068 ; CHECK-LABEL: entry:
1069 ; CHECK-DAG: %cmp2 = icmp ne i32 0, %arg
1070 ; CHECK-DAG: %gep = getelementptr i32, ptr %ptr1, i32 4
1071 ; CHECK: br label %loop
1076 %phi1 = phi i32 [ 0, %entry ], [ %phi2, %then ]
1077 %cmp1 = icmp ugt i32 16, %phi1
1078 br i1 %cmp1, label %if, label %if.if
1081 %cmp2 = icmp ne i32 0, %arg
1082 br i1 %cmp2, label %if.if, label %if.else
1085 %gep = getelementptr i32, ptr %ptr1, i32 4
1086 %val = load i32, ptr %gep, align 4
1093 %phi2 = phi i32 [ %val, %if.if ], [ %phi1, %if.else ]
1094 store i32 %phi2, ptr %ptr2, align 4
1098 ; %loop/%if/%then form a triangle, but %loop/%if/%then/%end also form a diamond.
1099 ; The triangle should be picked for conditional hoisting.
1100 ; CHECK-LABEL: @both_triangle_and_diamond
1101 define void @both_triangle_and_diamond(ptr %ptr1, ptr %ptr2, i32 %arg) {
1102 ; CHECK-LABEL: entry:
1103 ; CHECK-DAG: %cmp1 = icmp ne i32 0, %arg
1104 ; CHECK-DAG: %gep = getelementptr i32, ptr %ptr1, i32 4
1105 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]
1109 ; CHECK-ENABLED: [[IF_LICM]]:
1110 ; CHECK-ENABLED: br label %[[THEN_LICM]]
1112 ; CHECK-ENABLED: [[THEN_LICM]]:
1113 ; CHECK-ENABLED: %phi2 = phi i32 [ 0, %[[IF_LICM]] ], [ 1, %entry ]
1114 ; CHECK: br label %loop
1117 %phi1 = phi i32 [ 0, %entry ], [ %phi3, %end ]
1118 %cmp1 = icmp ne i32 0, %arg
1119 br i1 %cmp1, label %if, label %then
1122 %gep = getelementptr i32, ptr %ptr1, i32 4
1123 %val = load i32, ptr %gep, align 4
1124 %cmp2 = icmp ugt i32 16, %phi1
1125 br i1 %cmp2, label %end, label %then
1127 ; CHECK-LABEL: then:
1128 ; CHECK-DISABLED: %phi2 = phi i32 [ 0, %if ], [ 1, %loop ]
1130 %phi2 = phi i32 [ 0, %if ], [ 1, %loop ]
1134 %phi3 = phi i32 [ %phi2, %then ], [ %val, %if ]
1135 store i32 %phi3, ptr %ptr2, align 4
1139 ; We shouldn't duplicate the branch at the end of %loop and should instead hoist
1141 ; CHECK-LABEL: @same_destination_branch
1142 define i32 @same_destination_branch(i32 %arg1, i32 %arg2) {
1143 ; CHECK-LABEL: entry:
1144 ; CHECK-DAG: %cmp1 = icmp ne i32 %arg2, 0
1145 ; CHECK-DAG: %val = add i32 %arg1, 1
1146 ; CHECK: br label %loop
1150 ; CHECK-LABEL: loop:
1151 ; CHECK: %phi = phi i32 [ 0, %entry ], [ %add, %then ]
1153 %phi = phi i32 [ 0, %entry ], [ %add, %then ]
1154 %add = add i32 %phi, 1
1155 %cmp1 = icmp ne i32 %arg2, 0
1156 br i1 %cmp1, label %if, label %if
1159 %val = add i32 %arg1, 1
1163 %cmp2 = icmp ne i32 %val, %phi
1164 br i1 %cmp2, label %loop, label %end
1170 ; Diamond-like control flow but the left/right blocks actually have the same
1172 ; TODO: We could potentially hoist all of phi2-4, but currently only hoist phi2.
1173 ; CHECK-LABEL: @diamond_like_same_destinations
1174 define i32 @diamond_like_same_destinations(i32 %arg1, i32 %arg2) {
1175 ; CHECK-LABEL: entry:
1176 ; CHECK-DAG: %cmp1 = icmp ne i32 %arg1, 0
1177 ; CHECK-DAG: %cmp2 = icmp ugt i32 %arg2, 1
1178 ; CHECK-DAG: %cmp3 = icmp ugt i32 %arg2, 2
1179 ; CHECK-ENABLED: br i1 %cmp1, label %[[LEFT1_LICM:.*]], label %[[RIGHT1_LICM:.*]]
1183 ; CHECK-ENABLED: [[LEFT1_LICM]]:
1184 ; CHECK-ENABLED: br label %[[LEFT2_LICM:.*]]
1186 ; CHECK-ENABLED: [[RIGHT1_LICM]]:
1187 ; CHECK-ENABLED: br label %[[LEFT2_LICM]]
1189 ; CHECK-ENABLED: [[LEFT2_LICM]]:
1190 ; CHECK-ENABLED: %phi2 = phi i32 [ 0, %[[LEFT1_LICM]] ], [ 1, %[[RIGHT1_LICM]] ]
1191 ; CHECK: br label %loop
1194 %phi1 = phi i32 [ 0, %entry ], [ %add, %loopend ]
1195 %add = add i32 %phi1, 1
1196 %cmp1 = icmp ne i32 %arg1, 0
1197 br i1 %cmp1, label %left1, label %right1
1200 %cmp2 = icmp ugt i32 %arg2, 1
1201 br i1 %cmp2, label %left2, label %right2
1204 %cmp3 = icmp ugt i32 %arg2, 2
1205 br i1 %cmp3, label %left2, label %right2
1207 ; CHECK-LABEL: left2:
1208 ; CHECK-DISABLED: %phi2 = phi i32 [ 0, %left1 ], [ 1, %right1 ]
1210 %phi2 = phi i32 [ 0, %left1 ], [ 1, %right1 ]
1213 ; CHECK-LABEL: right2:
1214 ; CHECK: %phi3 = phi i32 [ 2, %left1 ], [ 3, %right1 ]
1216 %phi3 = phi i32 [ 2, %left1 ], [ 3, %right1 ]
1219 ; CHECK-LABEL: loopend:
1220 ; CHECK: %phi4 = phi i32 [ %phi2, %left2 ], [ %phi3, %right2 ]
1222 %phi4 = phi i32 [ %phi2, %left2 ], [ %phi3, %right2 ]
1223 %cmp4 = icmp ne i32 %phi1, 32
1224 br i1 %cmp4, label %loop, label %end
1230 ; A phi with multiple incoming values for the same block due to a branch with
1231 ; two destinations that are actually the same. We can't hoist this.
1232 ; TODO: This could be hoisted by erasing one of the incoming values.
1233 ; CHECK-LABEL: @phi_multiple_values_same_block
1234 define i32 @phi_multiple_values_same_block(i32 %arg, i1 %arg2) {
1235 ; CHECK-LABEL: entry:
1236 ; CHECK: %cmp = icmp sgt i32 %arg, 4
1238 ; CHECK: br label %loop
1243 %cmp = icmp sgt i32 %arg, 4
1244 br i1 %cmp, label %if, label %then
1247 br i1 %arg2, label %then, label %then
1250 %phi = phi i32 [ %arg, %loop ], [ 1, %if ], [ 1, %if ]
1251 br i1 %arg2, label %exit, label %loop
1257 ; %phi is conditionally used in %d, and the store that %d is used in cannot be
1258 ; hoisted. This means that we have to rehoist %d, but have to make sure to
1259 ; rehoist it after %phi.
1260 ; CHECK-LABEL: @phi_conditional_use
1261 define i64 @phi_conditional_use(i32 %f, ptr %g) {
1262 ; CHECK-LABEL: entry:
1263 ; CHECK: %cmp1 = icmp eq i32 %f, 1
1264 ; CHECK: %cmp2 = icmp eq i32 %f, 0
1265 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_END_LICM:.*]], label %[[IF_THEN_LICM:.*]]
1267 %cmp1 = icmp eq i32 %f, 1
1268 %cmp2 = icmp eq i32 %f, 0
1271 ; CHECK-ENABLED: [[IF_THEN_LICM]]:
1272 ; CHECK-ENABLED: br label %[[IF_END_LICM]]
1274 ; CHECK-ENABLED: [[IF_END_LICM]]:
1275 ; CHECK-ENABLED: %phi = phi i64 [ 0, %entry ], [ 1, %[[IF_THEN_LICM]] ]
1276 ; CHECK-ENABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi
1277 ; CHECK-ENABLED: i1 %cmp2, label %[[LOOP_BACKEDGE_LICM:.*]], label %[[IF_THEN2_LICM:.*]]
1279 ; CHECK-ENABLED: [[IF_THEN2_LICM]]:
1280 ; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]
1282 ; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:
1283 ; CHECK: br label %loop
1286 br i1 %cmp1, label %if.end, label %if.then
1291 ; CHECK-LABEL: if.end:
1292 ; CHECK-DISABLED: %phi = phi i64 [ 0, %loop ], [ 1, %if.then ]
1294 %phi = phi i64 [ 0, %loop ], [ 1, %if.then ]
1295 br i1 %cmp2, label %loop.backedge, label %if.then2
1297 ; CHECK-LABEL: if.then2:
1298 ; CHECK-DISABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi
1300 %d = getelementptr inbounds i32, ptr %g, i64 %phi
1301 store i32 1, ptr %d, align 4
1302 br label %loop.backedge
1308 ; As above, but we have two such phis
1309 ; CHECK-LABEL: @phi_conditional_use_twice
1310 define i64 @phi_conditional_use_twice(i32 %f, ptr %g) {
1311 ; CHECK-LABEL: entry:
1312 ; CHECK: %cmp1 = icmp eq i32 %f, 1
1313 ; CHECK: %cmp2 = icmp eq i32 %f, 0
1314 ; CHECK-ENABLED: br i1 %cmp1, label %[[IF_END_LICM:.*]], label %[[IF_THEN_LICM:.*]]
1316 %cmp1 = icmp eq i32 %f, 1
1317 %cmp2 = icmp eq i32 %f, 0
1318 %cmp3 = icmp sgt i32 %f, 0
1321 ; CHECK-ENABLED: [[IF_THEN_LICM]]:
1322 ; CHECK-ENABLED: br label %[[IF_END_LICM]]
1324 ; CHECK-ENABLED: [[IF_END_LICM]]:
1325 ; CHECK-ENABLED: %phi1 = phi i64 [ 0, %entry ], [ 1, %[[IF_THEN_LICM]] ]
1326 ; CHECK-ENABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi1
1327 ; CHECK-ENABLED: i1 %cmp2, label %[[IF_END2_LICM:.*]], label %[[IF_THEN2_LICM:.*]]
1329 ; CHECK-ENABLED: [[IF_THEN2_LICM]]:
1330 ; CHECK-ENABLED: br label %[[IF_END2_LICM]]
1332 ; CHECK-ENABLED: [[IF_END2_LICM]]:
1333 ; CHECK-ENABLED: %phi2 = phi i64 [ 2, %[[IF_END_LICM]] ], [ 3, %[[IF_THEN2_LICM]] ]
1334 ; CHECK-ENABLED: %e = getelementptr inbounds i32, ptr %g, i64 %phi2
1335 ; CHECK-ENABLED: i1 %cmp3, label %[[LOOP_BACKEDGE_LICM:.*]], label %[[IF_THEN3_LICM:.*]]
1337 ; CHECK-ENABLED: [[IF_THEN3_LICM]]:
1338 ; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]
1340 ; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:
1341 ; CHECK: br label %loop
1344 br i1 %cmp1, label %if.end, label %if.then
1349 ; CHECK-LABEL: if.end:
1350 ; CHECK-DISABLED: %phi1 = phi i64 [ 0, %loop ], [ 1, %if.then ]
1352 %phi1 = phi i64 [ 0, %loop ], [ 1, %if.then ]
1353 br i1 %cmp2, label %if.end2, label %if.then2
1355 ; CHECK-LABEL: if.then2:
1356 ; CHECK-DISABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi1
1358 %d = getelementptr inbounds i32, ptr %g, i64 %phi1
1359 store i32 1, ptr %d, align 4
1362 ; CHECK-LABEL: if.end2:
1363 ; CHECK-DISABLED: %phi2 = phi i64 [ 2, %if.end ], [ 3, %if.then2 ]
1365 %phi2 = phi i64 [ 2, %if.end ], [ 3, %if.then2 ]
1366 br i1 %cmp3, label %loop.backedge, label %if.then3
1368 ; CHECK-LABEL: if.then3:
1369 ; CHECK-DISABLED: %e = getelementptr inbounds i32, ptr %g, i64 %phi2
1371 %e = getelementptr inbounds i32, ptr %g, i64 %phi2
1372 store i32 1, ptr %e, align 4
1373 br label %loop.backedge
1379 ; The order that we hoist instructions from the loop is different to the textual
1380 ; order in the function. Check that we can rehoist this correctly.
1381 ; CHECK-LABEL: @rehoist_wrong_order_1
1382 define void @rehoist_wrong_order_1(ptr %ptr, i1 %arg) {
1383 ; CHECK-LABEL: entry
1384 ; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
1385 ; CHECK-DAG: %gep3 = getelementptr inbounds i32, ptr %ptr, i64 3
1386 ; CHECK-DAG: %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
1387 ; CHECK-ENABLED: br i1 %arg, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]
1391 ; CHECK-ENABLED: [[IF1_LICM]]:
1392 ; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM:.*]]
1394 ; CHECK-ENABLED: [[ELSE1_LICM]]:
1395 ; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]
1397 ; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:
1398 ; CHECK-ENABLED: br i1 %arg, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]
1400 ; CHECK-ENABLED: [[IF3_LICM]]:
1401 ; CHECK-ENABLED: br label %[[END_LICM]]
1403 ; CHECK-ENABLED: [[END_LICM]]:
1404 ; CHECK: br label %loop
1407 br i1 %arg, label %if1, label %else1
1410 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
1411 store i32 0, ptr %gep1, align 4
1412 br label %loop.backedge
1415 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
1416 store i32 0, ptr %gep2, align 4
1417 br i1 %arg, label %if2, label %loop.backedge
1420 br i1 %arg, label %if3, label %end
1423 %gep3 = getelementptr inbounds i32, ptr %ptr, i64 3
1424 store i32 0, ptr %gep3, align 4
1428 br label %loop.backedge
1435 ; CHECK-LABEL: @rehoist_wrong_order_2
1436 define void @rehoist_wrong_order_2(ptr %ptr, i1 %arg) {
1437 ; CHECK-LABEL: entry
1438 ; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
1439 ; CHECK-DAG: %gep3 = getelementptr inbounds i32, ptr %gep2, i64 3
1440 ; CHECK-DAG: %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
1441 ; CHECK-ENABLED: br i1 %arg, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]
1445 ; CHECK-ENABLED: [[IF1_LICM]]:
1446 ; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM:.*]]
1448 ; CHECK-ENABLED: [[ELSE1_LICM]]:
1449 ; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]
1451 ; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:
1452 ; CHECK-ENABLED: br i1 %arg, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]
1454 ; CHECK-ENABLED: [[IF3_LICM]]:
1455 ; CHECK-ENABLED: br label %[[END_LICM]]
1457 ; CHECK-ENABLED: [[END_LICM]]:
1458 ; CHECK: br label %loop
1461 br i1 %arg, label %if1, label %else1
1464 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
1465 store i32 0, ptr %gep1, align 4
1466 br label %loop.backedge
1469 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
1470 store i32 0, ptr %gep2, align 4
1471 br i1 %arg, label %if2, label %loop.backedge
1474 br i1 %arg, label %if3, label %end
1477 %gep3 = getelementptr inbounds i32, ptr %gep2, i64 3
1478 store i32 0, ptr %gep3, align 4
1482 br label %loop.backedge
1488 ; CHECK-LABEL: @rehoist_wrong_order_3
1489 define void @rehoist_wrong_order_3(ptr %ptr, i1 %arg) {
1490 ; CHECK-LABEL: entry
1491 ; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
1492 ; CHECK-DAG: %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
1493 ; CHECK-ENABLED: br i1 %arg, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]
1497 ; CHECK-ENABLED: [[IF1_LICM]]:
1498 ; CHECK-ENABLED: br label %[[IF2_LICM:.*]]
1500 ; CHECK-ENABLED: [[ELSE1_LICM]]:
1501 ; CHECK-ENABLED: br label %[[IF2_LICM]]
1503 ; CHECK-ENABLED: [[IF2_LICM]]:
1504 ; CHECK-ENABLED: %phi = phi ptr [ %gep1, %[[IF1_LICM]] ], [ %gep2, %[[ELSE1_LICM]] ]
1505 ; CHECK-ENABLED: %gep3 = getelementptr inbounds i32, ptr %phi, i64 3
1506 ; CHECK-ENABLED: br i1 %arg, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]
1508 ; CHECK-ENABLED: [[IF3_LICM]]:
1509 ; CHECK-ENABLED: br label %[[END_LICM]]
1511 ; CHECK-ENABLED: [[END_LICM]]:
1512 ; CHECK: br label %loop
1515 br i1 %arg, label %if1, label %else1
1518 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
1519 store i32 0, ptr %gep1, align 4
1523 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
1524 store i32 0, ptr %gep2, align 4
1525 br i1 %arg, label %if2, label %loop.backedge
1528 %phi = phi ptr [ %gep1, %if1 ], [ %gep2, %else1 ]
1529 br i1 %arg, label %if3, label %end
1532 %gep3 = getelementptr inbounds i32, ptr %phi, i64 3
1533 store i32 0, ptr %gep3, align 4
1537 br label %loop.backedge