forked from OSchip/llvm-project
1409 lines
45 KiB
LLVM
1409 lines
45 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -loop-simplifycfg < %s | FileCheck %s
|
|
; RUN: opt -S -passes='require<domtree>,loop(simplify-cfg)' < %s | FileCheck %s
|
|
; RUN: opt -S -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa < %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
|
|
}
|
|
|
|
; 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:%.*]], [[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 [[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 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:%.*]], [[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 [[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]
|
|
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_propogate_test_branch_loop(i32 %end) {
|
|
; CHECK-LABEL: @dead_block_propogate_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 [[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 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_propogate_test_switch_loop(i32 %end) {
|
|
; CHECK-LABEL: @dead_block_propogate_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 [[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]
|
|
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) {
|
|
; CHECK-LABEL: @dead_exit_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_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ]
|
|
; CHECK-NEXT: br label [[DUMMY:%.*]]
|
|
; CHECK: dummy:
|
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
|
; CHECK: backedge:
|
|
; 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: exit.loopexit:
|
|
; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[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
|
|
|
|
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: 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_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I]], [[HEADER]] ], [ [[I]], [[HEADER]] ]
|
|
; CHECK-NEXT: br label [[DUMMY:%.*]]
|
|
; CHECK: dummy:
|
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
|
; CHECK: backedge:
|
|
; 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: exit.loopexit:
|
|
; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[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:%.*]], [[BACKEDGE:%.*]] ]
|
|
; CHECK-NEXT: br i1 true, label [[LIVE_PREHEADER:%.*]], label [[DEAD_PREHEADER:%.*]]
|
|
; CHECK: live_preheader:
|
|
; CHECK-NEXT: br label [[LIVE_LOOP:%.*]]
|
|
; CHECK: live_loop:
|
|
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[LIVE_PREHEADER]] ], [ [[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: br label [[BACKEDGE]]
|
|
; CHECK: dead_preheader:
|
|
; CHECK-NEXT: br label [[DEAD_LOOP:%.*]]
|
|
; CHECK: dead_loop:
|
|
; CHECK-NEXT: [[B:%.*]] = phi i32 [ 0, [[DEAD_PREHEADER]] ], [ [[B_INC:%.*]], [[DEAD_LOOP]] ]
|
|
; CHECK-NEXT: [[B_INC]] = add i32 [[B]], 1
|
|
; CHECK-NEXT: [[CMP_B:%.*]] = icmp slt i32 [[B_INC]], [[END]]
|
|
; CHECK-NEXT: br i1 [[CMP_B]], label [[DEAD_LOOP]], label [[EXIT_B:%.*]]
|
|
; CHECK: exit.b:
|
|
; CHECK-NEXT: br label [[BACKEDGE]]
|
|
; CHECK: backedge:
|
|
; 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]], [[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 %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:%.*]], [[BACKEDGE:%.*]] ]
|
|
; CHECK-NEXT: switch i32 1, label [[DEAD_PREHEADER:%.*]] [
|
|
; CHECK-NEXT: i32 0, label [[DEAD_PREHEADER]]
|
|
; CHECK-NEXT: i32 1, label [[LIVE_PREHEADER:%.*]]
|
|
; CHECK-NEXT: i32 2, label [[DEAD_PREHEADER]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: live_preheader:
|
|
; CHECK-NEXT: br label [[LIVE_LOOP:%.*]]
|
|
; CHECK: live_loop:
|
|
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[LIVE_PREHEADER]] ], [ [[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: br label [[BACKEDGE]]
|
|
; CHECK: dead_preheader:
|
|
; CHECK-NEXT: br label [[DEAD_LOOP:%.*]]
|
|
; CHECK: dead_loop:
|
|
; CHECK-NEXT: [[B:%.*]] = phi i32 [ 0, [[DEAD_PREHEADER]] ], [ [[B_INC:%.*]], [[DEAD_LOOP]] ]
|
|
; CHECK-NEXT: [[B_INC]] = add i32 [[B]], 1
|
|
; CHECK-NEXT: [[CMP_B:%.*]] = icmp slt i32 [[B_INC]], [[END]]
|
|
; CHECK-NEXT: br i1 [[CMP_B]], label [[DEAD_LOOP]], label [[EXIT_B:%.*]]
|
|
; CHECK: exit.b:
|
|
; CHECK-NEXT: br label [[BACKEDGE]]
|
|
; CHECK: backedge:
|
|
; 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]], [[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_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: 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 true, 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 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: 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 true, 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 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 @no_live_block_test_branch_loop(i1 %c, i32 %end) {
|
|
; CHECK-LABEL: @no_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 i1 true, label [[BACKEDGE]], label [[LIVE]]
|
|
; 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
|
|
}
|
|
|
|
define i32 @no_live_block_test_switch_loop(i1 %c, i32 %end) {
|
|
; CHECK-LABEL: @no_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: switch i32 1, label [[LIVE]] [
|
|
; CHECK-NEXT: i32 0, label [[LIVE]]
|
|
; CHECK-NEXT: i32 1, label [[BACKEDGE]]
|
|
; CHECK-NEXT: i32 2, label [[LIVE]]
|
|
; CHECK-NEXT: ]
|
|
; 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
|
|
}
|
|
|
|
; 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:%.*]], [[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 [[CMP]], 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 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:%.*]], [[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 [[CMP]], 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]
|
|
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: 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 true, 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 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: 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 [[HEADER]] [
|
|
; CHECK-NEXT: i32 0, label [[OUTER_BACKEDGE]]
|
|
; 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 %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: 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 true, 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 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: 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 [[HEADER]] [
|
|
; CHECK-NEXT: i32 0, label [[OUTER_BACKEDGE]]
|
|
; 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 %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
|
|
}
|