Skip to content

Commit 10f0c1a

Browse files
authored
[PGO] Ensure non-zero entry-count after populateCounters (#112029)
With sampled instrumentation (#69535), profile counts may appear corrupt and `fixFuncEntryCount` may assert. In particular a function can have a 0 block count for its entry, while later blocks are non zero. This is only likely to happen for colder functions, so it is reasonable to take any action that does not crash. Here we simply bail from fixing the entry count.
1 parent 8a12e01 commit 10f0c1a

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,10 @@ void PGOUseFunc::populateCounters() {
16151615
assert(BI->Count && "BB count is not valid");
16161616
}
16171617
#endif
1618+
// Now annotate select instructions. This may fixup impossible block counts.
1619+
FuncInfo.SIVisitor.annotateSelects(this, &CountPosition);
1620+
assert(CountPosition == ProfileCountSize);
1621+
16181622
uint64_t FuncEntryCount = *getBBInfo(&*F.begin()).Count;
16191623
uint64_t FuncMaxCount = FuncEntryCount;
16201624
for (auto &BB : F) {
@@ -1630,10 +1634,6 @@ void PGOUseFunc::populateCounters() {
16301634
F.setEntryCount(ProfileCount(FuncEntryCount, Function::PCT_Real));
16311635
markFunctionAttributes(FuncEntryCount, FuncMaxCount);
16321636

1633-
// Now annotate select instructions
1634-
FuncInfo.SIVisitor.annotateSelects(this, &CountPosition);
1635-
assert(CountPosition == ProfileCountSize);
1636-
16371637
LLVM_DEBUG(FuncInfo.dumpInfo("after reading profile."));
16381638
}
16391639

@@ -1742,8 +1742,13 @@ void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
17421742
++(*CurCtrIdx);
17431743
uint64_t TotalCount = 0;
17441744
auto BI = UseFunc->findBBInfo(SI.getParent());
1745-
if (BI != nullptr)
1745+
if (BI != nullptr) {
17461746
TotalCount = *BI->Count;
1747+
1748+
// Fix the block count if it is impossible.
1749+
if (TotalCount < SCounts[0])
1750+
BI->Count = SCounts[0];
1751+
}
17471752
// False Count
17481753
SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
17491754
uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: rm -rf %t && split-file %s %t
2+
3+
; RUN: llvm-profdata merge %t/main.proftext -o %t/main.profdata
4+
; RUN: opt < %t/main.ll -passes=pgo-instr-use -pgo-test-profile-file=%t/main.profdata -S | FileCheck %s
5+
6+
;--- main.ll
7+
8+
; Instrumentation PGO sampling makes corrupt looking counters possible. This
9+
; tests one extreme case:
10+
; Test loading zero profile counts for all instrumented blocks while the entry
11+
; block is not instrumented. Additionally include a non-zero profile count for
12+
; a select instruction, which prevents short circuiting the PGO application.
13+
14+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
15+
target triple = "x86_64-unknown-linux-gnu"
16+
17+
define i32 @test_no_entry_block_counter(i32 %n) {
18+
; CHECK: define i32 @test_no_entry_block_counter(i32 %n)
19+
; CHECK-SAME: !prof ![[ENTRY_COUNT:[0-9]*]]
20+
entry:
21+
%cmp = icmp slt i32 42, %n
22+
br i1 %cmp, label %tail1, label %tail2
23+
tail1:
24+
%ret = select i1 true, i32 %n, i32 42
25+
; CHECK: %ret = select i1 true, i32 %n, i32 42
26+
; CHECK-SAME: !prof ![[BW_FOR_SELECT:[0-9]+]]
27+
ret i32 %ret
28+
tail2:
29+
ret i32 42
30+
}
31+
; CHECK: ![[ENTRY_COUNT]] = !{!"function_entry_count", i64 1}
32+
; CHECK: ![[BW_FOR_SELECT]] = !{!"branch_weights", i32 1, i32 0}
33+
34+
;--- main.proftext
35+
:ir
36+
test_no_entry_block_counter
37+
431494656217155589
38+
3
39+
0
40+
0
41+
1
42+

0 commit comments

Comments
 (0)