[IR][PGO] Verify the structure of VP metadata. (#145584)

This commit is contained in:
Mircea Trofin 2025-06-30 12:31:19 -07:00 committed by GitHub
parent 878d3594ed
commit 46628718c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 63 additions and 3 deletions

View File

@ -35,6 +35,9 @@ LLVM_ABI bool hasProfMD(const Instruction &I);
/// Checks if an MDNode contains Branch Weight Metadata
LLVM_ABI bool isBranchWeightMD(const MDNode *ProfileData);
/// Checks if an MDNode contains value profiling Metadata
LLVM_ABI bool isValueProfileMD(const MDNode *ProfileData);
/// Checks if an instructions has Branch Weight Metadata
///
/// \param I The instruction to check

View File

@ -103,7 +103,7 @@ bool isBranchWeightMD(const MDNode *ProfileData) {
return isTargetMD(ProfileData, MDProfLabels::BranchWeights, MinBWOps);
}
static bool isValueProfileMD(const MDNode *ProfileData) {
bool isValueProfileMD(const MDNode *ProfileData) {
return isTargetMD(ProfileData, MDProfLabels::ValueProfile, MinVPOps);
}

View File

@ -112,6 +112,7 @@
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/AMDGPUAddrSpace.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
@ -5032,9 +5033,27 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
Check(mdconst::dyn_extract<ConstantInt>(MDO),
"!prof brunch_weights operand is not a const int");
}
} else if (ProfName == MDProfLabels::ValueProfile) {
Check(isValueProfileMD(MD), "invalid value profiling metadata", MD);
ConstantInt *KindInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
Check(KindInt, "VP !prof missing kind argument", MD);
auto Kind = KindInt->getZExtValue();
Check(Kind >= InstrProfValueKind::IPVK_First &&
Kind <= InstrProfValueKind::IPVK_Last,
"Invalid VP !prof kind", MD);
Check(MD->getNumOperands() % 2 == 1,
"VP !prof should have an even number "
"of arguments after 'VP'",
MD);
if (Kind == InstrProfValueKind::IPVK_IndirectCallTarget ||
Kind == InstrProfValueKind::IPVK_MemOPSize)
Check(isa<CallBase>(I),
"VP !prof indirect call or memop size expected to be applied to "
"CallBase instructions only",
MD);
} else {
Check(ProfName == MDProfLabels::ValueProfile,
"expected either branch_weights or VP profile name", MD);
CheckFailed("expected either branch_weights or VP profile name", MD);
}
}

View File

@ -0,0 +1,38 @@
; Test MD_prof "VP" validation
; RUN: split-file %s %t
; RUN: opt -passes=verify %t/valid.ll --disable-output
; RUN: not opt -passes=verify %t/invalid-kind.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-KIND
; RUN: not opt -passes=verify %t/invalid-count.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-COUNT
; RUN: not opt -passes=verify %t/invalid-place.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-PLACE
;--- valid.ll
define void @test(ptr %0) {
call void %0(), !prof !0
ret void
}
!0 = !{!"VP", i32 0, i32 20, i64 1234, i64 10, i64 5678, i64 5}
;--- invalid-kind.ll
define void @test(ptr %0) {
call void %0(), !prof !0
ret void
}
!0 = !{!"VP", i32 3, i32 20, i64 1234, i64 10, i64 5678, i64 5}
; INVALID-KIND: Invalid VP !prof kind
;--- invalid-count.ll
define void @test(ptr %0) {
call void %0(), !prof !0
ret void
}
!0 = !{!"VP", i32 1, i64 1234, i64 10, i64 5678, i64 5}
; INVALID-COUNT: VP !prof should have an even number of arguments after 'VP'
;--- invalid-place.ll
define i32 @test(i32 %0) {
%r = add i32 %0, 1, !prof !0
ret i32 %r
}
!0 = !{!"VP", i32 1, i32 20, i64 1234, i64 10, i64 5678, i64 5}
; INVALID-PLACE: VP !prof indirect call or memop size expected to be applied to CallBase instructions only