summaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp110
1 files changed, 84 insertions, 26 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 75d02f4c8c82..e3ea256af16d 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -469,6 +469,9 @@ private:
void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
void visitDereferenceableMetadata(Instruction &I, MDNode *MD);
void visitProfMetadata(Instruction &I, MDNode *MD);
+ void visitCallStackMetadata(MDNode *MD);
+ void visitMemProfMetadata(Instruction &I, MDNode *MD);
+ void visitCallsiteMetadata(Instruction &I, MDNode *MD);
void visitAnnotationMetadata(MDNode *Annotation);
void visitAliasScopeMetadata(const MDNode *MD);
void visitAliasScopeListMetadata(const MDNode *MD);
@@ -1624,8 +1627,10 @@ Verifier::visitModuleFlag(const MDNode *Op,
break;
case Module::Min: {
- Check(mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)),
- "invalid value for 'min' module flag (expected constant integer)",
+ auto *V = mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2));
+ Check(V && V->getValue().isNonNegative(),
+ "invalid value for 'min' module flag (expected constant non-negative "
+ "integer)",
Op->getOperand(2));
break;
}
@@ -2200,7 +2205,13 @@ bool Verifier::verifyAttributeCount(AttributeList Attrs, unsigned Params) {
void Verifier::verifyInlineAsmCall(const CallBase &Call) {
const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
unsigned ArgNo = 0;
+ unsigned LabelNo = 0;
for (const InlineAsm::ConstraintInfo &CI : IA->ParseConstraints()) {
+ if (CI.Type == InlineAsm::isLabel) {
+ ++LabelNo;
+ continue;
+ }
+
// Only deal with constraints that correspond to call arguments.
if (!CI.hasArg())
continue;
@@ -2222,6 +2233,15 @@ void Verifier::verifyInlineAsmCall(const CallBase &Call) {
ArgNo++;
}
+
+ if (auto *CallBr = dyn_cast<CallBrInst>(&Call)) {
+ Check(LabelNo == CallBr->getNumIndirectDests(),
+ "Number of label constraints does not match number of callbr dests",
+ &Call);
+ } else {
+ Check(LabelNo == 0, "Label constraints can only be used with callbr",
+ &Call);
+ }
}
/// Verify that statepoint intrinsic is well formed.
@@ -2839,25 +2859,6 @@ void Verifier::visitCallBrInst(CallBrInst &CBI) {
Check(CBI.isInlineAsm(), "Callbr is currently only used for asm-goto!", &CBI);
const InlineAsm *IA = cast<InlineAsm>(CBI.getCalledOperand());
Check(!IA->canThrow(), "Unwinding from Callbr is not allowed");
- for (unsigned i = 0, e = CBI.getNumSuccessors(); i != e; ++i)
- Check(CBI.getSuccessor(i)->getType()->isLabelTy(),
- "Callbr successors must all have pointer type!", &CBI);
- for (unsigned i = 0, e = CBI.getNumOperands(); i != e; ++i) {
- Check(i >= CBI.arg_size() || !isa<BasicBlock>(CBI.getOperand(i)),
- "Using an unescaped label as a callbr argument!", &CBI);
- if (isa<BasicBlock>(CBI.getOperand(i)))
- for (unsigned j = i + 1; j != e; ++j)
- Check(CBI.getOperand(i) != CBI.getOperand(j),
- "Duplicate callbr destination!", &CBI);
- }
- {
- SmallPtrSet<BasicBlock *, 4> ArgBBs;
- for (Value *V : CBI.args())
- if (auto *BA = dyn_cast<BlockAddress>(V))
- ArgBBs.insert(BA->getBasicBlock());
- for (BasicBlock *BB : CBI.getIndirectDests())
- Check(ArgBBs.count(BB), "Indirect label missing from arglist.", &CBI);
- }
verifyInlineAsmCall(CBI);
visitTerminator(CBI);
@@ -4489,6 +4490,55 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
}
}
+void Verifier::visitCallStackMetadata(MDNode *MD) {
+ // Call stack metadata should consist of a list of at least 1 constant int
+ // (representing a hash of the location).
+ Check(MD->getNumOperands() >= 1,
+ "call stack metadata should have at least 1 operand", MD);
+
+ for (const auto &Op : MD->operands())
+ Check(mdconst::dyn_extract_or_null<ConstantInt>(Op),
+ "call stack metadata operand should be constant integer", Op);
+}
+
+void Verifier::visitMemProfMetadata(Instruction &I, MDNode *MD) {
+ Check(isa<CallBase>(I), "!memprof metadata should only exist on calls", &I);
+ Check(MD->getNumOperands() >= 1,
+ "!memprof annotations should have at least 1 metadata operand "
+ "(MemInfoBlock)",
+ MD);
+
+ // Check each MIB
+ for (auto &MIBOp : MD->operands()) {
+ MDNode *MIB = dyn_cast<MDNode>(MIBOp);
+ // The first operand of an MIB should be the call stack metadata.
+ // There rest of the operands should be MDString tags, and there should be
+ // at least one.
+ Check(MIB->getNumOperands() >= 2,
+ "Each !memprof MemInfoBlock should have at least 2 operands", MIB);
+
+ // Check call stack metadata (first operand).
+ Check(MIB->getOperand(0) != nullptr,
+ "!memprof MemInfoBlock first operand should not be null", MIB);
+ Check(isa<MDNode>(MIB->getOperand(0)),
+ "!memprof MemInfoBlock first operand should be an MDNode", MIB);
+ MDNode *StackMD = dyn_cast<MDNode>(MIB->getOperand(0));
+ visitCallStackMetadata(StackMD);
+
+ // Check that remaining operands are MDString.
+ Check(std::all_of(MIB->op_begin() + 1, MIB->op_end(),
+ [](const MDOperand &Op) { return isa<MDString>(Op); }),
+ "Not all !memprof MemInfoBlock operands 1 to N are MDString", MIB);
+ }
+}
+
+void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) {
+ Check(isa<CallBase>(I), "!callsite metadata should only exist on calls", &I);
+ // Verify the partial callstack annotated from memprof profiles. This callsite
+ // is a part of a profiled allocation callstack.
+ visitCallStackMetadata(MD);
+}
+
void Verifier::visitAnnotationMetadata(MDNode *Annotation) {
Check(isa<MDTuple>(Annotation), "annotation must be a tuple");
Check(Annotation->getNumOperands() >= 1,
@@ -4735,6 +4785,12 @@ void Verifier::visitInstruction(Instruction &I) {
if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof))
visitProfMetadata(I, MD);
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_memprof))
+ visitMemProfMetadata(I, MD);
+
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_callsite))
+ visitCallsiteMetadata(I, MD);
+
if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation))
visitAnnotationMetadata(Annotation);
@@ -5160,14 +5216,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
// In all other cases relocate should be tied to the statepoint directly.
// This covers relocates on a normal return path of invoke statepoint and
// relocates of a call statepoint.
- auto Token = Call.getArgOperand(0);
- Check(isa<GCStatepointInst>(Token),
+ auto *Token = Call.getArgOperand(0);
+ Check(isa<GCStatepointInst>(Token) || isa<UndefValue>(Token),
"gc relocate is incorrectly tied to the statepoint", Call, Token);
}
// Verify rest of the relocate arguments.
- const CallBase &StatepointCall =
- *cast<GCRelocateInst>(Call).getStatepoint();
+ const Value &StatepointCall = *cast<GCRelocateInst>(Call).getStatepoint();
// Both the base and derived must be piped through the safepoint.
Value *Base = Call.getArgOperand(1);
@@ -5182,7 +5237,10 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
const uint64_t DerivedIndex = cast<ConstantInt>(Derived)->getZExtValue();
// Check the bounds
- if (auto Opt = StatepointCall.getOperandBundle(LLVMContext::OB_gc_live)) {
+ if (isa<UndefValue>(StatepointCall))
+ break;
+ if (auto Opt = cast<GCStatepointInst>(StatepointCall)
+ .getOperandBundle(LLVMContext::OB_gc_live)) {
Check(BaseIndex < Opt->Inputs.size(),
"gc.relocate: statepoint base index out of bounds", Call);
Check(DerivedIndex < Opt->Inputs.size(),