aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorMircea Trofin <mtrofin@google.com>2025-09-10 15:34:35 -0700
committerGitHub <noreply@github.com>2025-09-10 15:34:35 -0700
commitf2d827c444d07b722a94689b427d6ad2d1c6b1b7 (patch)
tree0889e7d5698d24a9f00b81a4d02a1e49357b45b8 /llvm/lib/IR/Verifier.cpp
parent613caa909c78f707e88960723c6a98364656a926 (diff)
downloadllvm-f2d827c444d07b722a94689b427d6ad2d1c6b1b7.zip
llvm-f2d827c444d07b722a94689b427d6ad2d1c6b1b7.tar.gz
llvm-f2d827c444d07b722a94689b427d6ad2d1c6b1b7.tar.bz2
[profcheck] Require `unknown` metadata have an origin parameter (#157594)
Rather than passes using `!prof = !{!”unknown”}`​for cases where don’t have enough information to emit profile values, this patch captures the pass (or some other information) that can help diagnostics - i.e. `!{!”unknown”, !”some-pass-name”}`​. For example, suppose we emitted a `select`​ with the unknown metadata, and, later, end up needing to lower that to a conditional branch. If we observe (via sample profiling, for example) that the branch is biased and would have benefitted from a valid profile, the extra information can help speed up debugging. We can also (in a subsequent pass) generate optimization remarks about such lowered selects, with a similar aim - identify patterns lowering to `select`​ that may be worth some extra investment in extracting a more precise profile.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 81a5372..7d362ce 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -631,7 +631,7 @@ private:
void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
const Value *V, bool IsIntrinsic, bool IsInlineAsm);
void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
-
+ void verifyUnknownProfileMetadata(MDNode *MD);
void visitConstantExprsRecursively(const Constant *EntryC);
void visitConstantExpr(const ConstantExpr *CE);
void visitConstantPtrAuth(const ConstantPtrAuth *CPA);
@@ -2515,19 +2515,31 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
V);
}
}
+void Verifier::verifyUnknownProfileMetadata(MDNode *MD) {
+ Check(MD->getNumOperands() == 2,
+ "'unknown' !prof should have a single additional operand", MD);
+ auto *PassName = dyn_cast<MDString>(MD->getOperand(1));
+ Check(PassName != nullptr,
+ "'unknown' !prof should have an additional operand of type "
+ "string");
+ Check(!PassName->getString().empty(),
+ "the 'unknown' !prof operand should not be an empty string");
+}
void Verifier::verifyFunctionMetadata(
ArrayRef<std::pair<unsigned, MDNode *>> MDs) {
for (const auto &Pair : MDs) {
if (Pair.first == LLVMContext::MD_prof) {
MDNode *MD = Pair.second;
+ Check(MD->getNumOperands() >= 2,
+ "!prof annotations should have no less than 2 operands", MD);
// We may have functions that are synthesized by the compiler, e.g. in
// WPD, that we can't currently determine the entry count.
- if (isExplicitlyUnknownProfileMetadata(*MD))
+ if (MD->getOperand(0).equalsStr(
+ MDProfLabels::UnknownBranchWeightsMarker)) {
+ verifyUnknownProfileMetadata(MD);
continue;
-
- Check(MD->getNumOperands() >= 2,
- "!prof annotations should have no less than 2 operands", MD);
+ }
// Check first operand.
Check(MD->getOperand(0) != nullptr, "first operand should not be null",
@@ -5054,8 +5066,7 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
"'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);
+ verifyUnknownProfileMetadata(MD);
return;
}