
After #96127 landed, mshockwave reported that the pass was no longer threading SPEC2006/perlbench. After 96127 we started bailing out in `getStateDefMap` and rejecting the transformation because one of the unpredictable values was coming from inside the loop. There was no fundamental change in that function except that we started calling `Loop->contains(IncomingBB)` instead of `LoopBBs.count(IncomingBB)`. After some analysis I came to the conclusion that even before 96127 we would reject the transformation if we provided large enough limits on the path traversal (large enough so that LoopBBs contained blocks corresponding to that unpredictable value). In this patch I changed `getStateDefMap` to not terminate early on finding an unpredictable value, this is because `getPathsFromStateDefMap`, later, actually has checks to ensure that the final list of paths only have predictable values. As a result we can now partially thread functions like `negative6` in the tests that have some predictable paths. This patch does not really have any compile-time impact on the test suite without `-dfa-early-exit-heuristic=false` (early exit is enabled by default). Change-Id: Ie1633b370ed4a0eda8dea52650b40f6f66ef49a3
466 lines
24 KiB
LLVM
466 lines
24 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -passes=dfa-jump-threading -dfa-early-exit-heuristic=false %s | FileCheck %s
|
|
|
|
; These tests check if selects are unfolded properly for jump threading
|
|
; opportunities. There are three different patterns to consider:
|
|
; 1) Both operands are constant and the false branch is unfolded by default
|
|
; 2) One operand is constant and the other is another select to be unfolded. In
|
|
; this case a single select is sunk to a new block to unfold.
|
|
; 3) Both operands are a select, and both should be sunk to new blocks.
|
|
define i32 @test1(i32 %num) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COUNT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
|
|
; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[STATE_NEXT:%.*]], [[FOR_INC]] ]
|
|
; CHECK-NEXT: switch i32 [[STATE]], label [[FOR_INC_JT1:%.*]] [
|
|
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
|
|
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: for.body.jt2:
|
|
; CHECK-NEXT: [[COUNT_JT2:%.*]] = phi i32 [ [[INC_JT2:%.*]], [[FOR_INC_JT2:%.*]] ]
|
|
; CHECK-NEXT: [[STATE_JT2:%.*]] = phi i32 [ [[STATE_NEXT_JT2:%.*]], [[FOR_INC_JT2]] ]
|
|
; CHECK-NEXT: br label [[CASE2]]
|
|
; CHECK: for.body.jt1:
|
|
; CHECK-NEXT: [[COUNT_JT1:%.*]] = phi i32 [ [[INC_JT1:%.*]], [[FOR_INC_JT1]] ]
|
|
; CHECK-NEXT: [[STATE_JT1:%.*]] = phi i32 [ [[STATE_NEXT_JT1:%.*]], [[FOR_INC_JT1]] ]
|
|
; CHECK-NEXT: br label [[CASE1]]
|
|
; CHECK: case1:
|
|
; CHECK-NEXT: [[COUNT2:%.*]] = phi i32 [ [[COUNT_JT1]], [[FOR_BODY_JT1:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT2]]
|
|
; CHECK: case2:
|
|
; CHECK-NEXT: [[COUNT1:%.*]] = phi i32 [ [[COUNT_JT2]], [[FOR_BODY_JT2:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[COUNT1]], 50
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_INC_JT1]], label [[SEL_SI_UNFOLD_FALSE_JT2:%.*]]
|
|
; CHECK: sel.si.unfold.false:
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: sel.si.unfold.false.jt2:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI_JT2:%.*]] = phi i32 [ 2, [[CASE2]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT2]]
|
|
; CHECK: for.inc:
|
|
; CHECK-NEXT: [[STATE_NEXT]] = phi i32 [ poison, [[SEL_SI_UNFOLD_FALSE:%.*]] ]
|
|
; CHECK-NEXT: [[INC]] = add nsw i32 undef, 1
|
|
; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
|
|
; CHECK: for.inc.jt2:
|
|
; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ]
|
|
; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ]
|
|
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT4]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
|
|
; CHECK: for.inc.jt1:
|
|
; CHECK-NEXT: [[COUNT3:%.*]] = phi i32 [ [[COUNT]], [[FOR_BODY]] ], [ [[COUNT1]], [[CASE2]] ]
|
|
; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[CASE2]] ], [ 1, [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT3]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
|
|
; CHECK: for.end:
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%count = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ]
|
|
switch i32 %state, label %for.inc [
|
|
i32 1, label %case1
|
|
i32 2, label %case2
|
|
]
|
|
|
|
case1:
|
|
br label %for.inc
|
|
|
|
case2:
|
|
%cmp = icmp slt i32 %count, 50
|
|
%sel = select i1 %cmp, i32 1, i32 2
|
|
br label %for.inc
|
|
|
|
for.inc:
|
|
%state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ 2, %case1 ]
|
|
%inc = add nsw i32 %count, 1
|
|
%cmp.exit = icmp slt i32 %inc, %num
|
|
br i1 %cmp.exit, label %for.body, label %for.end
|
|
|
|
for.end:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @test2(i32 %num) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COUNT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
|
|
; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[STATE_NEXT:%.*]], [[FOR_INC]] ]
|
|
; CHECK-NEXT: switch i32 [[STATE]], label [[FOR_INC_JT1:%.*]] [
|
|
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
|
|
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: for.body.jt2:
|
|
; CHECK-NEXT: [[COUNT_JT2:%.*]] = phi i32 [ [[INC_JT2:%.*]], [[FOR_INC_JT2:%.*]] ]
|
|
; CHECK-NEXT: [[STATE_JT2:%.*]] = phi i32 [ [[STATE_NEXT_JT2:%.*]], [[FOR_INC_JT2]] ]
|
|
; CHECK-NEXT: br label [[CASE2]]
|
|
; CHECK: for.body.jt1:
|
|
; CHECK-NEXT: [[COUNT_JT1:%.*]] = phi i32 [ [[INC_JT1:%.*]], [[FOR_INC_JT1]] ]
|
|
; CHECK-NEXT: [[STATE_JT1:%.*]] = phi i32 [ [[STATE_NEXT_JT1:%.*]], [[FOR_INC_JT1]] ]
|
|
; CHECK-NEXT: br label [[CASE1]]
|
|
; CHECK: for.body.jt3:
|
|
; CHECK-NEXT: [[COUNT_JT3:%.*]] = phi i32 [ [[INC_JT3:%.*]], [[FOR_INC_JT3:%.*]] ]
|
|
; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ [[STATE_NEXT_JT3:%.*]], [[FOR_INC_JT3]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: case1:
|
|
; CHECK-NEXT: [[COUNT6:%.*]] = phi i32 [ [[COUNT_JT1]], [[FOR_BODY_JT1:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP_C1:%.*]] = icmp slt i32 [[COUNT6]], 50
|
|
; CHECK-NEXT: [[CMP2_C1:%.*]] = icmp slt i32 [[COUNT6]], 100
|
|
; CHECK-NEXT: br i1 [[CMP2_C1]], label [[STATE1_1_SI_UNFOLD_TRUE_JT1:%.*]], label [[STATE1_2_SI_UNFOLD_FALSE_JT3:%.*]]
|
|
; CHECK: case2:
|
|
; CHECK-NEXT: [[CMP_C2:%.*]] = icmp slt i32 [[COUNT]], 50
|
|
; CHECK-NEXT: [[CMP2_C2:%.*]] = icmp sgt i32 [[COUNT]], 100
|
|
; CHECK-NEXT: br i1 [[CMP2_C2]], label [[FOR_INC_JT3]], label [[STATE2_1_SI_UNFOLD_TRUE_JT1:%.*]]
|
|
; CHECK: state2.1.si.unfold.true:
|
|
; CHECK-NEXT: br i1 [[CMP_C2]], label [[STATE2_2_SI_UNFOLD_FALSE:%.*]], label [[STATE2_1_SI_UNFOLD_FALSE_JT2:%.*]]
|
|
; CHECK: state2.1.si.unfold.true.jt1:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI_JT1:%.*]] = phi i32 [ 1, [[CASE2]] ]
|
|
; CHECK-NEXT: br i1 [[CMP_C2]], label [[STATE2_2_SI_UNFOLD_FALSE_JT1:%.*]], label [[STATE2_1_SI_UNFOLD_FALSE:%.*]]
|
|
; CHECK: state2.1.si.unfold.false:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1:%.*]] = phi i32 [ 2, [[STATE2_1_SI_UNFOLD_TRUE_JT1]] ]
|
|
; CHECK-NEXT: br label [[STATE2_2_SI_UNFOLD_FALSE]]
|
|
; CHECK: state2.1.si.unfold.false.jt2:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1_JT2:%.*]] = phi i32 [ 2, [[STATE2_1_SI_UNFOLD_TRUE:%.*]] ]
|
|
; CHECK-NEXT: br label [[STATE2_2_SI_UNFOLD_FALSE_JT2:%.*]]
|
|
; CHECK: state2.2.si.unfold.false:
|
|
; CHECK-NEXT: [[STATE2_1_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[STATE2_1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI1]], [[STATE2_1_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: state2.2.si.unfold.false.jt2:
|
|
; CHECK-NEXT: [[STATE2_1_SI_UNFOLD_PHI_JT2:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI1_JT2]], [[STATE2_1_SI_UNFOLD_FALSE_JT2]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT2]]
|
|
; CHECK: state2.2.si.unfold.false.jt1:
|
|
; CHECK-NEXT: [[STATE2_1_SI_UNFOLD_PHI_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT1]], [[STATE2_1_SI_UNFOLD_TRUE_JT1]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT1]]
|
|
; CHECK: state1.2.si.unfold.false:
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: state1.2.si.unfold.false.jt3:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI2_JT3:%.*]] = phi i32 [ 3, [[CASE1]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT3]]
|
|
; CHECK: state1.1.si.unfold.true:
|
|
; CHECK-NEXT: br i1 [[CMP_C1]], label [[FOR_INC]], label [[STATE1_1_SI_UNFOLD_FALSE_JT2:%.*]]
|
|
; CHECK: state1.1.si.unfold.true.jt1:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ]
|
|
; CHECK-NEXT: br i1 [[CMP_C1]], label [[FOR_INC_JT1]], label [[STATE1_1_SI_UNFOLD_FALSE:%.*]]
|
|
; CHECK: state1.1.si.unfold.false:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI4:%.*]] = phi i32 [ 2, [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: state1.1.si.unfold.false.jt2:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI4_JT2:%.*]] = phi i32 [ 2, [[STATE1_1_SI_UNFOLD_TRUE:%.*]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT2]]
|
|
; CHECK: for.inc:
|
|
; CHECK-NEXT: [[COUNT5:%.*]] = phi i32 [ [[COUNT_JT3]], [[FOR_BODY_JT3:%.*]] ], [ undef, [[STATE1_1_SI_UNFOLD_TRUE]] ], [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_FALSE]] ], [ undef, [[STATE1_2_SI_UNFOLD_FALSE:%.*]] ], [ [[COUNT]], [[STATE2_2_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: [[STATE_NEXT]] = phi i32 [ [[STATE2_1_SI_UNFOLD_PHI]], [[STATE2_2_SI_UNFOLD_FALSE]] ], [ poison, [[STATE1_2_SI_UNFOLD_FALSE]] ], [ poison, [[STATE1_1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI4]], [[STATE1_1_SI_UNFOLD_FALSE]] ], [ 1, [[FOR_BODY_JT3]] ]
|
|
; CHECK-NEXT: [[INC]] = add nsw i32 [[COUNT5]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
|
|
; CHECK: for.inc.jt2:
|
|
; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ [[STATE2_1_SI_UNFOLD_PHI_JT2]], [[STATE2_2_SI_UNFOLD_FALSE_JT2]] ], [ [[DOTSI_UNFOLD_PHI4_JT2]], [[STATE1_1_SI_UNFOLD_FALSE_JT2]] ]
|
|
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 undef, 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2:%.*]], label [[FOR_END]]
|
|
; CHECK: for.inc.jt1:
|
|
; CHECK-NEXT: [[COUNT7:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ [[STATE2_1_SI_UNFOLD_PHI_JT1]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[DOTSI_UNFOLD_PHI3_JT1]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ]
|
|
; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT7]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
|
|
; CHECK: for.inc.jt3:
|
|
; CHECK-NEXT: [[COUNT8:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ], [ [[COUNT]], [[CASE2]] ]
|
|
; CHECK-NEXT: [[STATE_NEXT_JT3]] = phi i32 [ 3, [[CASE2]] ], [ [[DOTSI_UNFOLD_PHI2_JT3]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ]
|
|
; CHECK-NEXT: [[INC_JT3]] = add nsw i32 [[COUNT8]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT3:%.*]] = icmp slt i32 [[INC_JT3]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT3]], label [[FOR_BODY_JT3]], label [[FOR_END]]
|
|
; CHECK: for.end:
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%count = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ]
|
|
switch i32 %state, label %for.inc [
|
|
i32 1, label %case1
|
|
i32 2, label %case2
|
|
]
|
|
|
|
case1:
|
|
%cmp.c1 = icmp slt i32 %count, 50
|
|
%cmp2.c1 = icmp slt i32 %count, 100
|
|
%state1.1 = select i1 %cmp.c1, i32 1, i32 2
|
|
%state1.2 = select i1 %cmp2.c1, i32 %state1.1, i32 3
|
|
br label %for.inc
|
|
|
|
case2:
|
|
%cmp.c2 = icmp slt i32 %count, 50
|
|
%cmp2.c2 = icmp sgt i32 %count, 100
|
|
%state2.1 = select i1 %cmp.c2, i32 1, i32 2
|
|
%state2.2 = select i1 %cmp2.c2, i32 3, i32 %state2.1
|
|
br label %for.inc
|
|
|
|
for.inc:
|
|
%state.next = phi i32 [ %state1.2, %case1 ], [ %state2.2, %case2 ], [ 1, %for.body ]
|
|
%inc = add nsw i32 %count, 1
|
|
%cmp.exit = icmp slt i32 %inc, %num
|
|
br i1 %cmp.exit, label %for.body, label %for.end
|
|
|
|
for.end:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @test3(i32 %num) {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COUNT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
|
|
; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[STATE_NEXT:%.*]], [[FOR_INC]] ]
|
|
; CHECK-NEXT: switch i32 [[STATE]], label [[FOR_INC_JT1:%.*]] [
|
|
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
|
|
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: for.body.jt4:
|
|
; CHECK-NEXT: [[COUNT_JT4:%.*]] = phi i32 [ [[INC_JT4:%.*]], [[FOR_INC_JT4:%.*]] ]
|
|
; CHECK-NEXT: [[STATE_JT4:%.*]] = phi i32 [ [[STATE_NEXT_JT4:%.*]], [[FOR_INC_JT4]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT1]]
|
|
; CHECK: for.body.jt3:
|
|
; CHECK-NEXT: [[COUNT_JT3:%.*]] = phi i32 [ [[INC_JT3:%.*]], [[FOR_INC_JT3:%.*]] ]
|
|
; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ [[STATE_NEXT_JT3:%.*]], [[FOR_INC_JT3]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT1]]
|
|
; CHECK: for.body.jt2:
|
|
; CHECK-NEXT: [[COUNT_JT2:%.*]] = phi i32 [ [[INC_JT2:%.*]], [[FOR_INC_JT2:%.*]] ]
|
|
; CHECK-NEXT: [[STATE_JT2:%.*]] = phi i32 [ [[STATE_NEXT_JT2:%.*]], [[FOR_INC_JT2]] ]
|
|
; CHECK-NEXT: br label [[CASE2]]
|
|
; CHECK: for.body.jt1:
|
|
; CHECK-NEXT: [[COUNT_JT1:%.*]] = phi i32 [ [[INC_JT1:%.*]], [[FOR_INC_JT1]] ]
|
|
; CHECK-NEXT: [[STATE_JT1:%.*]] = phi i32 [ [[STATE_NEXT_JT1:%.*]], [[FOR_INC_JT1]] ]
|
|
; CHECK-NEXT: br label [[CASE1]]
|
|
; CHECK: case1:
|
|
; CHECK-NEXT: [[COUNT6:%.*]] = phi i32 [ [[COUNT_JT1]], [[FOR_BODY_JT1:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT2]]
|
|
; CHECK: case2:
|
|
; CHECK-NEXT: [[COUNT5:%.*]] = phi i32 [ [[COUNT_JT2]], [[FOR_BODY_JT2:%.*]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[COUNT5]], 50
|
|
; CHECK-NEXT: [[CMP_2:%.*]] = icmp slt i32 [[COUNT5]], 100
|
|
; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[COUNT5]], 1
|
|
; CHECK-NEXT: [[CMP_3:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[CMP_3]], label [[SEL_1_SI_UNFOLD_TRUE_JT1:%.*]], label [[SEL_2_SI_UNFOLD_TRUE_JT3:%.*]]
|
|
; CHECK: sel.2.si.unfold.true:
|
|
; CHECK-NEXT: br i1 [[CMP_2]], label [[SEL_3_SI_UNFOLD_FALSE:%.*]], label [[SEL_2_SI_UNFOLD_FALSE_JT4:%.*]]
|
|
; CHECK: sel.2.si.unfold.true.jt3:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI_JT3:%.*]] = phi i32 [ 3, [[CASE2]] ]
|
|
; CHECK-NEXT: br i1 [[CMP_2]], label [[SEL_3_SI_UNFOLD_FALSE_JT3:%.*]], label [[SEL_2_SI_UNFOLD_FALSE:%.*]]
|
|
; CHECK: sel.2.si.unfold.false:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1:%.*]] = phi i32 [ 4, [[SEL_2_SI_UNFOLD_TRUE_JT3]] ]
|
|
; CHECK-NEXT: br label [[SEL_3_SI_UNFOLD_FALSE]]
|
|
; CHECK: sel.2.si.unfold.false.jt4:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1_JT4:%.*]] = phi i32 [ 4, [[SEL_2_SI_UNFOLD_TRUE:%.*]] ]
|
|
; CHECK-NEXT: br label [[SEL_3_SI_UNFOLD_FALSE_JT4:%.*]]
|
|
; CHECK: sel.3.si.unfold.false:
|
|
; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[SEL_2_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI1]], [[SEL_2_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: sel.3.si.unfold.false.jt4:
|
|
; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT4:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI1_JT4]], [[SEL_2_SI_UNFOLD_FALSE_JT4]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT4]]
|
|
; CHECK: sel.3.si.unfold.false.jt3:
|
|
; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT3]], [[SEL_2_SI_UNFOLD_TRUE_JT3]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT3]]
|
|
; CHECK: sel.1.si.unfold.true:
|
|
; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_INC]], label [[SEL_1_SI_UNFOLD_FALSE_JT2:%.*]]
|
|
; CHECK: sel.1.si.unfold.true.jt1:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI2_JT1:%.*]] = phi i32 [ 1, [[CASE2]] ]
|
|
; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_INC_JT1]], label [[SEL_1_SI_UNFOLD_FALSE:%.*]]
|
|
; CHECK: sel.1.si.unfold.false:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3:%.*]] = phi i32 [ 2, [[SEL_1_SI_UNFOLD_TRUE_JT1]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: sel.1.si.unfold.false.jt2:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3_JT2:%.*]] = phi i32 [ 2, [[SEL_1_SI_UNFOLD_TRUE:%.*]] ]
|
|
; CHECK-NEXT: br label [[FOR_INC_JT2]]
|
|
; CHECK: for.inc:
|
|
; CHECK-NEXT: [[STATE_NEXT]] = phi i32 [ [[SEL_2_SI_UNFOLD_PHI]], [[SEL_3_SI_UNFOLD_FALSE]] ], [ poison, [[SEL_1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI3]], [[SEL_1_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: [[INC]] = add nsw i32 [[COUNT5]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
|
|
; CHECK: for.inc.jt4:
|
|
; CHECK-NEXT: [[STATE_NEXT_JT4]] = phi i32 [ [[SEL_2_SI_UNFOLD_PHI_JT4]], [[SEL_3_SI_UNFOLD_FALSE_JT4]] ]
|
|
; CHECK-NEXT: [[INC_JT4]] = add nsw i32 undef, 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT4:%.*]] = icmp slt i32 [[INC_JT4]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT4]], label [[FOR_BODY_JT4:%.*]], label [[FOR_END]]
|
|
; CHECK: for.inc.jt3:
|
|
; CHECK-NEXT: [[STATE_NEXT_JT3]] = phi i32 [ [[SEL_2_SI_UNFOLD_PHI_JT3]], [[SEL_3_SI_UNFOLD_FALSE_JT3]] ]
|
|
; CHECK-NEXT: [[INC_JT3]] = add nsw i32 [[COUNT5]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT3:%.*]] = icmp slt i32 [[INC_JT3]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT3]], label [[FOR_BODY_JT3:%.*]], label [[FOR_END]]
|
|
; CHECK: for.inc.jt2:
|
|
; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI3_JT2]], [[SEL_1_SI_UNFOLD_FALSE_JT2]] ]
|
|
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT6]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
|
|
; CHECK: for.inc.jt1:
|
|
; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT_JT4]], [[FOR_BODY_JT4]] ], [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ 1, [[FOR_BODY_JT3]] ], [ 1, [[FOR_BODY_JT4]] ], [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ]
|
|
; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT4]], 1
|
|
; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
|
|
; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
|
|
; CHECK: for.end:
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%count = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ]
|
|
switch i32 %state, label %for.inc [
|
|
i32 1, label %case1
|
|
i32 2, label %case2
|
|
]
|
|
|
|
case1:
|
|
br label %for.inc
|
|
|
|
case2:
|
|
%cmp.1 = icmp slt i32 %count, 50
|
|
%cmp.2 = icmp slt i32 %count, 100
|
|
%0 = and i32 %count, 1
|
|
%cmp.3 = icmp eq i32 %0, 0
|
|
%sel.1 = select i1 %cmp.1, i32 1, i32 2
|
|
%sel.2 = select i1 %cmp.2, i32 3, i32 4
|
|
%sel.3 = select i1 %cmp.3, i32 %sel.1, i32 %sel.2
|
|
br label %for.inc
|
|
|
|
for.inc:
|
|
%state.next = phi i32 [ %sel.3, %case2 ], [ 1, %for.body ], [ 2, %case1 ]
|
|
%inc = add nsw i32 %count, 1
|
|
%cmp.exit = icmp slt i32 %inc, %num
|
|
br i1 %cmp.exit, label %for.body, label %for.end
|
|
|
|
for.end:
|
|
ret i32 0
|
|
}
|
|
|
|
define void @select_coming_elsewhere(i1 %cond, i16 %a, i16 %b) {
|
|
; CHECK-LABEL: @select_coming_elsewhere(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[COND:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[E_ADDR_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[DIV]], [[LOR_END:%.*]] ]
|
|
; CHECK-NEXT: switch i16 [[E_ADDR_0]], label [[LOR_END]] [
|
|
; CHECK-NEXT: ]
|
|
; CHECK: lor.end:
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
;
|
|
entry:
|
|
%div = select i1 %cond, i16 %a, i16 %b
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %lor.end, %entry
|
|
%e.addr.0 = phi i16 [ 0, %entry ], [ %div, %lor.end ]
|
|
switch i16 %e.addr.0, label %lor.end [
|
|
]
|
|
|
|
lor.end: ; preds = %for.cond
|
|
br label %for.cond
|
|
}
|
|
|
|
define void @pr65222(i32 %flags, i1 %cmp, i1 %tobool.not) {
|
|
; CHECK-LABEL: @pr65222(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
|
; CHECK: while.cond:
|
|
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: then:
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT:%.*]], label [[COND1_SI_UNFOLD_TRUE:%.*]], label [[COND_SI_UNFOLD_TRUE:%.*]]
|
|
; CHECK: cond.si.unfold.true:
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TOUNFOLD_SI_UNFOLD_FALSE1:%.*]], label [[COND_SI_UNFOLD_FALSE_JT0:%.*]]
|
|
; CHECK: cond.si.unfold.true.jt2:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI:%.*]] = phi i32 [ 2, [[THEN]] ]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TOUNFOLD_SI_UNFOLD_FALSE:%.*]], label [[COND_SI_UNFOLD_FALSE:%.*]]
|
|
; CHECK: cond.si.unfold.false:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1:%.*]] = phi i32 [ 0, [[COND_SI_UNFOLD_TRUE]] ]
|
|
; CHECK-NEXT: br label [[TOUNFOLD_SI_UNFOLD_FALSE1]]
|
|
; CHECK: cond.si.unfold.false.jt0:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1_JT0:%.*]] = phi i32 [ 0, [[COND_SI_UNFOLD_TRUE1:%.*]] ]
|
|
; CHECK-NEXT: br label [[TOUNFOLD_SI_UNFOLD_FALSE_JT0:%.*]]
|
|
; CHECK: tounfold.si.unfold.false:
|
|
; CHECK-NEXT: [[COND_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[COND_SI_UNFOLD_TRUE1]] ], [ [[DOTSI_UNFOLD_PHI1]], [[COND_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: tounfold.si.unfold.false.jt0:
|
|
; CHECK-NEXT: [[COND_SI_UNFOLD_PHI_JT0:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI1_JT0]], [[COND_SI_UNFOLD_FALSE_JT0]] ]
|
|
; CHECK-NEXT: br label [[IF_END_JT0:%.*]]
|
|
; CHECK: tounfold.si.unfold.false.jt2:
|
|
; CHECK-NEXT: [[COND_SI_UNFOLD_PHI_JT2:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI]], [[COND_SI_UNFOLD_TRUE]] ]
|
|
; CHECK-NEXT: br label [[IF_END_JT2:%.*]]
|
|
; CHECK: cond1.si.unfold.true:
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[IF_END]], label [[COND1_SI_UNFOLD_FALSE_JT1:%.*]]
|
|
; CHECK: cond1.si.unfold.true.jt3:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI2:%.*]] = phi i32 [ 3, [[THEN]] ]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[IF_END_JT3:%.*]], label [[COND1_SI_UNFOLD_FALSE:%.*]]
|
|
; CHECK: cond1.si.unfold.false:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3:%.*]] = phi i32 [ 1, [[COND1_SI_UNFOLD_TRUE]] ]
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: cond1.si.unfold.false.jt1:
|
|
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3_JT1:%.*]] = phi i32 [ 1, [[COND1_SI_UNFOLD_TRUE1:%.*]] ]
|
|
; CHECK-NEXT: br label [[IF_END_JT1:%.*]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[UNFOLDED:%.*]] = phi i32 [ [[FLAGS:%.*]], [[WHILE_COND]] ], [ [[COND_SI_UNFOLD_PHI]], [[TOUNFOLD_SI_UNFOLD_FALSE1]] ], [ poison, [[COND1_SI_UNFOLD_TRUE1]] ], [ [[DOTSI_UNFOLD_PHI3]], [[COND1_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: [[OTHER:%.*]] = phi i32 [ [[FLAGS]], [[WHILE_COND]] ], [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE1]] ], [ 0, [[COND1_SI_UNFOLD_TRUE1]] ], [ 0, [[COND1_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: switch i32 [[UNFOLDED]], label [[UNREACHABLE:%.*]] [
|
|
; CHECK-NEXT: i32 0, label [[SW_BB:%.*]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: if.end.jt1:
|
|
; CHECK-NEXT: [[UNFOLDED_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI3_JT1]], [[COND1_SI_UNFOLD_FALSE_JT1]] ]
|
|
; CHECK-NEXT: [[OTHER_JT1:%.*]] = phi i32 [ 0, [[COND1_SI_UNFOLD_FALSE_JT1]] ]
|
|
; CHECK-NEXT: br label [[UNREACHABLE]]
|
|
; CHECK: if.end.jt3:
|
|
; CHECK-NEXT: [[UNFOLDED_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI2]], [[COND1_SI_UNFOLD_TRUE]] ]
|
|
; CHECK-NEXT: [[OTHER_JT3:%.*]] = phi i32 [ 0, [[COND1_SI_UNFOLD_TRUE]] ]
|
|
; CHECK-NEXT: br label [[UNREACHABLE]]
|
|
; CHECK: if.end.jt0:
|
|
; CHECK-NEXT: [[UNFOLDED_JT0:%.*]] = phi i32 [ [[COND_SI_UNFOLD_PHI_JT0]], [[TOUNFOLD_SI_UNFOLD_FALSE_JT0]] ]
|
|
; CHECK-NEXT: [[OTHER_JT0:%.*]] = phi i32 [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE_JT0]] ]
|
|
; CHECK-NEXT: br label [[SW_BB]]
|
|
; CHECK: if.end.jt2:
|
|
; CHECK-NEXT: [[UNFOLDED_JT2:%.*]] = phi i32 [ [[COND_SI_UNFOLD_PHI_JT2]], [[TOUNFOLD_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: [[OTHER_JT2:%.*]] = phi i32 [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE]] ]
|
|
; CHECK-NEXT: br label [[UNREACHABLE]]
|
|
; CHECK: unreachable:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: sw.bb:
|
|
; CHECK-NEXT: br label [[WHILE_COND]]
|
|
;
|
|
entry:
|
|
br label %while.cond
|
|
|
|
while.cond: ; preds = %sw.bb147, %if.end, %entry
|
|
br i1 %cmp, label %then, label %if.end
|
|
|
|
then: ; preds = %while.cond
|
|
%cond = select i1 %cmp, i32 2, i32 0
|
|
%cond1 = select i1 %cmp, i32 3, i32 1
|
|
%tounfold = select i1 %tobool.not, i32 %cond1, i32 %cond
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %then, %while.cond
|
|
%unfolded = phi i32 [ %tounfold, %then ], [ %flags, %while.cond ]
|
|
%other = phi i32 [ 0, %then ], [ %flags, %while.cond ]
|
|
switch i32 %unfolded, label %unreachable [
|
|
i32 0, label %sw.bb
|
|
]
|
|
|
|
unreachable:
|
|
unreachable
|
|
|
|
sw.bb: ; preds = %if.end
|
|
br label %while.cond
|
|
}
|