summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/Verifier.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Verifier.cpp349
1 files changed, 233 insertions, 116 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
index 9346c8bda75d..61707cc83504 100644
--- a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
@@ -86,6 +86,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
@@ -96,6 +97,7 @@
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
+#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
@@ -119,6 +121,7 @@ struct VerifierSupport {
raw_ostream *OS;
const Module &M;
ModuleSlotTracker MST;
+ Triple TT;
const DataLayout &DL;
LLVMContext &Context;
@@ -130,7 +133,8 @@ struct VerifierSupport {
bool TreatBrokenDebugInfoAsError = true;
explicit VerifierSupport(raw_ostream *OS, const Module &M)
- : OS(OS), M(M), MST(&M), DL(M.getDataLayout()), Context(M.getContext()) {}
+ : OS(OS), M(M), MST(&M), TT(M.getTargetTriple()), DL(M.getDataLayout()),
+ Context(M.getContext()) {}
private:
void Write(const Module *M) {
@@ -416,6 +420,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 <class Ty> bool isValidMetadataArray(const MDTuple &N);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
@@ -515,6 +520,7 @@ private:
DIExpression::FragmentInfo Fragment,
ValueOrMetadata *Desc);
void verifyFnArgs(const DbgVariableIntrinsic &I);
+ void verifyNotEntryValue(const DbgVariableIntrinsic &I);
/// Module-level debug info verification...
void verifyCompileUnits();
@@ -670,7 +676,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
Assert(InitArray, "wrong initalizer for intrinsic global variable",
Init);
for (Value *Op : InitArray->operands()) {
- Value *V = Op->stripPointerCastsNoFollowAliases();
+ Value *V = Op->stripPointerCasts();
Assert(isa<GlobalVariable>(V) || isa<Function>(V) ||
isa<GlobalAlias>(V),
"invalid llvm.used member", V);
@@ -979,6 +985,9 @@ void Verifier::visitDICompositeType(const DICompositeType &N) {
N.getRawVTableHolder());
AssertDI(!hasConflictingReferenceFlags(N.getFlags()),
"invalid reference flags", &N);
+ unsigned DIBlockByRefStruct = 1 << 4;
+ AssertDI((N.getFlags() & DIBlockByRefStruct) == 0,
+ "DIBlockByRefStruct on DICompositeType is no longer supported", &N);
if (N.isVector()) {
const DINodeArray Elements = N.getElements();
@@ -1306,11 +1315,12 @@ void Verifier::visitDIImportedEntity(const DIImportedEntity &N) {
}
void Verifier::visitComdat(const Comdat &C) {
- // The Module is invalid if the GlobalValue has private linkage. Entities
- // with private linkage don't have entries in the symbol table.
- if (const GlobalValue *GV = M.getNamedValue(C.getName()))
- Assert(!GV->hasPrivateLinkage(), "comdat global value has private linkage",
- GV);
+ // In COFF the Module is invalid if the GlobalValue has private linkage.
+ // Entities with private linkage don't have entries in the symbol table.
+ if (TT.isOSBinFormatCOFF())
+ if (const GlobalValue *GV = M.getNamedValue(C.getName()))
+ Assert(!GV->hasPrivateLinkage(),
+ "comdat global value has private linkage", GV);
}
void Verifier::visitModuleIdents(const Module &M) {
@@ -1498,7 +1508,6 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
case Attribute::NoCfCheck:
case Attribute::NoUnwind:
case Attribute::NoInline:
- case Attribute::NoFree:
case Attribute::AlwaysInline:
case Attribute::OptimizeForSize:
case Attribute::StackProtect:
@@ -1547,7 +1556,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
/// arguments.
static bool isFuncOrArgAttr(Attribute::AttrKind Kind) {
return Kind == Attribute::ReadOnly || Kind == Attribute::WriteOnly ||
- Kind == Attribute::ReadNone;
+ Kind == Attribute::ReadNone || Kind == Attribute::NoFree;
}
void Verifier::verifyAttributeTypes(AttributeSet Attrs, bool IsFunction,
@@ -1694,11 +1703,12 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
!RetAttrs.hasAttribute(Attribute::Nest) &&
!RetAttrs.hasAttribute(Attribute::StructRet) &&
!RetAttrs.hasAttribute(Attribute::NoCapture) &&
+ !RetAttrs.hasAttribute(Attribute::NoFree) &&
!RetAttrs.hasAttribute(Attribute::Returned) &&
!RetAttrs.hasAttribute(Attribute::InAlloca) &&
!RetAttrs.hasAttribute(Attribute::SwiftSelf) &&
!RetAttrs.hasAttribute(Attribute::SwiftError)),
- "Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', "
+ "Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', 'nofree'"
"'returned', 'swiftself', and 'swifterror' do not apply to return "
"values!",
V);
@@ -1834,6 +1844,34 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
if (Args.second && !CheckParam("number of elements", *Args.second))
return;
}
+
+ if (Attrs.hasFnAttribute("frame-pointer")) {
+ StringRef FP = Attrs.getAttribute(AttributeList::FunctionIndex,
+ "frame-pointer").getValueAsString();
+ if (FP != "all" && FP != "non-leaf" && FP != "none")
+ CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
+ }
+
+ if (Attrs.hasFnAttribute("patchable-function-prefix")) {
+ StringRef S = Attrs
+ .getAttribute(AttributeList::FunctionIndex,
+ "patchable-function-prefix")
+ .getValueAsString();
+ unsigned N;
+ if (S.getAsInteger(10, N))
+ CheckFailed(
+ "\"patchable-function-prefix\" takes an unsigned integer: " + S, V);
+ }
+ if (Attrs.hasFnAttribute("patchable-function-entry")) {
+ StringRef S = Attrs
+ .getAttribute(AttributeList::FunctionIndex,
+ "patchable-function-entry")
+ .getValueAsString();
+ unsigned N;
+ if (S.getAsInteger(10, N))
+ CheckFailed(
+ "\"patchable-function-entry\" takes an unsigned integer: " + S, V);
+ }
}
void Verifier::verifyFunctionMetadata(
@@ -2497,6 +2535,15 @@ void Verifier::visitCallBrInst(CallBrInst &CBI) {
Assert(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())
+ Assert(ArgBBs.find(BB) != ArgBBs.end(),
+ "Indirect label missing from arglist.", &CBI);
+ }
visitTerminator(CBI);
}
@@ -2715,8 +2762,8 @@ void Verifier::visitPtrToIntInst(PtrToIntInst &I) {
&I);
if (SrcTy->isVectorTy()) {
- VectorType *VSrc = dyn_cast<VectorType>(SrcTy);
- VectorType *VDest = dyn_cast<VectorType>(DestTy);
+ VectorType *VSrc = cast<VectorType>(SrcTy);
+ VectorType *VDest = cast<VectorType>(DestTy);
Assert(VSrc->getNumElements() == VDest->getNumElements(),
"PtrToInt Vector width mismatch", &I);
}
@@ -2740,8 +2787,8 @@ void Verifier::visitIntToPtrInst(IntToPtrInst &I) {
Assert(SrcTy->isVectorTy() == DestTy->isVectorTy(), "IntToPtr type mismatch",
&I);
if (SrcTy->isVectorTy()) {
- VectorType *VSrc = dyn_cast<VectorType>(SrcTy);
- VectorType *VDest = dyn_cast<VectorType>(DestTy);
+ VectorType *VSrc = cast<VectorType>(SrcTy);
+ VectorType *VDest = cast<VectorType>(DestTy);
Assert(VSrc->getNumElements() == VDest->getNumElements(),
"IntToPtr Vector width mismatch", &I);
}
@@ -2958,10 +3005,10 @@ void Verifier::visitCallBase(CallBase &Call) {
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicCall(ID, Call);
- // Verify that a callsite has at most one "deopt", at most one "funclet" and
- // at most one "gc-transition" operand bundle.
+ // Verify that a callsite has at most one "deopt", at most one "funclet", at
+ // most one "gc-transition", and at most one "cfguardtarget" operand bundle.
bool FoundDeoptBundle = false, FoundFuncletBundle = false,
- FoundGCTransitionBundle = false;
+ FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false;
for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) {
OperandBundleUse BU = Call.getOperandBundleAt(i);
uint32_t Tag = BU.getTagID();
@@ -2980,6 +3027,12 @@ void Verifier::visitCallBase(CallBase &Call) {
Assert(isa<FuncletPadInst>(BU.Inputs.front()),
"Funclet bundle operands should correspond to a FuncletPadInst",
Call);
+ } else if (Tag == LLVMContext::OB_cfguardtarget) {
+ Assert(!FoundCFGuardTargetBundle,
+ "Multiple CFGuardTarget operand bundles", Call);
+ FoundCFGuardTargetBundle = true;
+ Assert(BU.Inputs.size() == 1,
+ "Expected exactly one cfguardtarget bundle operand", Call);
}
}
@@ -3983,9 +4036,9 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) {
Assert(I.getType()->isPointerTy(), "dereferenceable, dereferenceable_or_null "
"apply only to pointer types", &I);
- Assert(isa<LoadInst>(I),
+ Assert((isa<LoadInst>(I) || isa<IntToPtrInst>(I)),
"dereferenceable, dereferenceable_or_null apply only to load"
- " instructions, use attributes for calls or invokes", &I);
+ " and inttoptr instructions, use attributes for calls or invokes", &I);
Assert(MD->getNumOperands() == 1, "dereferenceable, dereferenceable_or_null "
"take one operand!", &I);
ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
@@ -3993,6 +4046,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<MDString>(MD->getOperand(0)),
+ "expected string with name of the !prof annotation", MD);
+ MDString *MDS = cast<MDString>(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<BranchInst>(&I))
+ ExpectedNumOperands = BI->getNumSuccessors();
+ else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I))
+ ExpectedNumOperands = SI->getNumSuccessors();
+ else if (isa<CallInst>(&I) || isa<InvokeInst>(&I))
+ ExpectedNumOperands = 1;
+ else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I))
+ ExpectedNumOperands = IBI->getNumDestinations();
+ else if (isa<SelectInst>(&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<ConstantInt>(MDO),
+ "!prof brunch_weights operand is not a const int");
+ }
+ }
+}
+
/// verifyInstruction - Verify that an instruction is well formed.
///
void Verifier::visitInstruction(Instruction &I) {
@@ -4150,13 +4242,18 @@ 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<DILocation>(N), "invalid !dbg metadata attachment", &I, N);
visitMDNode(*N);
}
- if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I))
+ if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) {
verifyFragmentExpression(*DII);
+ verifyNotEntryValue(*DII);
+ }
InstsInThisBlock.insert(&I);
}
@@ -4230,32 +4327,9 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"an array");
break;
}
- case Intrinsic::experimental_constrained_fadd:
- case Intrinsic::experimental_constrained_fsub:
- case Intrinsic::experimental_constrained_fmul:
- case Intrinsic::experimental_constrained_fdiv:
- case Intrinsic::experimental_constrained_frem:
- case Intrinsic::experimental_constrained_fma:
- case Intrinsic::experimental_constrained_fptrunc:
- case Intrinsic::experimental_constrained_fpext:
- case Intrinsic::experimental_constrained_sqrt:
- case Intrinsic::experimental_constrained_pow:
- case Intrinsic::experimental_constrained_powi:
- case Intrinsic::experimental_constrained_sin:
- case Intrinsic::experimental_constrained_cos:
- case Intrinsic::experimental_constrained_exp:
- case Intrinsic::experimental_constrained_exp2:
- case Intrinsic::experimental_constrained_log:
- case Intrinsic::experimental_constrained_log10:
- case Intrinsic::experimental_constrained_log2:
- case Intrinsic::experimental_constrained_rint:
- case Intrinsic::experimental_constrained_nearbyint:
- case Intrinsic::experimental_constrained_maxnum:
- case Intrinsic::experimental_constrained_minnum:
- case Intrinsic::experimental_constrained_ceil:
- case Intrinsic::experimental_constrained_floor:
- case Intrinsic::experimental_constrained_round:
- case Intrinsic::experimental_constrained_trunc:
+#define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC, DAGN) \
+ case Intrinsic::INTRINSIC:
+#include "llvm/IR/ConstrainedOps.def"
visitConstrainedFPIntrinsic(cast<ConstrainedFPIntrinsic>(Call));
break;
case Intrinsic::dbg_declare: // llvm.dbg.declare
@@ -4623,28 +4697,33 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
}
case Intrinsic::smul_fix:
case Intrinsic::smul_fix_sat:
- case Intrinsic::umul_fix: {
+ case Intrinsic::umul_fix:
+ case Intrinsic::umul_fix_sat:
+ case Intrinsic::sdiv_fix:
+ case Intrinsic::udiv_fix: {
Value *Op1 = Call.getArgOperand(0);
Value *Op2 = Call.getArgOperand(1);
Assert(Op1->getType()->isIntOrIntVectorTy(),
- "first operand of [us]mul_fix[_sat] must be an int type or vector "
- "of ints");
+ "first operand of [us][mul|div]_fix[_sat] must be an int type or "
+ "vector of ints");
Assert(Op2->getType()->isIntOrIntVectorTy(),
- "second operand of [us]mul_fix_[sat] must be an int type or vector "
- "of ints");
+ "second operand of [us][mul|div]_fix[_sat] must be an int type or "
+ "vector of ints");
auto *Op3 = cast<ConstantInt>(Call.getArgOperand(2));
Assert(Op3->getType()->getBitWidth() <= 32,
- "third argument of [us]mul_fix[_sat] must fit within 32 bits");
+ "third argument of [us][mul|div]_fix[_sat] must fit within 32 bits");
- if (ID == Intrinsic::smul_fix || ID == Intrinsic::smul_fix_sat) {
+ if (ID == Intrinsic::smul_fix || ID == Intrinsic::smul_fix_sat ||
+ ID == Intrinsic::sdiv_fix) {
Assert(
Op3->getZExtValue() < Op1->getType()->getScalarSizeInBits(),
- "the scale of smul_fix[_sat] must be less than the width of the operands");
+ "the scale of s[mul|div]_fix[_sat] must be less than the width of "
+ "the operands");
} else {
Assert(Op3->getZExtValue() <= Op1->getType()->getScalarSizeInBits(),
- "the scale of umul_fix[_sat] must be less than or equal to the width of "
- "the operands");
+ "the scale of u[mul|div]_fix[_sat] must be less than or equal "
+ "to the width of the operands");
}
break;
}
@@ -4681,64 +4760,99 @@ static DISubprogram *getSubprogram(Metadata *LocalScope) {
}
void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
- unsigned NumOperands = FPI.getNumArgOperands();
- bool HasExceptionMD = false;
- bool HasRoundingMD = false;
+ unsigned NumOperands;
+ bool HasRoundingMD;
switch (FPI.getIntrinsicID()) {
- case Intrinsic::experimental_constrained_sqrt:
- case Intrinsic::experimental_constrained_sin:
- case Intrinsic::experimental_constrained_cos:
- case Intrinsic::experimental_constrained_exp:
- case Intrinsic::experimental_constrained_exp2:
- case Intrinsic::experimental_constrained_log:
- case Intrinsic::experimental_constrained_log10:
- case Intrinsic::experimental_constrained_log2:
- case Intrinsic::experimental_constrained_rint:
- case Intrinsic::experimental_constrained_nearbyint:
- case Intrinsic::experimental_constrained_ceil:
- case Intrinsic::experimental_constrained_floor:
- case Intrinsic::experimental_constrained_round:
- case Intrinsic::experimental_constrained_trunc:
- Assert((NumOperands == 3), "invalid arguments for constrained FP intrinsic",
- &FPI);
- HasExceptionMD = true;
- HasRoundingMD = true;
+#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
+ case Intrinsic::INTRINSIC: \
+ NumOperands = NARG; \
+ HasRoundingMD = ROUND_MODE; \
break;
+#include "llvm/IR/ConstrainedOps.def"
+ default:
+ llvm_unreachable("Invalid constrained FP intrinsic!");
+ }
+ NumOperands += (1 + HasRoundingMD);
+ // Compare intrinsics carry an extra predicate metadata operand.
+ if (isa<ConstrainedFPCmpIntrinsic>(FPI))
+ NumOperands += 1;
+ Assert((FPI.getNumArgOperands() == NumOperands),
+ "invalid arguments for constrained FP intrinsic", &FPI);
- case Intrinsic::experimental_constrained_fma:
- Assert((NumOperands == 5), "invalid arguments for constrained FP intrinsic",
- &FPI);
- HasExceptionMD = true;
- HasRoundingMD = true;
+ switch (FPI.getIntrinsicID()) {
+ case Intrinsic::experimental_constrained_lrint:
+ case Intrinsic::experimental_constrained_llrint: {
+ Type *ValTy = FPI.getArgOperand(0)->getType();
+ Type *ResultTy = FPI.getType();
+ Assert(!ValTy->isVectorTy() && !ResultTy->isVectorTy(),
+ "Intrinsic does not support vectors", &FPI);
+ }
break;
- case Intrinsic::experimental_constrained_fadd:
- case Intrinsic::experimental_constrained_fsub:
- case Intrinsic::experimental_constrained_fmul:
- case Intrinsic::experimental_constrained_fdiv:
- case Intrinsic::experimental_constrained_frem:
- case Intrinsic::experimental_constrained_pow:
- case Intrinsic::experimental_constrained_powi:
- case Intrinsic::experimental_constrained_maxnum:
- case Intrinsic::experimental_constrained_minnum:
- Assert((NumOperands == 4), "invalid arguments for constrained FP intrinsic",
- &FPI);
- HasExceptionMD = true;
- HasRoundingMD = true;
+ case Intrinsic::experimental_constrained_lround:
+ case Intrinsic::experimental_constrained_llround: {
+ Type *ValTy = FPI.getArgOperand(0)->getType();
+ Type *ResultTy = FPI.getType();
+ Assert(!ValTy->isVectorTy() && !ResultTy->isVectorTy(),
+ "Intrinsic does not support vectors", &FPI);
break;
+ }
- case Intrinsic::experimental_constrained_fptrunc:
- case Intrinsic::experimental_constrained_fpext: {
- if (FPI.getIntrinsicID() == Intrinsic::experimental_constrained_fptrunc) {
- Assert((NumOperands == 3),
- "invalid arguments for constrained FP intrinsic", &FPI);
- HasRoundingMD = true;
- } else {
- Assert((NumOperands == 2),
- "invalid arguments for constrained FP intrinsic", &FPI);
+ case Intrinsic::experimental_constrained_fcmp:
+ case Intrinsic::experimental_constrained_fcmps: {
+ auto Pred = cast<ConstrainedFPCmpIntrinsic>(&FPI)->getPredicate();
+ Assert(CmpInst::isFPPredicate(Pred),
+ "invalid predicate for constrained FP comparison intrinsic", &FPI);
+ break;
+ }
+
+ case Intrinsic::experimental_constrained_fptosi:
+ case Intrinsic::experimental_constrained_fptoui: {
+ Value *Operand = FPI.getArgOperand(0);
+ uint64_t NumSrcElem = 0;
+ Assert(Operand->getType()->isFPOrFPVectorTy(),
+ "Intrinsic first argument must be floating point", &FPI);
+ if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
+ NumSrcElem = OperandT->getNumElements();
+ }
+
+ Operand = &FPI;
+ Assert((NumSrcElem > 0) == Operand->getType()->isVectorTy(),
+ "Intrinsic first argument and result disagree on vector use", &FPI);
+ Assert(Operand->getType()->isIntOrIntVectorTy(),
+ "Intrinsic result must be an integer", &FPI);
+ if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
+ Assert(NumSrcElem == OperandT->getNumElements(),
+ "Intrinsic first argument and result vector lengths must be equal",
+ &FPI);
}
- HasExceptionMD = true;
+ }
+ break;
+ case Intrinsic::experimental_constrained_sitofp:
+ case Intrinsic::experimental_constrained_uitofp: {
+ Value *Operand = FPI.getArgOperand(0);
+ uint64_t NumSrcElem = 0;
+ Assert(Operand->getType()->isIntOrIntVectorTy(),
+ "Intrinsic first argument must be integer", &FPI);
+ if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
+ NumSrcElem = OperandT->getNumElements();
+ }
+
+ Operand = &FPI;
+ Assert((NumSrcElem > 0) == Operand->getType()->isVectorTy(),
+ "Intrinsic first argument and result disagree on vector use", &FPI);
+ Assert(Operand->getType()->isFPOrFPVectorTy(),
+ "Intrinsic result must be a floating point", &FPI);
+ if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
+ Assert(NumSrcElem == OperandT->getNumElements(),
+ "Intrinsic first argument and result vector lengths must be equal",
+ &FPI);
+ }
+ } break;
+
+ case Intrinsic::experimental_constrained_fptrunc:
+ case Intrinsic::experimental_constrained_fpext: {
Value *Operand = FPI.getArgOperand(0);
Type *OperandTy = Operand->getType();
Value *Result = &FPI;
@@ -4769,7 +4883,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
break;
default:
- llvm_unreachable("Invalid constrained FP intrinsic!");
+ break;
}
// If a non-metadata argument is passed in a metadata slot then the
@@ -4777,10 +4891,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
// match the specification in the intrinsic call table. Thus, no
// argument type check is needed here.
- if (HasExceptionMD) {
- Assert(FPI.getExceptionBehavior().hasValue(),
- "invalid exception behavior argument", &FPI);
- }
+ Assert(FPI.getExceptionBehavior().hasValue(),
+ "invalid exception behavior argument", &FPI);
if (HasRoundingMD) {
Assert(FPI.getRoundingMode().hasValue(),
"invalid rounding mode argument", &FPI);
@@ -4826,11 +4938,6 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) {
// This check is redundant with one in visitLocalVariable().
AssertDI(isType(Var->getRawType()), "invalid type ref", Var,
Var->getRawType());
- if (auto *Type = dyn_cast_or_null<DIType>(Var->getRawType()))
- if (Type->isBlockByrefStruct())
- AssertDI(DII.getExpression() && DII.getExpression()->getNumElements(),
- "BlockByRef variable without complex expression", Var, &DII);
-
verifyFnArgs(DII);
}
@@ -4935,6 +5042,16 @@ void Verifier::verifyFnArgs(const DbgVariableIntrinsic &I) {
Prev, Var);
}
+void Verifier::verifyNotEntryValue(const DbgVariableIntrinsic &I) {
+ DIExpression *E = dyn_cast_or_null<DIExpression>(I.getRawExpression());
+
+ // We don't know whether this intrinsic verified correctly.
+ if (!E || !E->isValid())
+ return;
+
+ AssertDI(!E->isEntryValue(), "Entry values are only allowed in MIR", &I);
+}
+
void Verifier::verifyCompileUnits() {
// When more than one Module is imported into the same context, such as during
// an LTO build before linking the modules, ODR type uniquing may cause types
@@ -5021,7 +5138,7 @@ struct VerifierLegacyPass : public FunctionPass {
}
bool doInitialization(Module &M) override {
- V = llvm::make_unique<Verifier>(
+ V = std::make_unique<Verifier>(
&dbgs(), /*ShouldTreatBrokenDebugInfoAsError=*/false, M);
return false;
}