From cd1de28b1e49310f97ed051998e950ec6d44389f Mon Sep 17 00:00:00 2001 From: Yevgeny Rouban Date: Tue, 13 Aug 2019 04:03:38 +0000 Subject: [PATCH] Verifier: check prof branch_weights This patch is to check some of constraints on !pro branch_weights metadata: https://llvm.org/docs/BranchWeightMetadata.html Reviewers: asbirlea, reames, chandlerc Reviewed By: reames Differential Revision: https://reviews.llvm.org/D61179 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368647 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Verifier.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index f961aa73c9d..2e109c5f6d9 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -418,6 +418,7 @@ private: void visitBasicBlock(BasicBlock &BB); void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); + void visitProfMetadata(Instruction &I, MDNode *MD); template bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); @@ -3996,6 +3997,45 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) { "dereferenceable_or_null metadata value must be an i64!", &I); } +void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { + Assert(MD->getNumOperands() >= 2, + "!prof annotations should have no less than 2 operands", MD); + + // Check first operand. + Assert(MD->getOperand(0) != nullptr, "first operand should not be null", MD); + Assert(isa(MD->getOperand(0)), + "expected string with name of the !prof annotation", MD); + MDString *MDS = cast(MD->getOperand(0)); + StringRef ProfName = MDS->getString(); + + // Check consistency of !prof branch_weights metadata. + if (ProfName.equals("branch_weights")) { + unsigned ExpectedNumOperands = 0; + if (BranchInst *BI = dyn_cast(&I)) + ExpectedNumOperands = BI->getNumSuccessors(); + else if (SwitchInst *SI = dyn_cast(&I)) + ExpectedNumOperands = SI->getNumSuccessors(); + else if (isa(&I) || isa(&I)) + ExpectedNumOperands = 1; + else if (IndirectBrInst *IBI = dyn_cast(&I)) + ExpectedNumOperands = IBI->getNumDestinations(); + else if (isa(&I)) + ExpectedNumOperands = 2; + else + CheckFailed("!prof branch_weights are not allowed for this instruction", + MD); + + Assert(MD->getNumOperands() == 1 + ExpectedNumOperands, + "Wrong number of operands", MD); + for (unsigned i = 1; i < MD->getNumOperands(); ++i) { + auto &MDO = MD->getOperand(i); + Assert(MDO, "second operand should not be null", MD); + Assert(mdconst::dyn_extract(MDO), + "!prof brunch_weights operand is not a const int"); + } + } +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -4153,6 +4193,9 @@ void Verifier::visitInstruction(Instruction &I) { "alignment is larger that implementation defined limit", &I); } + if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof)) + visitProfMetadata(I, MD); + if (MDNode *N = I.getDebugLoc().getAsMDNode()) { AssertDI(isa(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N); -- 2.40.0