Skip to content

Commit 59a5964

Browse files
committed
[SimplifyCFG] Don't speculatively execute BB[s] if they are predictably not taken
Same as D106650, but for `FoldTwoEntryPHINode()` Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D106717
1 parent e58ce35 commit 59a5964

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2736,7 +2736,33 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
27362736
PN->blocks(), std::back_inserter(IfBlocks), [](BasicBlock *IfBlock) {
27372737
return cast<BranchInst>(IfBlock->getTerminator())->isUnconditional();
27382738
});
2739-
assert(!IfBlocks.empty() && "Will have at least one block to speculate.");
2739+
assert((IfBlocks.size() == 1 || IfBlocks.size() == 2) &&
2740+
"Will have either one or two blocks to speculate.");
2741+
2742+
// If the branch is non-unpredictable, see if we either predictably jump to
2743+
// the merge bb (if we have only a single 'then' block), or if we predictably
2744+
// jump to one specific 'then' block (if we have two of them).
2745+
// It isn't beneficial to speculatively execute the code
2746+
// from the block that we know is predictably not entered.
2747+
if (!DomBI->getMetadata(LLVMContext::MD_unpredictable)) {
2748+
uint64_t TWeight, FWeight;
2749+
if (DomBI->extractProfMetadata(TWeight, FWeight) &&
2750+
(TWeight + FWeight) != 0) {
2751+
BranchProbability BITrueProb =
2752+
BranchProbability::getBranchProbability(TWeight, TWeight + FWeight);
2753+
BranchProbability Likely = TTI.getPredictableBranchThreshold();
2754+
BranchProbability BIFalseProb = BITrueProb.getCompl();
2755+
if (IfBlocks.size() == 1) {
2756+
BranchProbability BIBBProb =
2757+
DomBI->getSuccessor(0) == BB ? BITrueProb : BIFalseProb;
2758+
if (BIBBProb >= Likely)
2759+
return false;
2760+
} else {
2761+
if (BITrueProb >= Likely || BIFalseProb >= Likely)
2762+
return false;
2763+
}
2764+
}
2765+
}
27402766

27412767
// Don't try to fold an unreachable block. For example, the phi node itself
27422768
// can't be the candidate if-condition for a select that we want to form.

llvm/test/Transforms/PGOProfile/chr.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2013,7 +2013,8 @@ define i64 @test_chr_22(i1 %i, i64* %j, i64 %v0) !prof !14 {
20132013
; CHECK-NEXT: [[C1:%.*]] = icmp slt i64 [[V2]], 100
20142014
; CHECK-NEXT: br i1 [[C1]], label [[BB0_SPLIT:%.*]], label [[BB0_SPLIT_NONCHR:%.*]], !prof [[PROF15]]
20152015
; CHECK: common.ret:
2016-
; CHECK-NEXT: ret i64 99
2016+
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i64 [ 99, [[BB0_SPLIT]] ], [ 99, [[BB0_SPLIT_NONCHR]] ]
2017+
; CHECK-NEXT: ret i64 [[COMMON_RET_OP]]
20172018
; CHECK: bb0.split:
20182019
; CHECK-NEXT: [[V299:%.*]] = mul i64 [[V2]], 7860086430977039991
20192020
; CHECK-NEXT: store i64 [[V299]], i64* [[J:%.*]], align 4

llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-one-block-profmd.ll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
5959
; CHECK-NEXT: entry:
6060
; CHECK-NEXT: call void @sideeffect0()
6161
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
62+
; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
63+
; CHECK: cond.true:
6264
; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
63-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 [[V0]], !prof [[PROF0]]
65+
; CHECK-NEXT: br label [[END]]
66+
; CHECK: end:
67+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
6468
; CHECK-NEXT: call void @sideeffect1()
6569
; CHECK-NEXT: ret i32 [[RES]]
6670
;

llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-two-blocks-profmd.ll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ define i32 @predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) {
3939
; CHECK-NEXT: entry:
4040
; CHECK-NEXT: call void @sideeffect0()
4141
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
42+
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF0:![0-9]+]]
43+
; CHECK: cond.true:
4244
; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
45+
; CHECK-NEXT: br label [[END:%.*]]
46+
; CHECK: cond.false:
4347
; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]]
44-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !prof [[PROF0:![0-9]+]]
48+
; CHECK-NEXT: br label [[END]]
49+
; CHECK: end:
50+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ]
4551
; CHECK-NEXT: call void @sideeffect1()
4652
; CHECK-NEXT: ret i32 [[RES]]
4753
;
@@ -99,9 +105,15 @@ define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
99105
; CHECK-NEXT: entry:
100106
; CHECK-NEXT: call void @sideeffect0()
101107
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
108+
; CHECK-NEXT: br i1 [[CMP]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
109+
; CHECK: cond.true:
102110
; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
111+
; CHECK-NEXT: br label [[END:%.*]]
112+
; CHECK: cond.false:
103113
; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]]
104-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V1]], i32 [[V0]], !prof [[PROF0]]
114+
; CHECK-NEXT: br label [[END]]
115+
; CHECK: end:
116+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ]
105117
; CHECK-NEXT: call void @sideeffect1()
106118
; CHECK-NEXT: ret i32 [[RES]]
107119
;

0 commit comments

Comments
 (0)