aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorMircea Trofin <mtrofin@google.com>2025-06-30 16:57:11 -0700
committerGitHub <noreply@github.com>2025-06-30 16:57:11 -0700
commitd2500e639b641b0cfdd1564cc6ff4705b118f10c (patch)
tree18ec37f4aaf25a2008d6bee8b81049518492be42 /llvm/lib/IR/Verifier.cpp
parent12409a18f609f965fbd40aba77a0b50dcdba147f (diff)
downloadllvm-d2500e639b641b0cfdd1564cc6ff4705b118f10c.zip
llvm-d2500e639b641b0cfdd1564cc6ff4705b118f10c.tar.gz
llvm-d2500e639b641b0cfdd1564cc6ff4705b118f10c.tar.bz2
[pgo] add means to specify "unknown" MD_prof (#145578)
This PR is part of https://discourse.llvm.org/t/rfc-profile-information-propagation-unittesting/73595 In a slight departure from the RFC, instead of a brand-new `MD_prof_unknown` kind, this adds a first operand to `MD_prof` metadata. This makes it easy to replace with valid metadata (only one `MD_prof`), otherwise sites inserting valid `MD_prof` would also have to check to remove the `unknown` one. The patch just introduces the notion and fixes the verifier accordingly. Existing APIs working (esp. reading) `MD_prof` will be updated subsequently.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp56
1 files changed, 39 insertions, 17 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 853f3b4..227afe2b 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2527,6 +2527,12 @@ void Verifier::verifyFunctionMetadata(
for (const auto &Pair : MDs) {
if (Pair.first == LLVMContext::MD_prof) {
MDNode *MD = Pair.second;
+ if (isExplicitlyUnknownBranchWeightsMetadata(*MD)) {
+ CheckFailed("'unknown' !prof metadata should appear only on "
+ "instructions supporting the 'branch_weights' metadata",
+ MD);
+ continue;
+ }
Check(MD->getNumOperands() >= 2,
"!prof annotations should have no less than 2 operands", MD);
@@ -4989,9 +4995,24 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) {
}
void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
- Check(MD->getNumOperands() >= 2,
- "!prof annotations should have no less than 2 operands", MD);
-
+ auto GetBranchingTerminatorNumOperands = [&]() {
+ unsigned ExpectedNumOperands = 0;
+ if (BranchInst *BI = dyn_cast<BranchInst>(&I))
+ ExpectedNumOperands = BI->getNumSuccessors();
+ else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I))
+ ExpectedNumOperands = SI->getNumSuccessors();
+ else if (isa<CallInst>(&I))
+ ExpectedNumOperands = 1;
+ else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I))
+ ExpectedNumOperands = IBI->getNumDestinations();
+ else if (isa<SelectInst>(&I))
+ ExpectedNumOperands = 2;
+ else if (CallBrInst *CI = dyn_cast<CallBrInst>(&I))
+ ExpectedNumOperands = CI->getNumSuccessors();
+ return ExpectedNumOperands;
+ };
+ Check(MD->getNumOperands() >= 1,
+ "!prof annotations should have at least 1 operand", MD);
// Check first operand.
Check(MD->getOperand(0) != nullptr, "first operand should not be null", MD);
Check(isa<MDString>(MD->getOperand(0)),
@@ -4999,6 +5020,19 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
MDString *MDS = cast<MDString>(MD->getOperand(0));
StringRef ProfName = MDS->getString();
+ if (ProfName == MDProfLabels::UnknownBranchWeightsMarker) {
+ Check(GetBranchingTerminatorNumOperands() != 0 || isa<InvokeInst>(I),
+ "'unknown' !prof should only appear on instructions on which "
+ "'branch_weights' would",
+ MD);
+ Check(MD->getNumOperands() == 1,
+ "'unknown' !prof should have no additional operands", MD);
+ return;
+ }
+
+ Check(MD->getNumOperands() >= 2,
+ "!prof annotations should have no less than 2 operands", MD);
+
// Check consistency of !prof branch_weights metadata.
if (ProfName == MDProfLabels::BranchWeights) {
unsigned NumBranchWeights = getNumBranchWeights(*MD);
@@ -5006,20 +5040,8 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
Check(NumBranchWeights == 1 || NumBranchWeights == 2,
"Wrong number of InvokeInst branch_weights operands", MD);
} else {
- unsigned ExpectedNumOperands = 0;
- if (BranchInst *BI = dyn_cast<BranchInst>(&I))
- ExpectedNumOperands = BI->getNumSuccessors();
- else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I))
- ExpectedNumOperands = SI->getNumSuccessors();
- else if (isa<CallInst>(&I))
- ExpectedNumOperands = 1;
- else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I))
- ExpectedNumOperands = IBI->getNumDestinations();
- else if (isa<SelectInst>(&I))
- ExpectedNumOperands = 2;
- else if (CallBrInst *CI = dyn_cast<CallBrInst>(&I))
- ExpectedNumOperands = CI->getNumSuccessors();
- else
+ const unsigned ExpectedNumOperands = GetBranchingTerminatorNumOperands();
+ if (ExpectedNumOperands == 0)
CheckFailed("!prof branch_weights are not allowed for this instruction",
MD);