From e58ce35f7b672b87baf8402de286b13df6082a00 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Mon, 26 Jul 2021 02:30:31 +0300 Subject: [PATCH] [SimplifyCFG] Don't speculatively execute BB if it's predictably not taken If the branch isn't `unpredictable`, and it is predicted to *not* branch to the block we are considering speculatively executing, then it seems counter-productive to execute the code that is predicted not to be executed. Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D106650 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 14 ++++++++++++++ .../SimplifyCFG/speculatively-execute-block-profmd.ll | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index a58568d..f2f1519 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2372,6 +2372,20 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB, } assert(EndBB == BI->getSuccessor(!Invert) && "No edge from to end block"); + // If the branch is non-unpredictable, and is predicted to *not* branch to + // the `then` block, then avoid speculating it. + if (!BI->getMetadata(LLVMContext::MD_unpredictable)) { + uint64_t TWeight, FWeight; + if (BI->extractProfMetadata(TWeight, FWeight) && (TWeight + FWeight) != 0) { + uint64_t EndWeight = Invert ? TWeight : FWeight; + BranchProbability BIEndProb = + BranchProbability::getBranchProbability(EndWeight, TWeight + FWeight); + BranchProbability Likely = TTI.getPredictableBranchThreshold(); + if (BIEndProb >= Likely) + return false; + } + } + // Keep a count of how many times instructions are used within ThenBB when // they are candidates for sinking into ThenBB. Specifically: // - They are defined in BB, and diff --git a/llvm/test/Transforms/SimplifyCFG/speculatively-execute-block-profmd.ll b/llvm/test/Transforms/SimplifyCFG/speculatively-execute-block-profmd.ll index 8996f67..8748116 100644 --- a/llvm/test/Transforms/SimplifyCFG/speculatively-execute-block-profmd.ll +++ b/llvm/test/Transforms/SimplifyCFG/speculatively-execute-block-profmd.ll @@ -83,11 +83,12 @@ define i32 @predictably_nontaken(i1 %c, i32 %a, i32 %b) { ; CHECK: dispatch: ; CHECK-NEXT: call void @sideeffect1() ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[END]], label [[COND_TRUE:%.*]], !prof [[PROF0]] +; CHECK: cond.true: ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]] -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 0, i32 [[VAL]], !prof [[PROF0]] ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ] +; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 0, [[DISPATCH]] ], [ [[VAL]], [[COND_TRUE]] ] ; CHECK-NEXT: call void @sideeffect2() ; CHECK-NEXT: ret i32 [[RES]] ; -- 2.7.4