[llvm] 28a9147 - [GuardWidening] Remove WidenFrequentBranches transform

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 15:15:57 PST 2019


Author: Philip Reames
Date: 2019-11-19T15:15:52-08:00
New Revision: 28a91473e33eb3585a87514e4cf2523a9a587d82

URL: https://github.com/llvm/llvm-project/commit/28a91473e33eb3585a87514e4cf2523a9a587d82
DIFF: https://github.com/llvm/llvm-project/commit/28a91473e33eb3585a87514e4cf2523a9a587d82.diff

LOG: [GuardWidening] Remove WidenFrequentBranches transform

This code has never been enabled.  While it is tested, it's complicating some refactoring.  If we decide to re-implement this, doing it in SimplifyCFG would probably make more sense anyways.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/GuardWidening.cpp

Removed: 
    llvm/test/Transforms/GuardWidening/widen-frequent-branches.ll


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index 943cc9ac5938..69d9507b3564 100644
--- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp
+++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
@@ -69,22 +69,6 @@ using namespace llvm;
 STATISTIC(GuardsEliminated, "Number of eliminated guards");
 STATISTIC(CondBranchEliminated, "Number of eliminated conditional branches");
 
-static cl::opt<bool> WidenFrequentBranches(
-    "guard-widening-widen-frequent-branches", cl::Hidden,
-    cl::desc("Widen conditions of explicit branches into dominating guards in "
-             "case if their taken frequency exceeds threshold set by "
-             "guard-widening-frequent-branch-threshold option"),
-    cl::init(false));
-
-static cl::opt<unsigned> FrequentBranchThreshold(
-    "guard-widening-frequent-branch-threshold", cl::Hidden,
-    cl::desc("When WidenFrequentBranches is set to true, this option is used "
-             "to determine which branches are frequently taken. The criteria "
-             "that a branch is taken more often than "
-             "((FrequentBranchThreshold - 1) / FrequentBranchThreshold), then "
-             "it is considered frequently taken"),
-    cl::init(1000));
-
 static cl::opt<bool>
     WidenBranchGuards("guard-widening-widen-branch-guards", cl::Hidden,
                       cl::desc("Whether or not we should widen guards  "
@@ -129,7 +113,6 @@ class GuardWideningImpl {
   DominatorTree &DT;
   PostDominatorTree *PDT;
   LoopInfo &LI;
-  BranchProbabilityInfo *BPI;
 
   /// Together, these describe the region of interest.  This might be all of
   /// the blocks within a function, or only a given loop's blocks and preheader.
@@ -287,10 +270,9 @@ class GuardWideningImpl {
 public:
 
   explicit GuardWideningImpl(DominatorTree &DT, PostDominatorTree *PDT,
-                             LoopInfo &LI, BranchProbabilityInfo *BPI,
-                             DomTreeNode *Root,
+                             LoopInfo &LI, DomTreeNode *Root,
                              std::function<bool(BasicBlock*)> BlockFilter)
-    : DT(DT), PDT(PDT), LI(LI), BPI(BPI), Root(Root), BlockFilter(BlockFilter)
+    : DT(DT), PDT(PDT), LI(LI), Root(Root), BlockFilter(BlockFilter)
         {}
 
   /// The entry point for this pass.
@@ -309,13 +291,6 @@ static bool isSupportedGuardInstruction(const Instruction *Insn) {
 bool GuardWideningImpl::run() {
   DenseMap<BasicBlock *, SmallVector<Instruction *, 8>> GuardsInBlock;
   bool Changed = false;
-  Optional<BranchProbability> LikelyTaken = None;
-  if (WidenFrequentBranches && BPI) {
-    unsigned Threshold = FrequentBranchThreshold;
-    assert(Threshold > 0 && "Zero threshold makes no sense!");
-    LikelyTaken = BranchProbability(Threshold - 1, Threshold);
-  }
-
   for (auto DFI = df_begin(Root), DFE = df_end(Root);
        DFI != DFE; ++DFI) {
     auto *BB = (*DFI)->getBlock();
@@ -330,17 +305,6 @@ bool GuardWideningImpl::run() {
 
     for (auto *II : CurrentList)
       Changed |= eliminateInstrViaWidening(II, DFI, GuardsInBlock);
-    if (WidenFrequentBranches && BPI)
-      if (auto *BI = dyn_cast<BranchInst>(BB->getTerminator()))
-        if (BI->isConditional()) {
-          // If one of branches of a conditional is likely taken, try to
-          // eliminate it.
-          if (BPI->getEdgeProbability(BB, 0U) >= *LikelyTaken)
-            Changed |= eliminateInstrViaWidening(BI, DFI, GuardsInBlock);
-          else if (BPI->getEdgeProbability(BB, 1U) >= *LikelyTaken)
-            Changed |= eliminateInstrViaWidening(BI, DFI, GuardsInBlock,
-                                                 /*InvertCondition*/true);
-        }
   }
 
   assert(EliminatedGuardsAndBranches.empty() || Changed);
@@ -805,10 +769,7 @@ PreservedAnalyses GuardWideningPass::run(Function &F,
   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
   auto &LI = AM.getResult<LoopAnalysis>(F);
   auto &PDT = AM.getResult<PostDominatorTreeAnalysis>(F);
-  BranchProbabilityInfo *BPI = nullptr;
-  if (WidenFrequentBranches)
-    BPI = AM.getCachedResult<BranchProbabilityAnalysis>(F);
-  if (!GuardWideningImpl(DT, &PDT, LI, BPI, DT.getRootNode(),
+  if (!GuardWideningImpl(DT, &PDT, LI, DT.getRootNode(),
                          [](BasicBlock*) { return true; } ).run())
     return PreservedAnalyses::all();
 
@@ -820,22 +781,13 @@ PreservedAnalyses GuardWideningPass::run(Function &F,
 PreservedAnalyses GuardWideningPass::run(Loop &L, LoopAnalysisManager &AM,
                                          LoopStandardAnalysisResults &AR,
                                          LPMUpdater &U) {
-
-  const auto &FAM =
-    AM.getResult<FunctionAnalysisManagerLoopProxy>(L, AR).getManager();
-  Function &F = *L.getHeader()->getParent();
-  BranchProbabilityInfo *BPI = nullptr;
-  if (WidenFrequentBranches)
-    BPI = FAM.getCachedResult<BranchProbabilityAnalysis>(F);
-
   BasicBlock *RootBB = L.getLoopPredecessor();
   if (!RootBB)
     RootBB = L.getHeader();
   auto BlockFilter = [&](BasicBlock *BB) {
     return BB == RootBB || L.contains(BB);
   };
-  if (!GuardWideningImpl(AR.DT, nullptr, AR.LI, BPI,
-                         AR.DT.getNode(RootBB),
+  if (!GuardWideningImpl(AR.DT, nullptr, AR.LI, AR.DT.getNode(RootBB),
                          BlockFilter).run())
     return PreservedAnalyses::all();
 
@@ -856,10 +808,7 @@ struct GuardWideningLegacyPass : public FunctionPass {
     auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
     auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
     auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
-    BranchProbabilityInfo *BPI = nullptr;
-    if (WidenFrequentBranches)
-      BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
-    return GuardWideningImpl(DT, &PDT, LI, BPI, DT.getRootNode(),
+    return GuardWideningImpl(DT, &PDT, LI, DT.getRootNode(),
                          [](BasicBlock*) { return true; } ).run();
   }
 
@@ -868,8 +817,6 @@ struct GuardWideningLegacyPass : public FunctionPass {
     AU.addRequired<DominatorTreeWrapperPass>();
     AU.addRequired<PostDominatorTreeWrapperPass>();
     AU.addRequired<LoopInfoWrapperPass>();
-    if (WidenFrequentBranches)
-      AU.addRequired<BranchProbabilityInfoWrapperPass>();
   }
 };
 
@@ -895,16 +842,11 @@ struct LoopGuardWideningLegacyPass : public LoopPass {
     auto BlockFilter = [&](BasicBlock *BB) {
       return BB == RootBB || L->contains(BB);
     };
-    BranchProbabilityInfo *BPI = nullptr;
-    if (WidenFrequentBranches)
-      BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
-    return GuardWideningImpl(DT, PDT, LI, BPI,
+    return GuardWideningImpl(DT, PDT, LI,
                              DT.getNode(RootBB), BlockFilter).run();
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    if (WidenFrequentBranches)
-      AU.addRequired<BranchProbabilityInfoWrapperPass>();
     AU.setPreservesCFG();
     getLoopAnalysisUsage(AU);
     AU.addPreserved<PostDominatorTreeWrapperPass>();
@@ -920,8 +862,6 @@ INITIALIZE_PASS_BEGIN(GuardWideningLegacyPass, "guard-widening", "Widen guards",
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-if (WidenFrequentBranches)
-  INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
 INITIALIZE_PASS_END(GuardWideningLegacyPass, "guard-widening", "Widen guards",
                     false, false)
 
@@ -931,8 +871,6 @@ INITIALIZE_PASS_BEGIN(LoopGuardWideningLegacyPass, "loop-guard-widening",
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-if (WidenFrequentBranches)
-  INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
 INITIALIZE_PASS_END(LoopGuardWideningLegacyPass, "loop-guard-widening",
                     "Widen guards (within a single loop, as a loop pass)",
                     false, false)

diff  --git a/llvm/test/Transforms/GuardWidening/widen-frequent-branches.ll b/llvm/test/Transforms/GuardWidening/widen-frequent-branches.ll
deleted file mode 100644
index 2f6dceadf497..000000000000
--- a/llvm/test/Transforms/GuardWidening/widen-frequent-branches.ll
+++ /dev/null
@@ -1,820 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -guard-widening-widen-frequent-branches=true -guard-widening-frequent-branch-threshold=1000 -S -guard-widening < %s        | FileCheck %s
-; RUN: opt -guard-widening-widen-frequent-branches=true -guard-widening-frequent-branch-threshold=1000 -S -passes='require<branch-prob>,guard-widening' < %s | FileCheck %s
-
-declare void @llvm.experimental.guard(i1,...)
-declare void @foo()
-declare void @bar()
-
-; Check that we don't widen without branch probability.
-define void @test_01(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_01(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  ret void
-}
-
-; Check that we don't widen with branch probability below threshold.
-define void @test_02(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_02(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !0
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !0
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  ret void
-}
-
-; Check that we widen conditions of explicit branches into dominating guards
-; when the probability is high enough.
-define void @test_03(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_03(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  ret void
-}
-
-; Similar to test_03, but the likely taken branch is the false branch.
-define void @test_03_not_taken(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_03_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  ret void
-}
-
-; Widen loop-invariant condition into the guard in preheader.
-define void @test_04(i1 %cond_0, i1 %cond_1, i32 %n) {
-; CHECK-LABEL: @test_04(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br label %loop
-
-loop:
-  %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  %iv.next = add i32 %iv, 1
-  %cond = icmp slt i32 %iv.next, %n
-  br i1 %cond, label %loop, label %exit
-
-exit:
-  ret void
-}
-
-; Similar to test_04, but the likely taken branch is the false branch.
-define void @test_04_not_taken(i1 %cond_0, i1 %cond_1, i32 %n) {
-; CHECK-LABEL: @test_04_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br label %loop
-
-loop:
-  %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  %iv.next = add i32 %iv, 1
-  %cond = icmp slt i32 %iv.next, %n
-  br i1 %cond, label %loop, label %exit
-
-exit:
-  ret void
-}
-
-; Widen loop-invariant condition into the guard in the same loop.
-define void @test_05(i1 %cond_0, i1 %cond_1, i32 %n) {
-; CHECK-LABEL: @test_05(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-;
-entry:
-  br label %loop
-
-loop:
-  %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  %iv.next = add i32 %iv, 1
-  %cond = icmp slt i32 %iv.next, %n
-  br i1 %cond, label %loop, label %exit
-
-exit:
-  ret void
-}
-
-; Similar to test_05, but the likely taken branch is the false branch.
-define void @test_05_not_taken(i1 %cond_0, i1 %cond_1, i32 %n) {
-; CHECK-LABEL: @test_05_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
-; CHECK-NEXT:    [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       if.false:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-;
-entry:
-  br label %loop
-
-loop:
-  %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  call void @bar()
-  br label %merge
-
-merge:
-  %iv.next = add i32 %iv, 1
-  %cond = icmp slt i32 %iv.next, %n
-  br i1 %cond, label %loop, label %exit
-
-exit:
-  ret void
-}
-
-; Some of checks are frequently taken and some are not, make sure that we only
-; widen frequent ones.
-define void @test_06(i1 %cond_0, i1 %cond_1, i1 %cond_2, i1 %cond_3, i1 %cond_4, i32 %n) {
-; CHECK-LABEL: @test_06(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]]
-; CHECK-NEXT:    [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_4:%.*]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"() ]
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]], !prof !3
-; CHECK:       if.true_1:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE_1:%.*]]
-; CHECK:       if.false_1:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE_1]]
-; CHECK:       merge_1:
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]], !prof !1
-; CHECK:       if.true_2:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE_2:%.*]]
-; CHECK:       if.false_2:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE_2]]
-; CHECK:       merge_2:
-; CHECK-NEXT:    br i1 [[COND_3:%.*]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]], !prof !3
-; CHECK:       if.true_3:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE_3:%.*]]
-; CHECK:       if.false_3:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE_3]]
-; CHECK:       merge_3:
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE_4:%.*]], label [[IF_FALSE_4:%.*]], !prof !1
-; CHECK:       if.true_4:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[BACKEDGE]]
-; CHECK:       if.false_4:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[BACKEDGE]]
-; CHECK:       backedge:
-; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br label %loop
-
-loop:
-  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
-  br i1 %cond_1, label %if.true_1, label %if.false_1, !prof !2
-
-if.true_1:
-  call void @foo()
-  br label %merge_1
-
-if.false_1:
-  call void @bar()
-  br label %merge_1
-
-merge_1:
-  br i1 %cond_2, label %if.true_2, label %if.false_2, !prof !1
-
-if.true_2:
-  call void @foo()
-  br label %merge_2
-
-if.false_2:
-  call void @bar()
-  br label %merge_2
-
-merge_2:
-  br i1 %cond_3, label %if.true_3, label %if.false_3, !prof !2
-
-if.true_3:
-  call void @foo()
-  br label %merge_3
-
-if.false_3:
-  call void @bar()
-  br label %merge_3
-
-merge_3:
-  br i1 %cond_4, label %if.true_4, label %if.false_4, !prof !1
-
-if.true_4:
-  call void @foo()
-  br label %backedge
-
-if.false_4:
-  call void @bar()
-  br label %backedge
-
-backedge:
-  %iv.next = add i32 %iv, 1
-  %cond = icmp slt i32 %iv.next, %n
-  br i1 %cond, label %loop, label %exit
-
-exit:
-  ret void
-}
-
-; Similar to test_06, but the likely taken branch is the false branch.
-define void @test_06_not_taken(i1 %cond_0, i1 %cond_1, i1 %cond_2, i1 %cond_3, i1 %cond_4, i32 %n) {
-; CHECK-LABEL: @test_06_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[INVERTED:%.*]] = xor i1 [[COND_2:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
-; CHECK-NEXT:    [[INVERTED1:%.*]] = xor i1 [[COND_4:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK]], [[INVERTED1]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]], !prof !3
-; CHECK:       if.true_1:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE_1:%.*]]
-; CHECK:       if.false_1:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE_1]]
-; CHECK:       merge_1:
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]], !prof !2
-; CHECK:       if.true_2:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE_2:%.*]]
-; CHECK:       if.false_2:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE_2]]
-; CHECK:       merge_2:
-; CHECK-NEXT:    br i1 [[COND_3:%.*]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]], !prof !3
-; CHECK:       if.true_3:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE_3:%.*]]
-; CHECK:       if.false_3:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[MERGE_3]]
-; CHECK:       merge_3:
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE_4:%.*]], label [[IF_FALSE_4:%.*]], !prof !2
-; CHECK:       if.true_4:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[BACKEDGE]]
-; CHECK:       if.false_4:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[BACKEDGE]]
-; CHECK:       backedge:
-; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br label %loop
-
-loop:
-  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
-  br i1 %cond_1, label %if.true_1, label %if.false_1, !prof !2
-
-if.true_1:
-  call void @foo()
-  br label %merge_1
-
-if.false_1:
-  call void @bar()
-  br label %merge_1
-
-merge_1:
-  br i1 %cond_2, label %if.true_2, label %if.false_2, !prof !3
-
-if.true_2:
-  call void @foo()
-  br label %merge_2
-
-if.false_2:
-  call void @bar()
-  br label %merge_2
-
-merge_2:
-  br i1 %cond_3, label %if.true_3, label %if.false_3, !prof !2
-
-if.true_3:
-  call void @foo()
-  br label %merge_3
-
-if.false_3:
-  call void @bar()
-  br label %merge_3
-
-merge_3:
-  br i1 %cond_4, label %if.true_4, label %if.false_4, !prof !3
-
-if.true_4:
-  call void @foo()
-  br label %backedge
-
-if.false_4:
-  call void @bar()
-  br label %backedge
-
-backedge:
-  %iv.next = add i32 %iv, 1
-  %cond = icmp slt i32 %iv.next, %n
-  br i1 %cond, label %loop, label %exit
-
-exit:
-  ret void
-}
-
-; Check triangle CFG pattern.
-define void @test_07(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_07(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[MERGE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %merge, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-merge:
-  ret void
-}
-
-; Similar to test_07, but the likely taken branch is the false branch.
-define void @test_07_not_taken(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_07_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[MERGE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %merge, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-merge:
-  ret void
-}
-
-define void @test_08(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_08(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    ret void
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  ret void
-
-merge:
-  ret void
-}
-
-define void @test_08_not_taken(i1 %cond_0, i1 %cond_1) {
-; CHECK-LABEL: @test_08_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    ret void
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  ret void
-
-merge:
-  ret void
-}
-
-; Check that L >u C0 && L >u C1  ->  L >u max(C0, C1).
-define void @test_09(i32 %L) {
-; CHECK-LABEL: @test_09(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
-; CHECK-NEXT:    [[COND_1:%.*]] = icmp ugt i32 [[L]], 456
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    ret void
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %cond_0 = icmp ugt i32 %L, 123
-  %cond_1 = icmp ugt i32 %L, 456
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  ret void
-
-merge:
-  ret void
-}
-
-; Check that L >u C0 && !(L <=u C1)  ->  L >u max(C0, C1).
-define void @test_09_not_taken(i32 %L) {
-; CHECK-LABEL: @test_09_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
-; CHECK-NEXT:    [[COND_1:%.*]] = icmp ule i32 [[L]], 456
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    ret void
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %cond_0 = icmp ugt i32 %L, 123
-  %cond_1 = icmp ule i32 %L, 456
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  ret void
-
-merge:
-  ret void
-}
-
-; Check that a profitable transform is preferred over non-profitable.
-define void @test_10(i32 %L, i1 %irrelevant_cond, i1 %infinite_loop_cond) {
-; CHECK-LABEL: @test_10(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
-; CHECK-NEXT:    [[COND_1:%.*]] = icmp ugt i32 [[L]], 456
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[IRRELEVANT_COND:%.*]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 [[INFINITE_LOOP_COND:%.*]], label [[LOOP]], label [[AFTER_LOOP:%.*]]
-; CHECK:       after_loop:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %cond_0 = icmp ugt i32 %L, 123
-  %cond_1 = icmp ugt i32 %L, 456
-  br label %loop
-
-loop:
-  call void(i1, ...) @llvm.experimental.guard(i1 %irrelevant_cond) [ "deopt"() ]
-  br i1 %infinite_loop_cond, label %loop, label %after_loop
-
-after_loop:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !1
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  br label %merge
-
-merge:
-  ret void
-}
-
-; Check that a profitable transform is preferred over non-profitable.
-
-define void @test_10_not_taken(i32 %L, i1 %irrelevant_cond, i1 %infinite_loop_cond) {
-; CHECK-LABEL: @test_10_not_taken(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
-; CHECK-NEXT:    [[COND_1:%.*]] = icmp ule i32 [[L]], 456
-; CHECK-NEXT:    br label [[LOOP:%.*]]
-; CHECK:       loop:
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[IRRELEVANT_COND:%.*]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 [[INFINITE_LOOP_COND:%.*]], label [[LOOP]], label [[AFTER_LOOP:%.*]]
-; CHECK:       after_loop:
-; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
-; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
-; CHECK:       if.true:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[MERGE:%.*]]
-; CHECK:       if.false:
-; CHECK-NEXT:    br label [[MERGE]]
-; CHECK:       merge:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %cond_0 = icmp ugt i32 %L, 123
-  %cond_1 = icmp ule i32 %L, 456
-  br label %loop
-
-loop:
-  call void(i1, ...) @llvm.experimental.guard(i1 %irrelevant_cond) [ "deopt"() ]
-  br i1 %infinite_loop_cond, label %loop, label %after_loop
-
-after_loop:
-  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
-  br i1 %cond_1, label %if.true, label %if.false, !prof !3
-
-if.true:
-  call void @foo()
-  br label %merge
-
-if.false:
-  br label %merge
-
-merge:
-  ret void
-}
-
-!0 = !{!"branch_weights", i32 998, i32 1}
-!1 = !{!"branch_weights", i32 999, i32 1}
-!2 = !{!"branch_weights", i32 500, i32 500}
-!3 = !{!"branch_weights", i32 1, i32 999}


        


More information about the llvm-commits mailing list