| ; 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 |
| } |