diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp index b9546c5fa236b..e902b71776973 100644 --- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp +++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" @@ -393,6 +394,17 @@ class ConstantTerminatorFoldingImpl { DTUpdates.push_back({DominatorTree::Insert, Preheader, BB}); ++NumLoopExitsDeleted; } + // We don't really need to add branch weights to DummySwitch, because all + // but one branches are just a temporary artifact - see the comment on top + // of this function. But, it's easy to estimate the weights, and it helps + // maintain a property of the overall compiler - that the branch weights + // don't "just get dropped" accidentally (i.e. profcheck) + if (DummySwitch->getParent()->getParent()->hasProfileData()) { + SmallVector DummyBranchWeights(1 + DummySwitch->getNumCases()); + // default. 100% probability, the rest are dead. + DummyBranchWeights[0] = 1; + setBranchWeights(*DummySwitch, DummyBranchWeights, /*IsExpected=*/false); + } assert(L.getLoopPreheader() == NewPreheader && "Malformed CFG?"); if (Loop *OuterLoop = LI.getLoopFor(Preheader)) { diff --git a/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll b/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll index 1ec212f0bb5ea..46b6209986fed 100644 --- a/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll +++ b/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals ; REQUIRES: asserts ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require,loop(loop-simplifycfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s @@ -59,7 +59,7 @@ define i32 @dead_backedge_test_switch_loop(i32 %end) { ; CHECK: dead_backedge: ; CHECK-NEXT: [[I_2]] = add i32 [[I_1]], 10 ; CHECK-NEXT: switch i32 1, label [[EXIT:%.*]] [ -; CHECK-NEXT: i32 0, label [[HEADER_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[HEADER_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: exit: ; CHECK-NEXT: [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ] @@ -233,12 +233,12 @@ exit: ; Check that we preserve static reachibility of a dead exit block while deleting ; a branch. -define i32 @dead_exit_test_branch_loop(i32 %end) { +define i32 @dead_exit_test_branch_loop(i32 %end) !prof !{!"function_entry_count", i32 10} { ; CHECK-LABEL: @dead_exit_test_branch_loop( ; CHECK-NEXT: preheader: ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[DEAD:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: i32 1, label [[DEAD:%.*]] +; CHECK-NEXT: ], !prof [[PROF1:![0-9]+]] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] ; CHECK: header: @@ -262,7 +262,7 @@ preheader: header: %i = phi i32 [0, %preheader], [%i.inc, %backedge] - br i1 true, label %backedge, label %dead + br i1 true, label %backedge, label %dead, !prof !{!"branch_weights", i32 10, i32 1} dead: br label %dummy @@ -286,7 +286,7 @@ define i32 @dead_exit_test_switch_loop(i32 %end) { ; CHECK-LABEL: @dead_exit_test_switch_loop( ; CHECK-NEXT: preheader: ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[DEAD:%.*]] +; CHECK-NEXT: i32 1, label [[DEAD:%.*]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -383,9 +383,9 @@ define i32 @dead_loop_test_switch_loop(i32 %end) { ; 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: 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 @@ -552,7 +552,7 @@ define i32 @inf_loop_test_branch_loop(i32 %end) { ; CHECK-LABEL: @inf_loop_test_branch_loop( ; CHECK-NEXT: preheader: ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[EXIT:%.*]] +; CHECK-NEXT: i32 1, label [[EXIT:%.*]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -592,7 +592,7 @@ define i32 @inf_loop_test_switch_loop(i32 %end) { ; CHECK-LABEL: @inf_loop_test_switch_loop( ; CHECK-NEXT: preheader: ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[EXIT:%.*]] +; CHECK-NEXT: i32 1, label [[EXIT:%.*]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -1001,7 +1001,7 @@ define i32 @full_sub_loop_test_switch_loop(i32 %end) { ; 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: i32 0, label [[BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: dead: ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 @@ -1010,7 +1010,7 @@ define i32 @full_sub_loop_test_switch_loop(i32 %end) { ; 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: i32 0, label [[HEADER]] ; CHECK-NEXT: ] ; CHECK: outer_backedge: ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] @@ -1132,7 +1132,7 @@ define i32 @full_sub_loop_test_switch_loop_inverse_1(i32 %end) { ; 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: i32 0, label [[DEAD:%.*]] ; CHECK-NEXT: ] ; CHECK: dead: ; CHECK-NEXT: [[I_2:%.*]] = add i32 [[I]], 1 @@ -1141,7 +1141,7 @@ define i32 @full_sub_loop_test_switch_loop_inverse_1(i32 %end) { ; 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: i32 0, label [[HEADER]] ; CHECK-NEXT: ] ; CHECK: outer_backedge: ; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ] @@ -1195,7 +1195,7 @@ define i32 @full_sub_loop_test_branch_loop_inverse_2(i32 %end) { ; CHECK: outer_header: ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] +; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -1256,7 +1256,7 @@ define i32 @full_sub_loop_test_switch_loop_inverse_2(i32 %end) { ; CHECK: outer_header: ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] +; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -1318,7 +1318,7 @@ define i32 @full_sub_loop_test_branch_loop_inverse_3(i32 %end) { ; CHECK: outer_header: ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] +; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -1378,7 +1378,7 @@ define i32 @full_sub_loop_test_switch_loop_inverse_3(i32 %end) { ; CHECK: outer_header: ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ] ; CHECK-NEXT: switch i32 0, label [[PREHEADER_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] +; CHECK-NEXT: i32 1, label [[OUTER_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: preheader.split: ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -1441,7 +1441,7 @@ define i32 @exit_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) ; CHECK: loop_2: ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] ; CHECK-NEXT: switch i32 0, label [[LOOP_2_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]] +; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_2.split: ; CHECK-NEXT: br label [[LOOP_3:%.*]] @@ -1510,7 +1510,7 @@ define i32 @exit_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) ; CHECK: loop_2: ; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ] ; CHECK-NEXT: switch i32 0, label [[LOOP_2_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]] +; CHECK-NEXT: i32 1, label [[LOOP_2_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_2.split: ; CHECK-NEXT: br label [[LOOP_3:%.*]] @@ -1654,7 +1654,7 @@ define i32 @intermediate_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] ; CHECK: intermediate: ; CHECK-NEXT: switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [ -; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_3_backedge: ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 @@ -1792,7 +1792,7 @@ define i32 @intermediate_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i32 % ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]] ; CHECK: intermediate: ; CHECK-NEXT: switch i32 1, label [[LOOP_2_BACKEDGE]] [ -; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_3_backedge: ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 @@ -1944,7 +1944,7 @@ define i32 @intermediate_subloop_switch_from_inner_to_grandparent(i1 %cond1, i1 ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]] ; CHECK: intermediate_exit: ; CHECK-NEXT: switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [ -; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_3_backedge: ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 @@ -2102,7 +2102,7 @@ define i32 @intermediate_subloop_switch_from_inner_to_parent(i1 %cond1, i1 %cond ; CHECK-NEXT: br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]] ; CHECK: intermediate_exit: ; CHECK-NEXT: switch i32 1, label [[LOOP_2_BACKEDGE]] [ -; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_3_backedge: ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 @@ -2267,7 +2267,7 @@ define i32 @intermediate_complex_subloop_switch_from_inner_to_parent(i1 %cond1, ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]] ; CHECK: intermediate_exit: ; CHECK-NEXT: switch i32 1, label [[LOOP_2_BACKEDGE]] [ -; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_3_backedge: ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 @@ -2440,7 +2440,7 @@ define i32 @intermediate_complex_subloop_switch_from_inner_to_grandparent(i1 %co ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]] ; CHECK: intermediate_exit: ; CHECK-NEXT: switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [ -; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] +; CHECK-NEXT: i32 0, label [[LOOP_3_BACKEDGE]] ; CHECK-NEXT: ] ; CHECK: loop_3_backedge: ; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1 @@ -2585,38 +2585,38 @@ define void @test_crash_01(i1 %arg, i32 %arg2) { ; CHECK-NEXT: bb: ; CHECK-NEXT: br label [[BB1:%.*]] ; CHECK: bb1: -; CHECK-NEXT: br i1 %arg, label [[BB17:%.*]], label [[BB2:%.*]] +; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB17:%.*]], label [[BB2:%.*]] ; CHECK: bb2: ; CHECK-NEXT: switch i32 0, label [[BB2_SPLIT:%.*]] [ -; CHECK-NEXT: i32 1, label [[BB19:%.*]] +; CHECK-NEXT: i32 1, label [[BB19:%.*]] ; CHECK-NEXT: ] ; CHECK: bb2.split: ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: bb3: -; CHECK-NEXT: switch i32 %arg2, label [[BB16:%.*]] [ -; CHECK-NEXT: i32 0, label [[BB15:%.*]] -; CHECK-NEXT: i32 1, label [[BB14:%.*]] -; CHECK-NEXT: i32 2, label [[BB13:%.*]] -; CHECK-NEXT: i32 3, label [[BB12:%.*]] -; CHECK-NEXT: i32 4, label [[BB11:%.*]] -; CHECK-NEXT: i32 5, label [[BB8:%.*]] -; CHECK-NEXT: i32 6, label [[BB10:%.*]] -; CHECK-NEXT: i32 7, label [[BB9:%.*]] -; CHECK-NEXT: i32 8, label [[BB7:%.*]] +; CHECK-NEXT: switch i32 [[ARG2:%.*]], label [[BB16:%.*]] [ +; CHECK-NEXT: i32 0, label [[BB15:%.*]] +; CHECK-NEXT: i32 1, label [[BB14:%.*]] +; CHECK-NEXT: i32 2, label [[BB13:%.*]] +; CHECK-NEXT: i32 3, label [[BB12:%.*]] +; CHECK-NEXT: i32 4, label [[BB11:%.*]] +; CHECK-NEXT: i32 5, label [[BB8:%.*]] +; CHECK-NEXT: i32 6, label [[BB10:%.*]] +; CHECK-NEXT: i32 7, label [[BB9:%.*]] +; CHECK-NEXT: i32 8, label [[BB7:%.*]] ; CHECK-NEXT: ] ; CHECK: bb7: ; CHECK-NEXT: unreachable ; CHECK: bb8: -; CHECK-NEXT: switch i32 %arg2, label [[BB28:%.*]] [ -; CHECK-NEXT: i32 0, label [[BB27:%.*]] -; CHECK-NEXT: i32 1, label [[BB26:%.*]] -; CHECK-NEXT: i32 2, label [[BB23:%.*]] -; CHECK-NEXT: i32 3, label [[BB24:%.*]] -; CHECK-NEXT: i32 4, label [[BB25:%.*]] -; CHECK-NEXT: i32 5, label [[BB29:%.*]] -; CHECK-NEXT: i32 6, label [[BB22:%.*]] -; CHECK-NEXT: i32 7, label [[BB20:%.*]] -; CHECK-NEXT: i32 8, label [[BB21:%.*]] +; CHECK-NEXT: switch i32 [[ARG2]], label [[BB28:%.*]] [ +; CHECK-NEXT: i32 0, label [[BB27:%.*]] +; CHECK-NEXT: i32 1, label [[BB26:%.*]] +; CHECK-NEXT: i32 2, label [[BB23:%.*]] +; CHECK-NEXT: i32 3, label [[BB24:%.*]] +; CHECK-NEXT: i32 4, label [[BB25:%.*]] +; CHECK-NEXT: i32 5, label [[BB29:%.*]] +; CHECK-NEXT: i32 6, label [[BB22:%.*]] +; CHECK-NEXT: i32 7, label [[BB20:%.*]] +; CHECK-NEXT: i32 8, label [[BB21:%.*]] ; CHECK-NEXT: ] ; CHECK: bb9: ; CHECK-NEXT: unreachable @@ -2772,3 +2772,7 @@ bb28: ; preds = %bb8 bb29: ; preds = %bb8 br label %bb6 } +;. +; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10} +; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 0} +;.