| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals | |
| ; REQUIRES: asserts | |
| ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s | |
| ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(loop-simplifycfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s | |
| ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes=loop-simplifycfg -verify-memoryssa -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s | |
| target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" | |
| ; Make sure that we can eliminate a provably dead backedge. | |
| define i32 @dead_backedge_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_backedge_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[I_1:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100 | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]] | |
| ; CHECK: header.backedge: | |
| ; CHECK-NEXT: [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ] | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: dead_backedge: | |
| ; CHECK-NEXT: [[I_2]] = add i32 [[I_1]], 10 | |
| ; CHECK-NEXT: br i1 false, label [[HEADER_BACKEDGE]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_2_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge] | |
| %i.1 = add i32 %i, 1 | |
| %cmp1 = icmp slt i32 %i.1, 100 | |
| br i1 %cmp1, label %header, label %dead_backedge | |
| dead_backedge: | |
| %i.2 = add i32 %i.1, 10 | |
| br i1 false, label %header, label %exit | |
| exit: | |
| ret i32 %i.2 | |
| } | |
| ; Make sure that we can eliminate a provably dead backedge with switch. | |
| define i32 @dead_backedge_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_backedge_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[I_1:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100 | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]] | |
| ; CHECK: header.backedge: | |
| ; CHECK-NEXT: [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ] | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: dead_backedge: | |
| ; CHECK-NEXT: [[I_2]] = add i32 [[I_1]], 10 | |
| ; CHECK-NEXT: switch i32 1, label [[EXIT:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[HEADER_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_2_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge] | |
| %i.1 = add i32 %i, 1 | |
| %cmp1 = icmp slt i32 %i.1, 100 | |
| br i1 %cmp1, label %header, label %dead_backedge | |
| dead_backedge: | |
| %i.2 = add i32 %i.1, 10 | |
| switch i32 1, label %exit [i32 0, label %header] | |
| exit: | |
| ret i32 %i.2 | |
| } | |
| ; Check that we can eliminate a triangle. | |
| define i32 @dead_block_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_block_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can eliminate dead branches of a switch. | |
| define i32 @dead_block_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_block_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead [i32 0, label %dead | |
| i32 1, label %backedge | |
| i32 2, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can eliminate several dead blocks. | |
| define i32 @dead_block_propagate_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_block_propagate_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %dummy | |
| dummy: | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dummy] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can eliminate several blocks while removing a switch. | |
| define i32 @dead_block_propagate_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_block_propagate_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead [i32 0, label %dead | |
| i32 1, label %backedge | |
| i32 2, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %dummy | |
| dummy: | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dummy] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we preserve static reachibility of a dead exit block while deleting | |
| ; a branch. | |
| define i32 @dead_exit_test_branch_loop(i32 %end) !prof !{!"function_entry_count", i32 10} { | |
| ; CHECK-LABEL: @dead_exit_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[DEAD:%.*]] | |
| ; CHECK-NEXT: ], !prof [[PROF1:![0-9]+]] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: br label [[DUMMY:%.*]] | |
| ; CHECK: dummy: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ poison, [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ] | |
| ; CHECK-NEXT: ret i32 [[I_1]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %backedge, label %dead, !prof !{!"branch_weights", i32 10, i32 1} | |
| dead: | |
| br label %dummy | |
| dummy: | |
| br label %exit | |
| backedge: | |
| %i.inc = add i32 %i, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy] | |
| ret i32 %i.1 | |
| } | |
| ; Check that we preserve static reachibility of a dead exit block while deleting | |
| ; a switch. | |
| define i32 @dead_exit_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_exit_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[DEAD:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: br label [[DUMMY:%.*]] | |
| ; CHECK: dummy: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ poison, [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ] | |
| ; CHECK-NEXT: ret i32 [[I_1]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead [i32 0, label %dead | |
| i32 1, label %backedge | |
| i32 2, label %dead] | |
| dead: | |
| br label %dummy | |
| dummy: | |
| br label %exit | |
| backedge: | |
| %i.inc = add i32 %i, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy] | |
| ret i32 %i.1 | |
| } | |
| ; Check that we can completely eliminate the current loop, branch case. | |
| define i32 @dead_loop_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_loop_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 false, label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %dummy | |
| dummy: | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dummy] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 false, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can completely eliminate the current loop, switch case. | |
| define i32 @dead_loop_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_loop_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 1, label [[DEAD:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[DEAD]] | |
| ; CHECK-NEXT: i32 1, label [[BACKEDGE]] | |
| ; CHECK-NEXT: i32 2, label [[DEAD]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 false, label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead [i32 0, label %dead | |
| i32 1, label %backedge | |
| i32 2, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %dummy | |
| dummy: | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dummy] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 false, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can delete a dead inner loop entirely. | |
| define i32 @dead_sub_loop_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_sub_loop_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[EXIT_A:%.*]] ] | |
| ; CHECK-NEXT: br label [[LIVE_LOOP:%.*]] | |
| ; CHECK: live_loop: | |
| ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ] | |
| ; CHECK-NEXT: [[A_INC]] = add i32 [[A]], 1 | |
| ; CHECK-NEXT: [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A]] | |
| ; CHECK: exit.a: | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[EXIT_A]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %live_preheader, label %dead_preheader | |
| live_preheader: | |
| br label %live_loop | |
| live_loop: | |
| %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop] | |
| %a.inc = add i32 %a, 1 | |
| %cmp.a = icmp slt i32 %a.inc, %end | |
| br i1 %cmp.a, label %live_loop, label %exit.a | |
| exit.a: | |
| br label %backedge | |
| dead_preheader: | |
| br label %dead_loop | |
| dead_loop: | |
| %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop] | |
| %b.inc = add i32 %b, 1 | |
| %cmp.b = icmp slt i32 %b.inc, %end | |
| br i1 %cmp.b, label %dead_loop, label %exit.b | |
| exit.b: | |
| br label %backedge | |
| backedge: | |
| %i.inc = add i32 %i, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @dead_sub_loop_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @dead_sub_loop_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[EXIT_A:%.*]] ] | |
| ; CHECK-NEXT: br label [[LIVE_LOOP:%.*]] | |
| ; CHECK: live_loop: | |
| ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ] | |
| ; CHECK-NEXT: [[A_INC]] = add i32 [[A]], 1 | |
| ; CHECK-NEXT: [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A]] | |
| ; CHECK: exit.a: | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[EXIT_A]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead_preheader [i32 0, label %dead_preheader | |
| i32 1, label %live_preheader | |
| i32 2, label %dead_preheader] | |
| live_preheader: | |
| br label %live_loop | |
| live_loop: | |
| %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop] | |
| %a.inc = add i32 %a, 1 | |
| %cmp.a = icmp slt i32 %a.inc, %end | |
| br i1 %cmp.a, label %live_loop, label %exit.a | |
| exit.a: | |
| br label %backedge | |
| dead_preheader: | |
| br label %dead_loop | |
| dead_loop: | |
| %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop] | |
| %b.inc = add i32 %b, 1 | |
| %cmp.b = icmp slt i32 %b.inc, %end | |
| br i1 %cmp.b, label %dead_loop, label %exit.b | |
| exit.b: | |
| br label %backedge | |
| backedge: | |
| %i.inc = add i32 %i, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we preserve static reachability of an exit block even if we prove | |
| ; that the loop is infinite. Branch case. | |
| define i32 @inf_loop_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @inf_loop_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[EXIT:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret i32 poison | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %dummy | |
| dummy: | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dummy] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 true, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @inf_loop_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @inf_loop_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[EXIT:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret i32 poison | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead [i32 0, label %dead | |
| i32 1, label %backedge | |
| i32 2, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %dummy | |
| dummy: | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dummy] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 true, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that when the block is not actually dead, we don't remove it. | |
| define i32 @live_block_test_branch_loop(i1 %c, i32 %end) { | |
| ; CHECK-LABEL: @live_block_test_branch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]] | |
| ; CHECK: check: | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: live: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 %c, label %check, label %live | |
| check: | |
| br i1 true, label %backedge, label %live | |
| live: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %check], [%i.2, %live] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that when the block is not actually dead, we don't remove it. Version | |
| ; with Phi node. | |
| define i32 @live_block_test_branch_loop_phis(i1 %c, i32 %end) { | |
| ; CHECK-LABEL: @live_block_test_branch_loop_phis( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]] | |
| ; CHECK: check: | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: live: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 %c, label %check, label %live | |
| check: | |
| br i1 true, label %backedge, label %live | |
| live: | |
| %phi = phi i32 [ 1, %header ], [ -1, %check ] | |
| %i.2 = add i32 %i, %phi | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %check], [%i.2, %live] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @live_block_test_switch_loop(i1 %c, i32 %end) { | |
| ; CHECK-LABEL: @live_block_test_switch_loop( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]] | |
| ; CHECK: check: | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: live: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 %c, label %check, label %live | |
| check: | |
| switch i32 1, label %live [i32 0, label %live | |
| i32 1, label %backedge | |
| i32 2, label %live] | |
| live: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %check], [%i.2, %live] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @live_block_test_switch_loop_phis(i1 %c, i32 %end) { | |
| ; CHECK-LABEL: @live_block_test_switch_loop_phis( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]] | |
| ; CHECK: check: | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: live: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA]] | |
| ; | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 %c, label %check, label %live | |
| check: | |
| switch i32 1, label %live [i32 0, label %live | |
| i32 1, label %backedge | |
| i32 2, label %live] | |
| live: | |
| %phi = phi i32 [ 1, %header ], [ -1, %check ], [ -1, %check ], [ -1, %check ] | |
| %i.2 = add i32 %i, %phi | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %check], [%i.2, %live] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can remove part of blocks of inner loop while the loop still | |
| ; preserves, in presence of outer loop. | |
| define i32 @partial_sub_loop_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @partial_sub_loop_test_branch_loop( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[OUTER_BACKEDGE]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %outer_backedge | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @partial_sub_loop_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @partial_sub_loop_test_switch_loop( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[OUTER_BACKEDGE]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| switch i32 1, label %dead [i32 0, label %dead | |
| i32 1, label %backedge | |
| i32 2, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %header], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| %cmp = icmp slt i32 %i.inc, %end | |
| br i1 %cmp, label %header, label %outer_backedge | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Check that we can completely delete inner loop and preserve the outer loop. | |
| define i32 @full_sub_loop_test_branch_loop(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_branch_loop( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: br i1 false, label [[BACKEDGE]], label [[DEAD:%.*]] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: br i1 false, label [[HEADER]], label [[OUTER_BACKEDGE]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| br i1 false, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| br i1 false, label %header, label %outer_backedge | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @full_sub_loop_test_switch_loop(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_switch_loop( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: switch i32 1, label [[DEAD:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: switch i32 1, label [[OUTER_BACKEDGE]] [ | |
| ; CHECK-NEXT: i32 0, label [[HEADER]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| switch i32 1, label %dead [i32 0, label %backedge] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| switch i32 1, label %outer_backedge [i32 0, label %header] | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| ; Inverted condition in live_part. | |
| define i32 @full_sub_loop_test_branch_loop_inverse_1(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_branch_loop_inverse_1( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: br i1 false, label [[HEADER]], label [[OUTER_BACKEDGE]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| br i1 false, label %header, label %outer_backedge | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @full_sub_loop_test_switch_loop_inverse_1(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_switch_loop_inverse_1( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: switch i32 1, label [[BACKEDGE]] [ | |
| ; CHECK-NEXT: i32 0, label [[DEAD:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: dead: | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_1]], 1 | |
| ; CHECK-NEXT: switch i32 1, label [[OUTER_BACKEDGE]] [ | |
| ; CHECK-NEXT: i32 0, label [[HEADER]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| switch i32 1, label %backedge [i32 0, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| switch i32 1, label %outer_backedge [i32 0, label %header] | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @full_sub_loop_test_branch_loop_inverse_2(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_branch_loop_inverse_2( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_2]], 1 | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ poison, [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| br i1 false, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| br i1 true, label %header, label %outer_backedge | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @full_sub_loop_test_switch_loop_inverse_2(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_switch_loop_inverse_2( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I_2]], 1 | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ poison, [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| switch i32 1, label %dead [i32 0, label %backedge] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| switch i32 1, label %header [i32 0, label %outer_backedge] | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @full_sub_loop_test_branch_loop_inverse_3(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_branch_loop_inverse_3( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ poison, [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| br i1 true, label %backedge, label %dead | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| br i1 true, label %header, label %outer_backedge | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @full_sub_loop_test_switch_loop_inverse_3(i32 %end) { | |
| ; CHECK-LABEL: @full_sub_loop_test_switch_loop_inverse_3( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer_header: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: preheader.split: | |
| ; CHECK-NEXT: br label [[HEADER:%.*]] | |
| ; CHECK: header: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ] | |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I]], [[I]] | |
| ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: br label [[HEADER]] | |
| ; CHECK: outer_backedge: | |
| ; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ poison, [[OUTER_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_INC_LCSSA_LCSSA]] | |
| ; | |
| entry: | |
| br label %outer_header | |
| outer_header: | |
| %j = phi i32 [0, %entry], [%j.inc, %outer_backedge] | |
| br label %preheader | |
| preheader: | |
| br label %header | |
| header: | |
| %i = phi i32 [0, %preheader], [%i.inc, %backedge] | |
| br label %live_part | |
| live_part: | |
| %mul = mul i32 %i, %i | |
| switch i32 1, label %backedge [i32 0, label %dead] | |
| dead: | |
| %i.2 = add i32 %i, 1 | |
| br label %backedge | |
| backedge: | |
| %i.1 = phi i32 [%i, %live_part], [%i.2, %dead] | |
| %i.inc = add i32 %i.1, 1 | |
| switch i32 1, label %header [i32 0, label %outer_backedge] | |
| outer_backedge: | |
| %j.inc = add i32 %j, 1 | |
| %cmp.j = icmp slt i32 %j.inc, %end | |
| br i1 %cmp.j, label %outer_header, label %exit | |
| exit: | |
| ret i32 %i.inc | |
| } | |
| define i32 @exit_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) { | |
| ; CHECK-LABEL: @exit_branch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 0, label [[LOOP_2_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_2.split: | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2_SPLIT]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br label [[LOOP_3]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %loop_1_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 true, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @exit_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) { | |
| ; CHECK-LABEL: @exit_switch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: switch i32 0, label [[LOOP_2_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_2.split: | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2_SPLIT]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br label [[LOOP_3]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %loop_1_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| switch i32 1, label %loop_3 [i32 0, label %loop_2_backedge] | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_branch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br i1 false, label %loop_3_backedge, label %loop_1_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_switch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| switch i32 1, label %loop_1_backedge [i32 0, label %loop_3_backedge] | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_branch_from_inner_to_parent(i1 %cond1, i1 %cond2, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_branch_from_inner_to_parent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br i1 false, label %loop_3_backedge, label %loop_2_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_switch_from_inner_to_parent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: switch i32 1, label [[LOOP_2_BACKEDGE]] [ | |
| ; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| switch i32 1, label %loop_2_backedge [i32 0, label %loop_3_backedge] | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_subloop_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_subloop_branch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| br i1 false, label %loop_3_backedge, label %loop_1_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_subloop_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_subloop_switch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| switch i32 1, label %loop_1_backedge [i32 0, label %loop_3_backedge] | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_subloop_branch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_subloop_branch_from_inner_to_parent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| br i1 false, label %loop_3_backedge, label %loop_2_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_subloop_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_subloop_switch_from_inner_to_parent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: switch i32 1, label [[LOOP_2_BACKEDGE]] [ | |
| ; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| switch i32 1, label %loop_2_backedge [i32 0, label %loop_3_backedge] | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_complex_subloop_branch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_complex_subloop_branch_from_inner_to_parent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]] | |
| ; CHECK: intermediate_loop.backedge: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP]] | |
| ; CHECK: intermediate_block: | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_block | |
| intermediate_block: | |
| br i1 %cond2, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| br i1 false, label %loop_3_backedge, label %loop_2_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_complex_subloop_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_complex_subloop_switch_from_inner_to_parent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]] | |
| ; CHECK: intermediate_loop.backedge: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP]] | |
| ; CHECK: intermediate_block: | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: switch i32 1, label [[LOOP_2_BACKEDGE]] [ | |
| ; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_block | |
| intermediate_block: | |
| br i1 %cond2, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| switch i32 1, label %loop_2_backedge [i32 0, label %loop_3_backedge] | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_complex_subloop_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_complex_subloop_branch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]] | |
| ; CHECK: intermediate_loop.backedge: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP]] | |
| ; CHECK: intermediate_block: | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_block | |
| intermediate_block: | |
| br i1 %cond2, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| br i1 false, label %loop_3_backedge, label %loop_1_backedge | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @intermediate_complex_subloop_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) { | |
| ; CHECK-LABEL: @intermediate_complex_subloop_switch_from_inner_to_grandparent( | |
| ; CHECK-NEXT: preheader: | |
| ; CHECK-NEXT: br label [[LOOP_1:%.*]] | |
| ; CHECK: loop_1: | |
| ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_2:%.*]] | |
| ; CHECK: loop_2: | |
| ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_3:%.*]] | |
| ; CHECK: loop_3: | |
| ; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] | |
| ; CHECK: intermediate: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP:%.*]] | |
| ; CHECK: intermediate_loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]] | |
| ; CHECK: intermediate_loop.backedge: | |
| ; CHECK-NEXT: br label [[INTERMEDIATE_LOOP]] | |
| ; CHECK: intermediate_block: | |
| ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]] | |
| ; CHECK: intermediate_exit: | |
| ; CHECK-NEXT: switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: loop_3_backedge: | |
| ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 | |
| ; CHECK-NEXT: br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]] | |
| ; CHECK: loop_2_backedge: | |
| ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 | |
| ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]] | |
| ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]] | |
| ; CHECK: loop_1_backedge.loopexit: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge.loopexit1: | |
| ; CHECK-NEXT: br label [[LOOP_1_BACKEDGE]] | |
| ; CHECK: loop_1_backedge: | |
| ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ] | |
| ; CHECK-NEXT: ret i32 [[I_LCSSA]] | |
| ; | |
| preheader: | |
| br label %loop_1 | |
| loop_1: | |
| %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ] | |
| br label %loop_2 | |
| loop_2: | |
| %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ] | |
| br label %loop_3 | |
| loop_3: | |
| %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ] | |
| br i1 %cond1, label %loop_3_backedge, label %intermediate | |
| intermediate: | |
| br label %intermediate_loop | |
| intermediate_loop: | |
| br i1 %cond3, label %intermediate_loop, label %intermediate_block | |
| intermediate_block: | |
| br i1 %cond2, label %intermediate_loop, label %intermediate_exit | |
| intermediate_exit: | |
| switch i32 1, label %loop_1_backedge [i32 0, label %loop_3_backedge] | |
| loop_3_backedge: | |
| %k.next = add i32 %k, 1 | |
| br i1 %cond2, label %loop_3, label %loop_2_backedge | |
| loop_2_backedge: | |
| %j.next = add i32 %j, 1 | |
| %c_2 = icmp slt i32 %j.next, %N | |
| br i1 %c_2, label %loop_2, label %loop_1_backedge | |
| loop_1_backedge: | |
| %i.next = add i32 %i, 1 | |
| %c_1 = icmp slt i32 %i.next, %N | |
| br i1 %c_1, label %loop_1, label %exit | |
| exit: | |
| ret i32 %i | |
| } | |
| define i32 @complex_dead_subloop_branch(i1 %cond1, i1 %cond2, i1 %cond3) { | |
| ; CHECK-LABEL: @complex_dead_subloop_branch( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[LOOP]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[RESULT_LCSSA:%.*]] = phi i32 [ 0, [[LOOP]] ] | |
| ; CHECK-NEXT: ret i32 [[RESULT_LCSSA]] | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| br i1 true, label %latch, label %subloop | |
| subloop: | |
| br i1 %cond1, label %x, label %y | |
| x: | |
| br label %subloop_latch | |
| y: | |
| br label %subloop_latch | |
| subloop_latch: | |
| %dead_phi = phi i32 [ 1, %x ], [ 2, %y ] | |
| br i1 %cond2, label %latch, label %subloop | |
| latch: | |
| %result = phi i32 [ 0, %loop ], [ %dead_phi, %subloop_latch ] | |
| br i1 %cond3, label %loop, label %exit | |
| exit: | |
| ret i32 %result | |
| } | |
| define i32 @complex_dead_subloop_switch(i1 %cond1, i1 %cond2, i1 %cond3) { | |
| ; CHECK-LABEL: @complex_dead_subloop_switch( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[LOOP]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[RESULT_LCSSA:%.*]] = phi i32 [ 0, [[LOOP]] ] | |
| ; CHECK-NEXT: ret i32 [[RESULT_LCSSA]] | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| switch i32 1, label %latch [ i32 0, label %subloop ] | |
| subloop: | |
| br i1 %cond1, label %x, label %y | |
| x: | |
| br label %subloop_latch | |
| y: | |
| br label %subloop_latch | |
| subloop_latch: | |
| %dead_phi = phi i32 [ 1, %x ], [ 2, %y ] | |
| br i1 %cond2, label %latch, label %subloop | |
| latch: | |
| %result = phi i32 [ 0, %loop ], [ %dead_phi, %subloop_latch ] | |
| br i1 %cond3, label %loop, label %exit | |
| exit: | |
| ret i32 %result | |
| } | |
| define void @test_crash_01(i1 %arg, i32 %arg2) { | |
| ; CHECK-LABEL: @test_crash_01( | |
| ; CHECK-NEXT: bb: | |
| ; CHECK-NEXT: br label [[BB1:%.*]] | |
| ; CHECK: bb1: | |
| ; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB17:%.*]], label [[BB2:%.*]] | |
| ; CHECK: bb2: | |
| ; CHECK-NEXT: switch i32 0, label [[BB2_SPLIT:%.*]] [ | |
| ; CHECK-NEXT: i32 1, label [[BB19:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: bb2.split: | |
| ; CHECK-NEXT: br label [[BB3:%.*]] | |
| ; CHECK: bb3: | |
| ; CHECK-NEXT: switch i32 [[ARG2:%.*]], label [[BB16:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[BB15:%.*]] | |
| ; CHECK-NEXT: i32 1, label [[BB14:%.*]] | |
| ; CHECK-NEXT: i32 2, label [[BB13:%.*]] | |
| ; CHECK-NEXT: i32 3, label [[BB12:%.*]] | |
| ; CHECK-NEXT: i32 4, label [[BB11:%.*]] | |
| ; CHECK-NEXT: i32 5, label [[BB8:%.*]] | |
| ; CHECK-NEXT: i32 6, label [[BB10:%.*]] | |
| ; CHECK-NEXT: i32 7, label [[BB9:%.*]] | |
| ; CHECK-NEXT: i32 8, label [[BB7:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: bb7: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb8: | |
| ; CHECK-NEXT: switch i32 [[ARG2]], label [[BB28:%.*]] [ | |
| ; CHECK-NEXT: i32 0, label [[BB27:%.*]] | |
| ; CHECK-NEXT: i32 1, label [[BB26:%.*]] | |
| ; CHECK-NEXT: i32 2, label [[BB23:%.*]] | |
| ; CHECK-NEXT: i32 3, label [[BB24:%.*]] | |
| ; CHECK-NEXT: i32 4, label [[BB25:%.*]] | |
| ; CHECK-NEXT: i32 5, label [[BB29:%.*]] | |
| ; CHECK-NEXT: i32 6, label [[BB22:%.*]] | |
| ; CHECK-NEXT: i32 7, label [[BB20:%.*]] | |
| ; CHECK-NEXT: i32 8, label [[BB21:%.*]] | |
| ; CHECK-NEXT: ] | |
| ; CHECK: bb9: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb10: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb11: | |
| ; CHECK-NEXT: br label [[BB8]] | |
| ; CHECK: bb12: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb13: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb14: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb15: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb16: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb17: | |
| ; CHECK-NEXT: ret void | |
| ; CHECK: bb19: | |
| ; CHECK-NEXT: ret void | |
| ; CHECK: bb20: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb21: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb22: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb23: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb24: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb25: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb26: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb27: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb28: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: bb29: | |
| ; CHECK-NEXT: br label [[BB3]] | |
| ; | |
| bb: | |
| br label %bb1 | |
| bb1: ; preds = %bb | |
| br i1 %arg, label %bb17, label %bb2 | |
| bb2: ; preds = %bb1 | |
| br label %bb3 | |
| bb3: ; preds = %bb6, %bb2 | |
| br label %bb4 | |
| bb4: ; preds = %bb3 | |
| switch i32 0, label %bb5 [ | |
| i32 1, label %bb19 | |
| i32 2, label %bb18 | |
| ] | |
| bb5: ; preds = %bb4 | |
| switch i32 %arg2, label %bb16 [ | |
| i32 0, label %bb15 | |
| i32 1, label %bb14 | |
| i32 2, label %bb13 | |
| i32 3, label %bb12 | |
| i32 4, label %bb11 | |
| i32 5, label %bb8 | |
| i32 6, label %bb10 | |
| i32 7, label %bb9 | |
| i32 8, label %bb7 | |
| ] | |
| bb6: ; preds = %bb29, %bb18 | |
| br label %bb3 | |
| bb7: ; preds = %bb5 | |
| unreachable | |
| bb8: ; preds = %bb11, %bb5 | |
| switch i32 %arg2, label %bb28 [ | |
| i32 0, label %bb27 | |
| i32 1, label %bb26 | |
| i32 2, label %bb23 | |
| i32 3, label %bb24 | |
| i32 4, label %bb25 | |
| i32 5, label %bb29 | |
| i32 6, label %bb22 | |
| i32 7, label %bb20 | |
| i32 8, label %bb21 | |
| ] | |
| bb9: ; preds = %bb5 | |
| unreachable | |
| bb10: ; preds = %bb5 | |
| unreachable | |
| bb11: ; preds = %bb5 | |
| br label %bb8 | |
| bb12: ; preds = %bb5 | |
| unreachable | |
| bb13: ; preds = %bb5 | |
| unreachable | |
| bb14: ; preds = %bb5 | |
| unreachable | |
| bb15: ; preds = %bb5 | |
| unreachable | |
| bb16: ; preds = %bb5 | |
| unreachable | |
| bb17: ; preds = %bb1 | |
| ret void | |
| bb18: ; preds = %bb4 | |
| br label %bb6 | |
| bb19: ; preds = %bb4 | |
| ret void | |
| bb20: ; preds = %bb8 | |
| unreachable | |
| bb21: ; preds = %bb8 | |
| unreachable | |
| bb22: ; preds = %bb8 | |
| unreachable | |
| bb23: ; preds = %bb8 | |
| unreachable | |
| bb24: ; preds = %bb8 | |
| unreachable | |
| bb25: ; preds = %bb8 | |
| unreachable | |
| bb26: ; preds = %bb8 | |
| unreachable | |
| bb27: ; preds = %bb8 | |
| unreachable | |
| bb28: ; preds = %bb8 | |
| unreachable | |
| bb29: ; preds = %bb8 | |
| br label %bb6 | |
| } | |
| ;. | |
| ; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10} | |
| ; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 0} | |
| ;. |