summaryrefslogtreecommitdiffstats
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.cpp117
1 files changed, 50 insertions, 67 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 55d3a323610..44095bf05e1 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -500,7 +500,7 @@ private:
const Value *V);
void verifyParameterAttrs(AttributeSet Attrs, Type *Ty, const Value *V);
void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
- const Value *V);
+ const Value *V, bool IsIntrinsic);
void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
void visitConstantExprsRecursively(const Constant *EntryC);
@@ -1562,6 +1562,11 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
verifyAttributeTypes(Attrs, /*IsFunction=*/false, V);
+ if (Attrs.hasAttribute(Attribute::ImmArg)) {
+ Assert(Attrs.getNumAttributes() == 1,
+ "Attribute 'immarg' is incompatible with other attributes", V);
+ }
+
// Check for mutually incompatible attributes. Only inreg is compatible with
// sret.
unsigned AttrCount = 0;
@@ -1649,7 +1654,7 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
// Check parameter attributes against a function type.
// The value V is printed in error messages.
void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
- const Value *V) {
+ const Value *V, bool IsIntrinsic) {
if (Attrs.isEmpty())
return;
@@ -1686,6 +1691,11 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
Type *Ty = FT->getParamType(i);
AttributeSet ArgAttrs = Attrs.getParamAttributes(i);
+ if (!IsIntrinsic) {
+ Assert(!ArgAttrs.hasAttribute(Attribute::ImmArg),
+ "immarg attribute only applies to intrinsics",V);
+ }
+
verifyParameterAttrs(ArgAttrs, Ty, V);
if (ArgAttrs.hasAttribute(Attribute::Nest)) {
@@ -1904,16 +1914,8 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
"reordering restrictions required by safepoint semantics",
Call);
- const Value *IDV = Call.getArgOperand(0);
- Assert(isa<ConstantInt>(IDV), "gc.statepoint ID must be a constant integer",
- Call);
-
- const Value *NumPatchBytesV = Call.getArgOperand(1);
- Assert(isa<ConstantInt>(NumPatchBytesV),
- "gc.statepoint number of patchable bytes must be a constant integer",
- Call);
const int64_t NumPatchBytes =
- cast<ConstantInt>(NumPatchBytesV)->getSExtValue();
+ cast<ConstantInt>(Call.getArgOperand(1))->getSExtValue();
assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!");
Assert(NumPatchBytes >= 0,
"gc.statepoint number of patchable bytes must be "
@@ -1926,12 +1928,7 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
"gc.statepoint callee must be of function pointer type", Call, Target);
FunctionType *TargetFuncType = cast<FunctionType>(PT->getElementType());
- const Value *NumCallArgsV = Call.getArgOperand(3);
- Assert(isa<ConstantInt>(NumCallArgsV),
- "gc.statepoint number of arguments to underlying call "
- "must be constant integer",
- Call);
- const int NumCallArgs = cast<ConstantInt>(NumCallArgsV)->getZExtValue();
+ const int NumCallArgs = cast<ConstantInt>(Call.getArgOperand(3))->getZExtValue();
Assert(NumCallArgs >= 0,
"gc.statepoint number of arguments to underlying call "
"must be positive",
@@ -1950,10 +1947,8 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
Assert(NumCallArgs == NumParams,
"gc.statepoint mismatch in number of call args", Call);
- const Value *FlagsV = Call.getArgOperand(4);
- Assert(isa<ConstantInt>(FlagsV),
- "gc.statepoint flags must be constant integer", Call);
- const uint64_t Flags = cast<ConstantInt>(FlagsV)->getZExtValue();
+ const uint64_t Flags
+ = cast<ConstantInt>(Call.getArgOperand(4))->getZExtValue();
Assert((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0,
"unknown flag used in gc.statepoint flags argument", Call);
@@ -2130,8 +2125,11 @@ void Verifier::visitFunction(const Function &F) {
Assert(verifyAttributeCount(Attrs, FT->getNumParams()),
"Attribute after last parameter!", &F);
+ bool isLLVMdotName = F.getName().size() >= 5 &&
+ F.getName().substr(0, 5) == "llvm.";
+
// Check function attributes.
- verifyFunctionAttrs(FT, Attrs, &F);
+ verifyFunctionAttrs(FT, Attrs, &F, isLLVMdotName);
// On function declarations/definitions, we do not support the builtin
// attribute. We do not check this in VerifyFunctionAttrs since that is
@@ -2170,9 +2168,6 @@ void Verifier::visitFunction(const Function &F) {
break;
}
- bool isLLVMdotName = F.getName().size() >= 5 &&
- F.getName().substr(0, 5) == "llvm.";
-
// Check that the argument values match the function type for this function...
unsigned i = 0;
for (const Argument &Arg : F.args()) {
@@ -2800,17 +2795,21 @@ void Verifier::visitCallBase(CallBase &Call) {
Assert(verifyAttributeCount(Attrs, Call.arg_size()),
"Attribute after last parameter!", Call);
+ bool IsIntrinsic = Call.getCalledFunction() &&
+ Call.getCalledFunction()->getName().startswith("llvm.");
+
+ Function *Callee
+ = dyn_cast<Function>(Call.getCalledValue()->stripPointerCasts());
+
if (Attrs.hasAttribute(AttributeList::FunctionIndex, Attribute::Speculatable)) {
// Don't allow speculatable on call sites, unless the underlying function
// declaration is also speculatable.
- Function *Callee =
- dyn_cast<Function>(Call.getCalledValue()->stripPointerCasts());
Assert(Callee && Callee->isSpeculatable(),
"speculatable attribute may not apply to call sites", Call);
}
// Verify call attributes.
- verifyFunctionAttrs(FTy, Attrs, &Call);
+ verifyFunctionAttrs(FTy, Attrs, &Call, IsIntrinsic);
// Conservatively check the inalloca argument.
// We have a bug if we can find that there is an underlying alloca without
@@ -2825,7 +2824,7 @@ void Verifier::visitCallBase(CallBase &Call) {
// For each argument of the callsite, if it has the swifterror argument,
// make sure the underlying alloca/parameter it comes from has a swifterror as
// well.
- for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
if (Call.paramHasAttr(i, Attribute::SwiftError)) {
Value *SwiftErrorArg = Call.getArgOperand(i);
if (auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets())) {
@@ -2842,6 +2841,21 @@ void Verifier::visitCallBase(CallBase &Call) {
Call);
}
+ if (Attrs.hasParamAttribute(i, Attribute::ImmArg)) {
+ // Don't allow immarg on call sites, unless the underlying declaration
+ // also has the matching immarg.
+ Assert(Callee && Callee->hasParamAttribute(i, Attribute::ImmArg),
+ "immarg may not apply only to call sites",
+ Call.getArgOperand(i), Call);
+ }
+
+ if (Call.paramHasAttr(i, Attribute::ImmArg)) {
+ Value *ArgVal = Call.getArgOperand(i);
+ Assert(isa<ConstantInt>(ArgVal) || isa<ConstantFP>(ArgVal),
+ "immarg operand has non-immediate parameter", ArgVal, Call);
+ }
+ }
+
if (FTy->isVarArg()) {
// FIXME? is 'nest' even legal here?
bool SawNest = false;
@@ -2891,8 +2905,7 @@ void Verifier::visitCallBase(CallBase &Call) {
}
// Verify that there's no metadata unless it's a direct call to an intrinsic.
- if (!Call.getCalledFunction() ||
- !Call.getCalledFunction()->getName().startswith("llvm.")) {
+ if (!IsIntrinsic) {
for (Type *ParamTy : FTy->params()) {
Assert(!ParamTy->isMetadataTy(),
"Function has metadata parameter but isn't an intrinsic", Call);
@@ -4181,13 +4194,6 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"an array");
break;
}
- case Intrinsic::ctlz: // llvm.ctlz
- case Intrinsic::cttz: // llvm.cttz
- Assert(isa<ConstantInt>(Call.getArgOperand(1)),
- "is_zero_undef argument of bit counting intrinsics must be a "
- "constant int",
- Call);
- break;
case Intrinsic::experimental_constrained_fadd:
case Intrinsic::experimental_constrained_fsub:
case Intrinsic::experimental_constrained_fmul:
@@ -4243,9 +4249,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"alignment of arg 1 of memory intrinsic must be 0 or a power of 2",
Call);
}
- Assert(isa<ConstantInt>(Call.getArgOperand(3)),
- "isvolatile argument of memory intrinsics must be a constant int",
- Call);
+
break;
}
case Intrinsic::memcpy_element_unordered_atomic:
@@ -4254,11 +4258,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
const auto *AMI = cast<AtomicMemIntrinsic>(&Call);
ConstantInt *ElementSizeCI =
- dyn_cast<ConstantInt>(AMI->getRawElementSizeInBytes());
- Assert(ElementSizeCI,
- "element size of the element-wise unordered atomic memory "
- "intrinsic must be a constant int",
- Call);
+ cast<ConstantInt>(AMI->getRawElementSizeInBytes());
const APInt &ElementSizeVal = ElementSizeCI->getValue();
Assert(ElementSizeVal.isPowerOf2(),
"element size of the element-wise atomic memory intrinsic "
@@ -4313,28 +4313,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
Call);
break;
case Intrinsic::prefetch:
- Assert(isa<ConstantInt>(Call.getArgOperand(1)) &&
- isa<ConstantInt>(Call.getArgOperand(2)) &&
- cast<ConstantInt>(Call.getArgOperand(1))->getZExtValue() < 2 &&
- cast<ConstantInt>(Call.getArgOperand(2))->getZExtValue() < 4,
+ Assert(cast<ConstantInt>(Call.getArgOperand(1))->getZExtValue() < 2 &&
+ cast<ConstantInt>(Call.getArgOperand(2))->getZExtValue() < 4,
"invalid arguments to llvm.prefetch", Call);
break;
case Intrinsic::stackprotector:
Assert(isa<AllocaInst>(Call.getArgOperand(1)->stripPointerCasts()),
"llvm.stackprotector parameter #2 must resolve to an alloca.", Call);
break;
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::invariant_start:
- Assert(isa<ConstantInt>(Call.getArgOperand(0)),
- "size argument of memory use markers must be a constant integer",
- Call);
- break;
- case Intrinsic::invariant_end:
- Assert(isa<ConstantInt>(Call.getArgOperand(1)),
- "llvm.invariant.end parameter #2 must be a constant integer", Call);
- break;
-
case Intrinsic::localescape: {
BasicBlock *BB = Call.getParent();
Assert(BB == &BB->getParent()->front(),
@@ -4359,9 +4345,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"llvm.localrecover first "
"argument must be function defined in this module",
Call);
- auto *IdxArg = dyn_cast<ConstantInt>(Call.getArgOperand(2));
- Assert(IdxArg, "idx argument of llvm.localrecover must be a constant int",
- Call);
+ auto *IdxArg = cast<ConstantInt>(Call.getArgOperand(2));
auto &Entry = FrameEscapeInfo[Fn];
Entry.second = unsigned(
std::max(uint64_t(Entry.second), IdxArg->getLimitedValue(~0U) + 1));
@@ -4606,8 +4590,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"second operand of [us]mul_fix must be an int type or vector "
"of ints");
- auto *Op3 = dyn_cast<ConstantInt>(Call.getArgOperand(2));
- Assert(Op3, "third argument of [us]mul_fix must be a constant integer");
+ auto *Op3 = cast<ConstantInt>(Call.getArgOperand(2));
Assert(Op3->getType()->getBitWidth() <= 32,
"third argument of [us]mul_fix must fit within 32 bits");
OpenPOWER on IntegriCloud