X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FIR%2FVerifier.cpp;h=19b11b45ac3233a7a0227bf5d357c8369819e4d6;hb=cf0db29df20d9c665da7e82bb261bdd7cf7f1b2b;hp=374f8f210be21a0c410bf88da12d10bc470beb44;hpb=4406c32c19214dede074e54d6f6ecf94f7284bfb;p=oota-llvm.git diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 374f8f210be..19b11b45ac3 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -181,11 +181,6 @@ class Verifier : public InstVisitor, VerifierSupport { /// \brief Track unresolved string-based type references. SmallDenseMap UnresolvedTypeRefs; - /// \brief The personality function referenced by the LandingPadInsts. - /// All LandingPadInsts within the same function must use the same - /// personality function. - const Value *PersonalityFn; - /// \brief Whether we've seen a call to @llvm.frameescape in this function /// already. bool SawFrameEscape; @@ -196,8 +191,7 @@ class Verifier : public InstVisitor, VerifierSupport { public: explicit Verifier(raw_ostream &OS) - : VerifierSupport(OS), Context(nullptr), PersonalityFn(nullptr), - SawFrameEscape(false) {} + : VerifierSupport(OS), Context(nullptr), SawFrameEscape(false) {} bool verify(const Function &F) { M = F.getParent(); @@ -231,7 +225,6 @@ public: // FIXME: We strip const here because the inst visitor strips const. visit(const_cast(F)); InstsInThisBlock.clear(); - PersonalityFn = nullptr; SawFrameEscape = false; return !Broken; @@ -400,6 +393,8 @@ private: bool isReturnValue, const Value *V); void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, const Value *V); + void VerifyFunctionMetadata( + const SmallVector, 4> MDs); void VerifyConstantExprBitcastType(const ConstantExpr *CE); void VerifyStatepoint(ImmutableCallSite CS); @@ -492,7 +487,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { GV.getName() == "llvm.compiler.used")) { Assert(!GV.hasInitializer() || GV.hasAppendingLinkage(), "invalid linkage for intrinsic global variable", &GV); - Type *GVType = GV.getType()->getElementType(); + Type *GVType = GV.getValueType(); if (ArrayType *ATy = dyn_cast(GVType)) { PointerType *PTy = dyn_cast(ATy->getElementType()); Assert(PTy, "wrong type for intrinsic global variable", &GV); @@ -582,7 +577,6 @@ void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl &Visited, } void Verifier::visitGlobalAlias(const GlobalAlias &GA) { - Assert(!GA.getName().empty(), "Alias name cannot be empty!", &GA); Assert(GlobalAlias::isValidLinkage(GA.getLinkage()), "Alias should have private, internal, linkonce, weak, linkonce_odr, " "weak_odr, or external linkage!", @@ -1084,7 +1078,7 @@ void Verifier::visitDIExpression(const DIExpression &N) { void Verifier::visitDIObjCProperty(const DIObjCProperty &N) { Assert(N.getTag() == dwarf::DW_TAG_APPLE_property, "invalid tag", &N); if (auto *T = N.getRawType()) - Assert(isa(T), "invalid type ref", &N, T); + Assert(isTypeRef(N, T), "invalid type ref", &N, T); if (auto *F = N.getRawFile()) Assert(isa(F), "invalid file", &N, F); } @@ -1249,6 +1243,7 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::StackProtect || I->getKindAsEnum() == Attribute::StackProtectReq || I->getKindAsEnum() == Attribute::StackProtectStrong || + I->getKindAsEnum() == Attribute::SafeStack || I->getKindAsEnum() == Attribute::NoRedZone || I->getKindAsEnum() == Attribute::NoImplicitFloat || I->getKindAsEnum() == Attribute::Naked || @@ -1266,7 +1261,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::NoBuiltin || I->getKindAsEnum() == Attribute::Cold || I->getKindAsEnum() == Attribute::OptimizeNone || - I->getKindAsEnum() == Attribute::JumpTable) { + I->getKindAsEnum() == Attribute::JumpTable || + I->getKindAsEnum() == Attribute::Convergent) { if (!isFunction) { CheckFailed("Attribute '" + I->getAsString() + "' only applies to functions!", V); @@ -1463,6 +1459,36 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, } } +void Verifier::VerifyFunctionMetadata( + const SmallVector, 4> MDs) { + if (MDs.empty()) + return; + + for (unsigned i = 0; i < MDs.size(); i++) { + if (MDs[i].first == LLVMContext::MD_prof) { + MDNode *MD = MDs[i].second; + Assert(MD->getNumOperands() == 2, + "!prof annotations should have exactly 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(); + Assert(ProfName.equals("function_entry_count"), + "first operand should be 'function_entry_count'", MD); + + // Check second operand. + Assert(MD->getOperand(1) != nullptr, "second operand should not be null", + MD); + Assert(isa(MD->getOperand(1)), + "expected integer argument to function_entry_count", MD); + } + } +} + void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) { if (CE->getOpcode() != Instruction::BitCast) return; @@ -1499,13 +1525,34 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { "reordering restrictions required by safepoint semantics", &CI); - const Value *Target = CS.getArgument(0); + const Value *IDV = CS.getArgument(0); + Assert(isa(IDV), "gc.statepoint ID must be a constant integer", + &CI); + + const Value *NumPatchBytesV = CS.getArgument(1); + Assert(isa(NumPatchBytesV), + "gc.statepoint number of patchable bytes must be a constant integer", + &CI); + const int64_t NumPatchBytes = + cast(NumPatchBytesV)->getSExtValue(); + assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!"); + Assert(NumPatchBytes >= 0, "gc.statepoint number of patchable bytes must be " + "positive", + &CI); + + const Value *Target = CS.getArgument(2); const PointerType *PT = dyn_cast(Target->getType()); Assert(PT && PT->getElementType()->isFunctionTy(), "gc.statepoint callee must be of function pointer type", &CI, Target); FunctionType *TargetFuncType = cast(PT->getElementType()); - const Value *NumCallArgsV = CS.getArgument(1); + if (NumPatchBytes) + Assert(isa(Target->stripPointerCasts()), + "gc.statepoint must have null as call target if number of patchable " + "bytes is non zero", + &CI); + + const Value *NumCallArgsV = CS.getArgument(3); Assert(isa(NumCallArgsV), "gc.statepoint number of arguments to underlying call " "must be constant integer", @@ -1529,7 +1576,7 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { Assert(NumCallArgs == NumParams, "gc.statepoint mismatch in number of call args", &CI); - const Value *FlagsV = CS.getArgument(2); + const Value *FlagsV = CS.getArgument(4); Assert(isa(FlagsV), "gc.statepoint flags must be constant integer", &CI); const uint64_t Flags = cast(FlagsV)->getZExtValue(); @@ -1540,13 +1587,14 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { // the type of the wrapped callee. for (int i = 0; i < NumParams; i++) { Type *ParamType = TargetFuncType->getParamType(i); - Type *ArgType = CS.getArgument(3+i)->getType(); + Type *ArgType = CS.getArgument(5 + i)->getType(); Assert(ArgType == ParamType, "gc.statepoint call argument does not match wrapped " "function type", &CI); } - const int EndCallArgsInx = 2+NumCallArgs; + + const int EndCallArgsInx = 4 + NumCallArgs; const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1); Assert(isa(NumTransitionArgsV), @@ -1570,7 +1618,7 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { &CI); const int ExpectedNumArgs = - 5 + NumCallArgs + NumTransitionArgs + NumDeoptArgs; + 7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs; Assert(ExpectedNumArgs <= (int)CS.arg_size(), "gc.statepoint too few arguments according to length fields", &CI); @@ -1691,6 +1739,7 @@ void Verifier::visitFunction(const Function &F) { SmallVector, 4> MDs; F.getAllMetadata(MDs); assert(F.hasMetadata() != MDs.empty() && "Bit out-of-sync"); + VerifyFunctionMetadata(MDs); if (F.isMaterializable()) { // Function has a body somewhere we can't see. @@ -1701,6 +1750,8 @@ void Verifier::visitFunction(const Function &F) { "invalid linkage type for function declaration", &F); Assert(MDs.empty(), "function without a body cannot have metadata", &F, MDs.empty() ? nullptr : MDs.front().second); + Assert(!F.hasPersonalityFn(), + "Function declaration shouldn't have a personality routine", &F); } else { // Verify that this function (which has a body) is not named "llvm.*". It // is not legal to define intrinsics. @@ -2132,8 +2183,8 @@ void Verifier::visitPHINode(PHINode &PN) { // Check that all of the values of the PHI node have the same type as the // result, and that the incoming blocks are really basic blocks. - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { - Assert(PN.getType() == PN.getIncomingValue(i)->getType(), + for (Value *IncValue : PN.incoming_values()) { + Assert(PN.getType() == IncValue->getType(), "PHI node operands are not the same type as the result!", &PN); } @@ -2335,7 +2386,7 @@ void Verifier::visitCallInst(CallInst &CI) { verifyMustTailCall(CI); if (Function *F = CI.getCalledFunction()) - if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) + if (Intrinsic::ID ID = F->getIntrinsicID()) visitIntrinsicFunctionCall(ID, CI); } @@ -2739,22 +2790,16 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { &LPI); } + Function *F = LPI.getParent()->getParent(); + Assert(F->hasPersonalityFn(), + "LandingPadInst needs to be in a function with a personality.", &LPI); + // The landingpad instruction must be the first non-PHI instruction in the // block. Assert(LPI.getParent()->getLandingPadInst() == &LPI, "LandingPadInst not the first non-PHI instruction in the block.", &LPI); - // The personality functions for all landingpad instructions within the same - // function should match. - if (PersonalityFn) - Assert(LPI.getPersonalityFn() == PersonalityFn, - "Personality function doesn't match others in function", &LPI); - PersonalityFn = LPI.getPersonalityFn(); - - // All operands must be constants. - Assert(isa(PersonalityFn), "Personality function is not constant!", - &LPI); for (unsigned i = 0, e = LPI.getNumClauses(); i < e; ++i) { Constant *Clause = LPI.getClause(i); if (LPI.isCatch(i)) { @@ -3065,8 +3110,8 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, dyn_cast(ThisArgVecTy->getVectorElementType()); if (!ThisArgEltTy) return true; - return (!(ThisArgEltTy->getElementType() == - ReferenceType->getVectorElementType())); + return ThisArgEltTy->getElementType() != + ReferenceType->getVectorElementType(); } } llvm_unreachable("unhandled"); @@ -3192,7 +3237,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert(AI, "llvm.gcroot parameter #1 must be an alloca.", &CI); Assert(isa(CI.getArgOperand(1)), "llvm.gcroot parameter #2 must be a constant.", &CI); - if (!AI->getType()->getElementType()->isPointerTy()) { + if (!AI->getAllocatedType()->isPointerTy()) { Assert(!isa(CI.getArgOperand(1)), "llvm.gcroot parameter #1 must either be a pointer alloca, " "or argument #2 must be a non-null constant.", @@ -3289,7 +3334,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { CI.getArgOperand(0)); // Assert that result type matches wrapped callee. - const Value *Target = StatepointCS.getArgument(0); + const Value *Target = StatepointCS.getArgument(2); const PointerType *PT = cast(Target->getType()); const FunctionType *TargetFuncType = cast(PT->getElementType()); @@ -3309,17 +3354,17 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "gc relocate on unwind path incorrectly linked to the statepoint", &CI); - const BasicBlock *invokeBB = + const BasicBlock *InvokeBB = ExtractValue->getParent()->getUniquePredecessor(); // Landingpad relocates should have only one predecessor with invoke // statepoint terminator - Assert(invokeBB, "safepoints should have unique landingpads", + Assert(InvokeBB, "safepoints should have unique landingpads", ExtractValue->getParent()); - Assert(invokeBB->getTerminator(), "safepoint block should be well formed", - invokeBB); - Assert(isStatepoint(invokeBB->getTerminator()), - "gc relocate should be linked to a statepoint", invokeBB); + Assert(InvokeBB->getTerminator(), "safepoint block should be well formed", + InvokeBB); + Assert(isStatepoint(InvokeBB->getTerminator()), + "gc relocate should be linked to a statepoint", InvokeBB); } else { // In all other cases relocate should be tied to the statepoint directly. @@ -3332,8 +3377,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // Verify rest of the relocate arguments - GCRelocateOperands ops(&CI); - ImmutableCallSite StatepointCS(ops.getStatepoint()); + GCRelocateOperands Ops(&CI); + ImmutableCallSite StatepointCS(Ops.getStatepoint()); // Both the base and derived must be piped through the safepoint Value* Base = CI.getArgOperand(1); @@ -3356,18 +3401,19 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // section of the statepoint's argument Assert(StatepointCS.arg_size() > 0, "gc.statepoint: insufficient arguments"); - Assert(isa(StatepointCS.getArgument(1)), + Assert(isa(StatepointCS.getArgument(3)), "gc.statement: number of call arguments must be constant integer"); const unsigned NumCallArgs = - cast(StatepointCS.getArgument(1))->getZExtValue(); - Assert(StatepointCS.arg_size() > NumCallArgs+3, + cast(StatepointCS.getArgument(3))->getZExtValue(); + Assert(StatepointCS.arg_size() > NumCallArgs + 5, "gc.statepoint: mismatch in number of call arguments"); - Assert(isa(StatepointCS.getArgument(NumCallArgs+3)), + Assert(isa(StatepointCS.getArgument(NumCallArgs + 5)), "gc.statepoint: number of transition arguments must be " "a constant integer"); const int NumTransitionArgs = - cast(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue(); - const int DeoptArgsStart = 2 + NumCallArgs + 1 + NumTransitionArgs + 1; + cast(StatepointCS.getArgument(NumCallArgs + 5)) + ->getZExtValue(); + const int DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1; Assert(isa(StatepointCS.getArgument(DeoptArgsStart)), "gc.statepoint: number of deoptimization arguments must be " "a constant integer"); @@ -3384,10 +3430,18 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "'gc parameters' section of the statepoint call", &CI); - // Assert that the result type matches the type of the relocated pointer + // Relocated value must be a pointer type, but gc_relocate does not need to return the + // same pointer type as the relocated pointer. It can be casted to the correct type later + // if it's desired. However, they must have the same address space. GCRelocateOperands Operands(&CI); - Assert(Operands.getDerivedPtr()->getType() == CI.getType(), - "gc.relocate: relocating a pointer shouldn't change its type", &CI); + Assert(Operands.getDerivedPtr()->getType()->isPointerTy(), + "gc.relocate: relocated value must be a gc pointer", &CI); + + // gc_relocate return type must be a pointer type, and is verified earlier in + // VerifyIntrinsicType(). + Assert(cast(CI.getType())->getAddressSpace() == + cast(Operands.getDerivedPtr()->getType())->getAddressSpace(), + "gc.relocate: relocating a pointer shouldn't change its address space", &CI); break; } }; @@ -3637,7 +3691,7 @@ struct VerifierLegacyPass : public FunctionPass { AU.setPreservesAll(); } }; -} +} // namespace char VerifierLegacyPass::ID = 0; INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false)