diff options
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 117 |
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"); |