Skip to content

Commit e58ce35

Browse files
committed
[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
1 parent 48379f2 commit e58ce35

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,6 +2372,20 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
23722372
}
23732373
assert(EndBB == BI->getSuccessor(!Invert) && "No edge from to end block");
23742374

2375+
// If the branch is non-unpredictable, and is predicted to *not* branch to
2376+
// the `then` block, then avoid speculating it.
2377+
if (!BI->getMetadata(LLVMContext::MD_unpredictable)) {
2378+
uint64_t TWeight, FWeight;
2379+
if (BI->extractProfMetadata(TWeight, FWeight) && (TWeight + FWeight) != 0) {
2380+
uint64_t EndWeight = Invert ? TWeight : FWeight;
2381+
BranchProbability BIEndProb =
2382+
BranchProbability::getBranchProbability(EndWeight, TWeight + FWeight);
2383+
BranchProbability Likely = TTI.getPredictableBranchThreshold();
2384+
if (BIEndProb >= Likely)
2385+
return false;
2386+
}
2387+
}
2388+
23752389
// Keep a count of how many times instructions are used within ThenBB when
23762390
// they are candidates for sinking into ThenBB. Specifically:
23772391
// - They are defined in BB, and

llvm/test/Transforms/SimplifyCFG/speculatively-execute-block-profmd.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ define i32 @predictably_nontaken(i1 %c, i32 %a, i32 %b) {
8383
; CHECK: dispatch:
8484
; CHECK-NEXT: call void @sideeffect1()
8585
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
86+
; CHECK-NEXT: br i1 [[CMP]], label [[END]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
87+
; CHECK: cond.true:
8688
; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
87-
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 0, i32 [[VAL]], !prof [[PROF0]]
8889
; CHECK-NEXT: br label [[END]]
8990
; CHECK: end:
90-
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
91+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 0, [[DISPATCH]] ], [ [[VAL]], [[COND_TRUE]] ]
9192
; CHECK-NEXT: call void @sideeffect2()
9293
; CHECK-NEXT: ret i32 [[RES]]
9394
;

0 commit comments

Comments
 (0)