Skip to content

Commit 4662871

Browse files
authored
[IR][PGO] Verify the structure of VP metadata. (#145584)
1 parent 878d359 commit 4662871

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

llvm/include/llvm/IR/ProfDataUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ LLVM_ABI bool hasProfMD(const Instruction &I);
3535
/// Checks if an MDNode contains Branch Weight Metadata
3636
LLVM_ABI bool isBranchWeightMD(const MDNode *ProfileData);
3737

38+
/// Checks if an MDNode contains value profiling Metadata
39+
LLVM_ABI bool isValueProfileMD(const MDNode *ProfileData);
40+
3841
/// Checks if an instructions has Branch Weight Metadata
3942
///
4043
/// \param I The instruction to check

llvm/lib/IR/ProfDataUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ bool isBranchWeightMD(const MDNode *ProfileData) {
103103
return isTargetMD(ProfileData, MDProfLabels::BranchWeights, MinBWOps);
104104
}
105105

106-
static bool isValueProfileMD(const MDNode *ProfileData) {
106+
bool isValueProfileMD(const MDNode *ProfileData) {
107107
return isTargetMD(ProfileData, MDProfLabels::ValueProfile, MinVPOps);
108108
}
109109

llvm/lib/IR/Verifier.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
#include "llvm/IR/Value.h"
113113
#include "llvm/InitializePasses.h"
114114
#include "llvm/Pass.h"
115+
#include "llvm/ProfileData/InstrProf.h"
115116
#include "llvm/Support/AMDGPUAddrSpace.h"
116117
#include "llvm/Support/AtomicOrdering.h"
117118
#include "llvm/Support/Casting.h"
@@ -5032,9 +5033,27 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
50325033
Check(mdconst::dyn_extract<ConstantInt>(MDO),
50335034
"!prof brunch_weights operand is not a const int");
50345035
}
5036+
} else if (ProfName == MDProfLabels::ValueProfile) {
5037+
Check(isValueProfileMD(MD), "invalid value profiling metadata", MD);
5038+
ConstantInt *KindInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
5039+
Check(KindInt, "VP !prof missing kind argument", MD);
5040+
5041+
auto Kind = KindInt->getZExtValue();
5042+
Check(Kind >= InstrProfValueKind::IPVK_First &&
5043+
Kind <= InstrProfValueKind::IPVK_Last,
5044+
"Invalid VP !prof kind", MD);
5045+
Check(MD->getNumOperands() % 2 == 1,
5046+
"VP !prof should have an even number "
5047+
"of arguments after 'VP'",
5048+
MD);
5049+
if (Kind == InstrProfValueKind::IPVK_IndirectCallTarget ||
5050+
Kind == InstrProfValueKind::IPVK_MemOPSize)
5051+
Check(isa<CallBase>(I),
5052+
"VP !prof indirect call or memop size expected to be applied to "
5053+
"CallBase instructions only",
5054+
MD);
50355055
} else {
5036-
Check(ProfName == MDProfLabels::ValueProfile,
5037-
"expected either branch_weights or VP profile name", MD);
5056+
CheckFailed("expected either branch_weights or VP profile name", MD);
50385057
}
50395058
}
50405059

llvm/test/Verifier/value-profile.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; Test MD_prof "VP" validation
2+
3+
; RUN: split-file %s %t
4+
; RUN: opt -passes=verify %t/valid.ll --disable-output
5+
; RUN: not opt -passes=verify %t/invalid-kind.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-KIND
6+
; RUN: not opt -passes=verify %t/invalid-count.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-COUNT
7+
; RUN: not opt -passes=verify %t/invalid-place.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-PLACE
8+
9+
;--- valid.ll
10+
define void @test(ptr %0) {
11+
call void %0(), !prof !0
12+
ret void
13+
}
14+
!0 = !{!"VP", i32 0, i32 20, i64 1234, i64 10, i64 5678, i64 5}
15+
16+
;--- invalid-kind.ll
17+
define void @test(ptr %0) {
18+
call void %0(), !prof !0
19+
ret void
20+
}
21+
!0 = !{!"VP", i32 3, i32 20, i64 1234, i64 10, i64 5678, i64 5}
22+
; INVALID-KIND: Invalid VP !prof kind
23+
24+
;--- invalid-count.ll
25+
define void @test(ptr %0) {
26+
call void %0(), !prof !0
27+
ret void
28+
}
29+
!0 = !{!"VP", i32 1, i64 1234, i64 10, i64 5678, i64 5}
30+
; INVALID-COUNT: VP !prof should have an even number of arguments after 'VP'
31+
32+
;--- invalid-place.ll
33+
define i32 @test(i32 %0) {
34+
%r = add i32 %0, 1, !prof !0
35+
ret i32 %r
36+
}
37+
!0 = !{!"VP", i32 1, i32 20, i64 1234, i64 10, i64 5678, i64 5}
38+
; INVALID-PLACE: VP !prof indirect call or memop size expected to be applied to CallBase instructions only

0 commit comments

Comments
 (0)