diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/lib/IR/Verifier.cpp | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/IR/Verifier.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/IR/Verifier.cpp | 602 |
1 files changed, 301 insertions, 301 deletions
diff --git a/contrib/libs/llvm12/lib/IR/Verifier.cpp b/contrib/libs/llvm12/lib/IR/Verifier.cpp index 6dd299ee98..71152f7176 100644 --- a/contrib/libs/llvm12/lib/IR/Verifier.cpp +++ b/contrib/libs/llvm12/lib/IR/Verifier.cpp @@ -115,11 +115,11 @@ using namespace llvm; -static cl::opt<bool> VerifyNoAliasScopeDomination( - "verify-noalias-scope-decl-dom", cl::Hidden, cl::init(false), - cl::desc("Ensure that llvm.experimental.noalias.scope.decl for identical " - "scopes are not dominating")); - +static cl::opt<bool> VerifyNoAliasScopeDomination( + "verify-noalias-scope-decl-dom", cl::Hidden, cl::init(false), + cl::desc("Ensure that llvm.experimental.noalias.scope.decl for identical " + "scopes are not dominating")); + namespace llvm { struct VerifierSupport { @@ -287,9 +287,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { /// Whether the current function has a DISubprogram attached to it. bool HasDebugInfo = false; - /// The current source language. - dwarf::SourceLanguage CurrentSourceLang = dwarf::DW_LANG_lo_user; - + /// The current source language. + dwarf::SourceLanguage CurrentSourceLang = dwarf::DW_LANG_lo_user; + /// Whether source was present on the first DIFile encountered in each CU. DenseMap<const DICompileUnit *, bool> HasSourceDebugInfo; @@ -318,8 +318,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { TBAAVerifier TBAAVerifyHelper; - SmallVector<IntrinsicInst *, 4> NoAliasScopeDecls; - + SmallVector<IntrinsicInst *, 4> NoAliasScopeDecls; + void checkAtomicMemAccessSize(Type *Ty, const Instruction *I); public: @@ -367,8 +367,8 @@ public: LandingPadResultTy = nullptr; SawFrameEscape = false; SiblingFuncletInfo.clear(); - verifyNoAliasScopeDecl(); - NoAliasScopeDecls.clear(); + verifyNoAliasScopeDecl(); + NoAliasScopeDecls.clear(); return !Broken; } @@ -436,7 +436,7 @@ private: void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); void visitProfMetadata(Instruction &I, MDNode *MD); - void visitAnnotationMetadata(MDNode *Annotation); + void visitAnnotationMetadata(MDNode *Annotation); template <class Ty> bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); @@ -545,9 +545,9 @@ private: /// Verify all-or-nothing property of DIFile source attribute within a CU. void verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F); - - /// Verify the llvm.experimental.noalias.scope.decl declarations - void verifyNoAliasScopeDecl(); + + /// Verify the llvm.experimental.noalias.scope.decl declarations + void verifyNoAliasScopeDecl(); }; } // end anonymous namespace @@ -603,8 +603,8 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { Assert(!GV.isDSOLocal(), "GlobalValue with DLLImport Storage is dso_local!", &GV); - Assert((GV.isDeclaration() && - (GV.hasExternalLinkage() || GV.hasExternalWeakLinkage())) || + Assert((GV.isDeclaration() && + (GV.hasExternalLinkage() || GV.hasExternalWeakLinkage())) || GV.hasAvailableExternallyLinkage(), "Global is marked as dllimport, but not external", &GV); } @@ -714,16 +714,16 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { } // Scalable vectors cannot be global variables, since we don't know - // the runtime size. If the global is an array containing scalable vectors, - // that will be caught by the isValidElementType methods in StructType or - // ArrayType instead. + // the runtime size. If the global is an array containing scalable vectors, + // that will be caught by the isValidElementType methods in StructType or + // ArrayType instead. Assert(!isa<ScalableVectorType>(GV.getValueType()), "Globals cannot contain scalable vectors", &GV); - if (auto *STy = dyn_cast<StructType>(GV.getValueType())) - Assert(!STy->containsScalableVectorType(), - "Globals cannot contain scalable vectors", &GV); - + if (auto *STy = dyn_cast<StructType>(GV.getValueType())) + Assert(!STy->containsScalableVectorType(), + "Globals cannot contain scalable vectors", &GV); + if (!GV.hasInitializer()) { visitGlobalValue(GV); return; @@ -913,9 +913,9 @@ void Verifier::visitDIScope(const DIScope &N) { void Verifier::visitDISubrange(const DISubrange &N) { AssertDI(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N); - bool HasAssumedSizedArraySupport = dwarf::isFortran(CurrentSourceLang); - AssertDI(HasAssumedSizedArraySupport || N.getRawCountNode() || - N.getRawUpperBound(), + bool HasAssumedSizedArraySupport = dwarf::isFortran(CurrentSourceLang); + AssertDI(HasAssumedSizedArraySupport || N.getRawCountNode() || + N.getRawUpperBound(), "Subrange must contain count or upperBound", &N); AssertDI(!N.getRawCountNode() || !N.getRawUpperBound(), "Subrange can have any one of count or upperBound", &N); @@ -941,43 +941,43 @@ void Verifier::visitDISubrange(const DISubrange &N) { "Stride must be signed constant or DIVariable or DIExpression", &N); } -void Verifier::visitDIGenericSubrange(const DIGenericSubrange &N) { - AssertDI(N.getTag() == dwarf::DW_TAG_generic_subrange, "invalid tag", &N); - AssertDI(N.getRawCountNode() || N.getRawUpperBound(), - "GenericSubrange must contain count or upperBound", &N); - AssertDI(!N.getRawCountNode() || !N.getRawUpperBound(), - "GenericSubrange can have any one of count or upperBound", &N); - auto *CBound = N.getRawCountNode(); - AssertDI(!CBound || isa<DIVariable>(CBound) || isa<DIExpression>(CBound), - "Count must be signed constant or DIVariable or DIExpression", &N); - auto *LBound = N.getRawLowerBound(); - AssertDI(LBound, "GenericSubrange must contain lowerBound", &N); - AssertDI(isa<DIVariable>(LBound) || isa<DIExpression>(LBound), - "LowerBound must be signed constant or DIVariable or DIExpression", - &N); - auto *UBound = N.getRawUpperBound(); - AssertDI(!UBound || isa<DIVariable>(UBound) || isa<DIExpression>(UBound), - "UpperBound must be signed constant or DIVariable or DIExpression", - &N); - auto *Stride = N.getRawStride(); - AssertDI(Stride, "GenericSubrange must contain stride", &N); - AssertDI(isa<DIVariable>(Stride) || isa<DIExpression>(Stride), - "Stride must be signed constant or DIVariable or DIExpression", &N); -} - +void Verifier::visitDIGenericSubrange(const DIGenericSubrange &N) { + AssertDI(N.getTag() == dwarf::DW_TAG_generic_subrange, "invalid tag", &N); + AssertDI(N.getRawCountNode() || N.getRawUpperBound(), + "GenericSubrange must contain count or upperBound", &N); + AssertDI(!N.getRawCountNode() || !N.getRawUpperBound(), + "GenericSubrange can have any one of count or upperBound", &N); + auto *CBound = N.getRawCountNode(); + AssertDI(!CBound || isa<DIVariable>(CBound) || isa<DIExpression>(CBound), + "Count must be signed constant or DIVariable or DIExpression", &N); + auto *LBound = N.getRawLowerBound(); + AssertDI(LBound, "GenericSubrange must contain lowerBound", &N); + AssertDI(isa<DIVariable>(LBound) || isa<DIExpression>(LBound), + "LowerBound must be signed constant or DIVariable or DIExpression", + &N); + auto *UBound = N.getRawUpperBound(); + AssertDI(!UBound || isa<DIVariable>(UBound) || isa<DIExpression>(UBound), + "UpperBound must be signed constant or DIVariable or DIExpression", + &N); + auto *Stride = N.getRawStride(); + AssertDI(Stride, "GenericSubrange must contain stride", &N); + AssertDI(isa<DIVariable>(Stride) || isa<DIExpression>(Stride), + "Stride must be signed constant or DIVariable or DIExpression", &N); +} + void Verifier::visitDIEnumerator(const DIEnumerator &N) { AssertDI(N.getTag() == dwarf::DW_TAG_enumerator, "invalid tag", &N); } void Verifier::visitDIBasicType(const DIBasicType &N) { AssertDI(N.getTag() == dwarf::DW_TAG_base_type || - N.getTag() == dwarf::DW_TAG_unspecified_type || - N.getTag() == dwarf::DW_TAG_string_type, + N.getTag() == dwarf::DW_TAG_unspecified_type || + N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N); -} - -void Verifier::visitDIStringType(const DIStringType &N) { - AssertDI(N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N); +} + +void Verifier::visitDIStringType(const DIStringType &N) { + AssertDI(N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N); AssertDI(!(N.isBigEndian() && N.isLittleEndian()) , "has conflicting flags", &N); } @@ -1079,21 +1079,21 @@ void Verifier::visitDICompositeType(const DICompositeType &N) { AssertDI(N.getTag() == dwarf::DW_TAG_array_type, "dataLocation can only appear in array type"); } - - if (N.getRawAssociated()) { - AssertDI(N.getTag() == dwarf::DW_TAG_array_type, - "associated can only appear in array type"); - } - - if (N.getRawAllocated()) { - AssertDI(N.getTag() == dwarf::DW_TAG_array_type, - "allocated can only appear in array type"); - } - - if (N.getRawRank()) { - AssertDI(N.getTag() == dwarf::DW_TAG_array_type, - "rank can only appear in array type"); - } + + if (N.getRawAssociated()) { + AssertDI(N.getTag() == dwarf::DW_TAG_array_type, + "associated can only appear in array type"); + } + + if (N.getRawAllocated()) { + AssertDI(N.getTag() == dwarf::DW_TAG_array_type, + "allocated can only appear in array type"); + } + + if (N.getRawRank()) { + AssertDI(N.getTag() == dwarf::DW_TAG_array_type, + "rank can only appear in array type"); + } } void Verifier::visitDISubroutineType(const DISubroutineType &N) { @@ -1143,8 +1143,8 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) { AssertDI(!N.getFile()->getFilename().empty(), "invalid filename", &N, N.getFile()); - CurrentSourceLang = (dwarf::SourceLanguage)N.getSourceLanguage(); - + CurrentSourceLang = (dwarf::SourceLanguage)N.getSourceLanguage(); + verifySourceDebugInfo(N, *N.getFile()); AssertDI((N.getEmissionKind() <= DICompileUnit::LastEmissionKind), @@ -1586,8 +1586,8 @@ void Verifier::visitModuleFlagCGProfileEntry(const MDOperand &MDO) { if (!FuncMDO) return; auto F = dyn_cast<ValueAsMetadata>(FuncMDO); - Assert(F && isa<Function>(F->getValue()->stripPointerCasts()), - "expected a Function or null", FuncMDO); + Assert(F && isa<Function>(F->getValue()->stripPointerCasts()), + "expected a Function or null", FuncMDO); }; auto Node = dyn_cast_or_null<MDNode>(MDO); Assert(Node && Node->getNumOperands() == 3, "expected a MDNode triple", MDO); @@ -1605,7 +1605,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { case Attribute::NoReturn: case Attribute::NoSync: case Attribute::WillReturn: - case Attribute::NoCallback: + case Attribute::NoCallback: case Attribute::NoCfCheck: case Attribute::NoUnwind: case Attribute::NoInline: @@ -1634,7 +1634,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { case Attribute::Builtin: case Attribute::NoBuiltin: case Attribute::Cold: - case Attribute::Hot: + case Attribute::Hot: case Attribute::OptForFuzzing: case Attribute::OptimizeNone: case Attribute::JumpTable: @@ -1648,8 +1648,8 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { case Attribute::Speculatable: case Attribute::StrictFP: case Attribute::NullPointerIsValid: - case Attribute::MustProgress: - case Attribute::NoProfile: + case Attribute::MustProgress: + case Attribute::NoProfile: return true; default: break; @@ -1717,10 +1717,10 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty, AttrCount += Attrs.hasAttribute(Attribute::StructRet) || Attrs.hasAttribute(Attribute::InReg); AttrCount += Attrs.hasAttribute(Attribute::Nest); - AttrCount += Attrs.hasAttribute(Attribute::ByRef); + AttrCount += Attrs.hasAttribute(Attribute::ByRef); Assert(AttrCount <= 1, "Attributes 'byval', 'inalloca', 'preallocated', 'inreg', 'nest', " - "'byref', and 'sret' are incompatible!", + "'byref', and 'sret' are incompatible!", V); Assert(!(Attrs.hasAttribute(Attribute::InAlloca) && @@ -1775,10 +1775,10 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty, SmallPtrSet<Type*, 4> Visited; if (!PTy->getElementType()->isSized(&Visited)) { Assert(!Attrs.hasAttribute(Attribute::ByVal) && - !Attrs.hasAttribute(Attribute::ByRef) && - !Attrs.hasAttribute(Attribute::InAlloca) && - !Attrs.hasAttribute(Attribute::Preallocated), - "Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not " + !Attrs.hasAttribute(Attribute::ByRef) && + !Attrs.hasAttribute(Attribute::InAlloca) && + !Attrs.hasAttribute(Attribute::Preallocated), + "Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not " "support unsized types!", V); } @@ -1787,28 +1787,28 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty, "Attribute 'swifterror' only applies to parameters " "with pointer to pointer type!", V); - - if (Attrs.hasAttribute(Attribute::ByRef)) { - Assert(Attrs.getByRefType() == PTy->getElementType(), - "Attribute 'byref' type does not match parameter!", V); - } - - if (Attrs.hasAttribute(Attribute::ByVal) && Attrs.getByValType()) { - Assert(Attrs.getByValType() == PTy->getElementType(), - "Attribute 'byval' type does not match parameter!", V); - } - - if (Attrs.hasAttribute(Attribute::Preallocated)) { - Assert(Attrs.getPreallocatedType() == PTy->getElementType(), - "Attribute 'preallocated' type does not match parameter!", V); - } + + if (Attrs.hasAttribute(Attribute::ByRef)) { + Assert(Attrs.getByRefType() == PTy->getElementType(), + "Attribute 'byref' type does not match parameter!", V); + } + + if (Attrs.hasAttribute(Attribute::ByVal) && Attrs.getByValType()) { + Assert(Attrs.getByValType() == PTy->getElementType(), + "Attribute 'byval' type does not match parameter!", V); + } + + if (Attrs.hasAttribute(Attribute::Preallocated)) { + Assert(Attrs.getPreallocatedType() == PTy->getElementType(), + "Attribute 'preallocated' type does not match parameter!", V); + } } else { Assert(!Attrs.hasAttribute(Attribute::ByVal), "Attribute 'byval' only applies to parameters with pointer type!", V); - Assert(!Attrs.hasAttribute(Attribute::ByRef), - "Attribute 'byref' only applies to parameters with pointer type!", - V); + Assert(!Attrs.hasAttribute(Attribute::ByRef), + "Attribute 'byref' only applies to parameters with pointer type!", + V); Assert(!Attrs.hasAttribute(Attribute::SwiftError), "Attribute 'swifterror' only applies to parameters " "with pointer type!", @@ -1839,11 +1839,11 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, !RetAttrs.hasAttribute(Attribute::Returned) && !RetAttrs.hasAttribute(Attribute::InAlloca) && !RetAttrs.hasAttribute(Attribute::Preallocated) && - !RetAttrs.hasAttribute(Attribute::ByRef) && + !RetAttrs.hasAttribute(Attribute::ByRef) && !RetAttrs.hasAttribute(Attribute::SwiftSelf) && !RetAttrs.hasAttribute(Attribute::SwiftError)), - "Attributes 'byval', 'inalloca', 'preallocated', 'byref', " - "'nest', 'sret', 'nocapture', 'nofree', " + "Attributes 'byval', 'inalloca', 'preallocated', 'byref', " + "'nest', 'sret', 'nocapture', 'nofree', " "'returned', 'swiftself', and 'swifterror' do not apply to return " "values!", V); @@ -2177,8 +2177,8 @@ void Verifier::verifyStatepoint(const CallBase &Call) { Call); const int NumTransitionArgs = cast<ConstantInt>(NumTransitionArgsV)->getZExtValue(); - Assert(NumTransitionArgs == 0, - "gc.statepoint w/inline transition bundle is deprecated", Call); + Assert(NumTransitionArgs == 0, + "gc.statepoint w/inline transition bundle is deprecated", Call); const int EndTransitionArgsInx = EndCallArgsInx + 1 + NumTransitionArgs; const Value *NumDeoptArgsV = Call.getArgOperand(EndTransitionArgsInx + 1); @@ -2187,12 +2187,12 @@ void Verifier::verifyStatepoint(const CallBase &Call) { "must be constant integer", Call); const int NumDeoptArgs = cast<ConstantInt>(NumDeoptArgsV)->getZExtValue(); - Assert(NumDeoptArgs == 0, - "gc.statepoint w/inline deopt operands is deprecated", Call); + Assert(NumDeoptArgs == 0, + "gc.statepoint w/inline deopt operands is deprecated", Call); - const int ExpectedNumArgs = 7 + NumCallArgs; - Assert(ExpectedNumArgs == (int)Call.arg_size(), - "gc.statepoint too many arguments", Call); + const int ExpectedNumArgs = 7 + NumCallArgs; + Assert(ExpectedNumArgs == (int)Call.arg_size(), + "gc.statepoint too many arguments", Call); // Check that the only uses of this gc.statepoint are gc.result or // gc.relocate calls which are tied to this statepoint and thus part @@ -2338,11 +2338,11 @@ void Verifier::visitFunction(const Function &F) { default: case CallingConv::C: break; - case CallingConv::X86_INTR: { - Assert(F.arg_empty() || Attrs.hasParamAttribute(0, Attribute::ByVal), - "Calling convention parameter requires byval", &F); - break; - } + case CallingConv::X86_INTR: { + Assert(F.arg_empty() || Attrs.hasParamAttribute(0, Attribute::ByVal), + "Calling convention parameter requires byval", &F); + break; + } case CallingConv::AMDGPU_KERNEL: case CallingConv::SPIR_KERNEL: Assert(F.getReturnType()->isVoidTy(), @@ -2355,28 +2355,28 @@ void Verifier::visitFunction(const Function &F) { case CallingConv::AMDGPU_CS: Assert(!F.hasStructRetAttr(), "Calling convention does not allow sret", &F); - if (F.getCallingConv() != CallingConv::SPIR_KERNEL) { - const unsigned StackAS = DL.getAllocaAddrSpace(); - unsigned i = 0; - for (const Argument &Arg : F.args()) { - Assert(!Attrs.hasParamAttribute(i, Attribute::ByVal), - "Calling convention disallows byval", &F); - Assert(!Attrs.hasParamAttribute(i, Attribute::Preallocated), - "Calling convention disallows preallocated", &F); - Assert(!Attrs.hasParamAttribute(i, Attribute::InAlloca), - "Calling convention disallows inalloca", &F); - - if (Attrs.hasParamAttribute(i, Attribute::ByRef)) { - // FIXME: Should also disallow LDS and GDS, but we don't have the enum - // value here. - Assert(Arg.getType()->getPointerAddressSpace() != StackAS, - "Calling convention disallows stack byref", &F); - } - - ++i; - } - } - + if (F.getCallingConv() != CallingConv::SPIR_KERNEL) { + const unsigned StackAS = DL.getAllocaAddrSpace(); + unsigned i = 0; + for (const Argument &Arg : F.args()) { + Assert(!Attrs.hasParamAttribute(i, Attribute::ByVal), + "Calling convention disallows byval", &F); + Assert(!Attrs.hasParamAttribute(i, Attribute::Preallocated), + "Calling convention disallows preallocated", &F); + Assert(!Attrs.hasParamAttribute(i, Attribute::InAlloca), + "Calling convention disallows inalloca", &F); + + if (Attrs.hasParamAttribute(i, Attribute::ByRef)) { + // FIXME: Should also disallow LDS and GDS, but we don't have the enum + // value here. + Assert(Arg.getType()->getPointerAddressSpace() != StackAS, + "Calling convention disallows stack byref", &F); + } + + ++i; + } + } + LLVM_FALLTHROUGH; case CallingConv::Fast: case CallingConv::Cold: @@ -2479,10 +2479,10 @@ void Verifier::visitFunction(const Function &F) { "function must have a single !dbg attachment", &F, I.second); AssertDI(isa<DISubprogram>(I.second), "function !dbg attachment must be a subprogram", &F, I.second); - AssertDI(cast<DISubprogram>(I.second)->isDistinct(), - "function definition may only have a distinct !dbg attachment", - &F); - + AssertDI(cast<DISubprogram>(I.second)->isDistinct(), + "function definition may only have a distinct !dbg attachment", + &F); + auto *SP = cast<DISubprogram>(I.second); const Function *&AttachedTo = DISubprogramAttachments[SP]; AssertDI(!AttachedTo || AttachedTo == &F, @@ -2577,7 +2577,7 @@ void Verifier::visitBasicBlock(BasicBlock &BB) { // Check constraints that this basic block imposes on all of the PHI nodes in // it. if (isa<PHINode>(BB.front())) { - SmallVector<BasicBlock *, 8> Preds(predecessors(&BB)); + SmallVector<BasicBlock *, 8> Preds(predecessors(&BB)); SmallVector<std::pair<BasicBlock*, Value*>, 8> Values; llvm::sort(Preds); for (const PHINode &PN : BB.phis()) { @@ -2971,8 +2971,8 @@ void Verifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) { Assert(SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace(), "AddrSpaceCast must be between different address spaces", &I); if (auto *SrcVTy = dyn_cast<VectorType>(SrcTy)) - Assert(SrcVTy->getElementCount() == - cast<VectorType>(DestTy)->getElementCount(), + Assert(SrcVTy->getElementCount() == + cast<VectorType>(DestTy)->getElementCount(), "AddrSpaceCast vector pointer number of elements mismatch", &I); visitInstruction(I); } @@ -3258,19 +3258,19 @@ static bool isTypeCongruent(Type *L, Type *R) { static AttrBuilder getParameterABIAttributes(int I, AttributeList Attrs) { static const Attribute::AttrKind ABIAttrs[] = { - Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca, - Attribute::InReg, Attribute::SwiftSelf, Attribute::SwiftError, - Attribute::Preallocated, Attribute::ByRef}; + Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca, + Attribute::InReg, Attribute::SwiftSelf, Attribute::SwiftError, + Attribute::Preallocated, Attribute::ByRef}; AttrBuilder Copy; for (auto AK : ABIAttrs) { if (Attrs.hasParamAttribute(I, AK)) Copy.addAttribute(AK); } - - // `align` is ABI-affecting only in combination with `byval` or `byref`. + + // `align` is ABI-affecting only in combination with `byval` or `byref`. if (Attrs.hasParamAttribute(I, Attribute::Alignment) && - (Attrs.hasParamAttribute(I, Attribute::ByVal) || - Attrs.hasParamAttribute(I, Attribute::ByRef))) + (Attrs.hasParamAttribute(I, Attribute::ByVal) || + Attrs.hasParamAttribute(I, Attribute::ByRef))) Copy.addAlignmentAttr(Attrs.getParamAlignment(I)); return Copy; } @@ -3506,7 +3506,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { "GEP base pointer is not a vector or a vector of pointers", &GEP); Assert(GEP.getSourceElementType()->isSized(), "GEP into unsized type!", &GEP); - SmallVector<Value *, 16> Idxs(GEP.indices()); + SmallVector<Value *, 16> Idxs(GEP.indices()); Assert(all_of( Idxs, [](Value* V) { return V->getType()->isIntOrIntVectorTy(); }), "GEP indexes must be integers", &GEP); @@ -4291,14 +4291,14 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { } } -void Verifier::visitAnnotationMetadata(MDNode *Annotation) { - Assert(isa<MDTuple>(Annotation), "annotation must be a tuple"); - Assert(Annotation->getNumOperands() >= 1, - "annotation must have at least one operand"); - for (const MDOperand &Op : Annotation->operands()) - Assert(isa<MDString>(Op.get()), "operands must be strings"); -} - +void Verifier::visitAnnotationMetadata(MDNode *Annotation) { + Assert(isa<MDTuple>(Annotation), "annotation must be a tuple"); + Assert(Annotation->getNumOperands() >= 1, + "annotation must have at least one operand"); + for (const MDOperand &Op : Annotation->operands()) + Assert(isa<MDString>(Op.get()), "operands must be strings"); +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -4368,7 +4368,7 @@ void Verifier::visitInstruction(Instruction &I) { F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 || F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint || - F->getIntrinsicID() == Intrinsic::wasm_rethrow, + F->getIntrinsicID() == Intrinsic::wasm_rethrow, "Cannot invoke an intrinsic other than donothing, patchpoint, " "statepoint, coro_resume or coro_destroy", &I); @@ -4459,9 +4459,9 @@ void Verifier::visitInstruction(Instruction &I) { if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof)) visitProfMetadata(I, MD); - if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation)) - visitAnnotationMetadata(Annotation); - + if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation)) + visitAnnotationMetadata(Annotation); + if (MDNode *N = I.getDebugLoc().getAsMDNode()) { AssertDI(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N, AreDebugLocsAllowed::Yes); @@ -4548,30 +4548,30 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { "tags must be valid attribute names"); Attribute::AttrKind Kind = Attribute::getAttrKindFromName(Elem.Tag->getKey()); - unsigned ArgCount = Elem.End - Elem.Begin; - if (Kind == Attribute::Alignment) { - Assert(ArgCount <= 3 && ArgCount >= 2, - "alignment assumptions should have 2 or 3 arguments"); - Assert(Call.getOperand(Elem.Begin)->getType()->isPointerTy(), - "first argument should be a pointer"); - Assert(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(), - "second argument should be an integer"); - if (ArgCount == 3) - Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(), - "third argument should be an integer if present"); - return; - } - Assert(ArgCount <= 2, "to many arguments"); + unsigned ArgCount = Elem.End - Elem.Begin; + if (Kind == Attribute::Alignment) { + Assert(ArgCount <= 3 && ArgCount >= 2, + "alignment assumptions should have 2 or 3 arguments"); + Assert(Call.getOperand(Elem.Begin)->getType()->isPointerTy(), + "first argument should be a pointer"); + Assert(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(), + "second argument should be an integer"); + if (ArgCount == 3) + Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(), + "third argument should be an integer if present"); + return; + } + Assert(ArgCount <= 2, "to many arguments"); if (Kind == Attribute::None) break; if (Attribute::doesAttrKindHaveArgument(Kind)) { - Assert(ArgCount == 2, "this attribute should have 2 arguments"); + Assert(ArgCount == 2, "this attribute should have 2 arguments"); Assert(isa<ConstantInt>(Call.getOperand(Elem.Begin + 1)), "the second argument should be a constant integral value"); } else if (isFuncOnlyAttr(Kind)) { - Assert((ArgCount) == 0, "this attribute has no argument"); + Assert((ArgCount) == 0, "this attribute has no argument"); } else if (!isFuncOrArgAttr(Kind)) { - Assert((ArgCount) == 1, "this attribute should have one argument"); + Assert((ArgCount) == 1, "this attribute should have one argument"); } } break; @@ -5010,17 +5010,17 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { case Intrinsic::sadd_sat: case Intrinsic::uadd_sat: case Intrinsic::ssub_sat: - case Intrinsic::usub_sat: - case Intrinsic::sshl_sat: - case Intrinsic::ushl_sat: { + case Intrinsic::usub_sat: + case Intrinsic::sshl_sat: + case Intrinsic::ushl_sat: { Value *Op1 = Call.getArgOperand(0); Value *Op2 = Call.getArgOperand(1); Assert(Op1->getType()->isIntOrIntVectorTy(), - "first operand of [us][add|sub|shl]_sat must be an int type or " - "vector of ints"); + "first operand of [us][add|sub|shl]_sat must be an int type or " + "vector of ints"); Assert(Op2->getType()->isIntOrIntVectorTy(), - "second operand of [us][add|sub|shl]_sat must be an int type or " - "vector of ints"); + "second operand of [us][add|sub|shl]_sat must be an int type or " + "vector of ints"); break; } case Intrinsic::smul_fix: @@ -5073,14 +5073,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { Assert(Size % 16 == 0, "bswap must be an even number of bytes", &Call); break; } - case Intrinsic::invariant_start: { - ConstantInt *InvariantSize = dyn_cast<ConstantInt>(Call.getArgOperand(0)); - Assert(InvariantSize && - (!InvariantSize->isNegative() || InvariantSize->isMinusOne()), - "invariant_start parameter must be -1, 0 or a positive number", - &Call); - break; - } + case Intrinsic::invariant_start: { + ConstantInt *InvariantSize = dyn_cast<ConstantInt>(Call.getArgOperand(0)); + Assert(InvariantSize && + (!InvariantSize->isNegative() || InvariantSize->isMinusOne()), + "invariant_start parameter must be -1, 0 or a positive number", + &Call); + break; + } case Intrinsic::matrix_multiply: case Intrinsic::matrix_transpose: case Intrinsic::matrix_column_major_load: @@ -5144,7 +5144,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { "Vector element type mismatch of the result and second operand " "vector!", IF); - Assert(cast<FixedVectorType>(ResultTy)->getNumElements() == + Assert(cast<FixedVectorType>(ResultTy)->getNumElements() == NumRows->getZExtValue() * NumColumns->getZExtValue(), "Result of a matrix operation does not fit in the returned vector!"); @@ -5154,30 +5154,30 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { break; } - case Intrinsic::experimental_vector_insert: { - VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType()); - VectorType *SubVecTy = cast<VectorType>(Call.getArgOperand(1)->getType()); - - Assert(VecTy->getElementType() == SubVecTy->getElementType(), - "experimental_vector_insert parameters must have the same element " - "type.", - &Call); - break; - } - case Intrinsic::experimental_vector_extract: { - VectorType *ResultTy = cast<VectorType>(Call.getType()); - VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType()); - - Assert(ResultTy->getElementType() == VecTy->getElementType(), - "experimental_vector_extract result must have the same element " - "type as the input vector.", - &Call); - break; - } - case Intrinsic::experimental_noalias_scope_decl: { - NoAliasScopeDecls.push_back(cast<IntrinsicInst>(&Call)); - break; - } + case Intrinsic::experimental_vector_insert: { + VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType()); + VectorType *SubVecTy = cast<VectorType>(Call.getArgOperand(1)->getType()); + + Assert(VecTy->getElementType() == SubVecTy->getElementType(), + "experimental_vector_insert parameters must have the same element " + "type.", + &Call); + break; + } + case Intrinsic::experimental_vector_extract: { + VectorType *ResultTy = cast<VectorType>(Call.getType()); + VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType()); + + Assert(ResultTy->getElementType() == VecTy->getElementType(), + "experimental_vector_extract result must have the same element " + "type as the input vector.", + &Call); + break; + } + case Intrinsic::experimental_noalias_scope_decl: { + NoAliasScopeDecls.push_back(cast<IntrinsicInst>(&Call)); + break; + } }; } @@ -5254,7 +5254,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) { Assert(Operand->getType()->isFPOrFPVectorTy(), "Intrinsic first argument must be floating point", &FPI); if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) { - NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements(); + NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements(); } Operand = &FPI; @@ -5263,7 +5263,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) { Assert(Operand->getType()->isIntOrIntVectorTy(), "Intrinsic result must be an integer", &FPI); if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) { - Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(), + Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(), "Intrinsic first argument and result vector lengths must be equal", &FPI); } @@ -5277,7 +5277,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) { Assert(Operand->getType()->isIntOrIntVectorTy(), "Intrinsic first argument must be integer", &FPI); if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) { - NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements(); + NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements(); } Operand = &FPI; @@ -5286,7 +5286,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) { Assert(Operand->getType()->isFPOrFPVectorTy(), "Intrinsic result must be a floating point", &FPI); if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) { - Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(), + Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(), "Intrinsic first argument and result vector lengths must be equal", &FPI); } @@ -5305,8 +5305,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) { Assert(OperandTy->isVectorTy() == ResultTy->isVectorTy(), "Intrinsic first argument and result disagree on vector use", &FPI); if (OperandTy->isVectorTy()) { - Assert(cast<FixedVectorType>(OperandTy)->getNumElements() == - cast<FixedVectorType>(ResultTy)->getNumElements(), + Assert(cast<FixedVectorType>(OperandTy)->getNumElements() == + cast<FixedVectorType>(ResultTy)->getNumElements(), "Intrinsic first argument and result vector lengths must be equal", &FPI); } @@ -5528,75 +5528,75 @@ void Verifier::verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F) { "inconsistent use of embedded source"); } -void Verifier::verifyNoAliasScopeDecl() { - if (NoAliasScopeDecls.empty()) - return; - - // only a single scope must be declared at a time. - for (auto *II : NoAliasScopeDecls) { - assert(II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl && - "Not a llvm.experimental.noalias.scope.decl ?"); - const auto *ScopeListMV = dyn_cast<MetadataAsValue>( - II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg)); - Assert(ScopeListMV != nullptr, - "llvm.experimental.noalias.scope.decl must have a MetadataAsValue " - "argument", - II); - - const auto *ScopeListMD = dyn_cast<MDNode>(ScopeListMV->getMetadata()); - Assert(ScopeListMD != nullptr, "!id.scope.list must point to an MDNode", - II); - Assert(ScopeListMD->getNumOperands() == 1, - "!id.scope.list must point to a list with a single scope", II); - } - - // Only check the domination rule when requested. Once all passes have been - // adapted this option can go away. - if (!VerifyNoAliasScopeDomination) - return; - - // Now sort the intrinsics based on the scope MDNode so that declarations of - // the same scopes are next to each other. - auto GetScope = [](IntrinsicInst *II) { - const auto *ScopeListMV = cast<MetadataAsValue>( - II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg)); - return &cast<MDNode>(ScopeListMV->getMetadata())->getOperand(0); - }; - - // We are sorting on MDNode pointers here. For valid input IR this is ok. - // TODO: Sort on Metadata ID to avoid non-deterministic error messages. - auto Compare = [GetScope](IntrinsicInst *Lhs, IntrinsicInst *Rhs) { - return GetScope(Lhs) < GetScope(Rhs); - }; - - llvm::sort(NoAliasScopeDecls, Compare); - - // Go over the intrinsics and check that for the same scope, they are not - // dominating each other. - auto ItCurrent = NoAliasScopeDecls.begin(); - while (ItCurrent != NoAliasScopeDecls.end()) { - auto CurScope = GetScope(*ItCurrent); - auto ItNext = ItCurrent; - do { - ++ItNext; - } while (ItNext != NoAliasScopeDecls.end() && - GetScope(*ItNext) == CurScope); - - // [ItCurrent, ItNext) represents the declarations for the same scope. - // Ensure they are not dominating each other.. but only if it is not too - // expensive. - if (ItNext - ItCurrent < 32) - for (auto *I : llvm::make_range(ItCurrent, ItNext)) - for (auto *J : llvm::make_range(ItCurrent, ItNext)) - if (I != J) - Assert(!DT.dominates(I, J), - "llvm.experimental.noalias.scope.decl dominates another one " - "with the same scope", - I); - ItCurrent = ItNext; - } -} - +void Verifier::verifyNoAliasScopeDecl() { + if (NoAliasScopeDecls.empty()) + return; + + // only a single scope must be declared at a time. + for (auto *II : NoAliasScopeDecls) { + assert(II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl && + "Not a llvm.experimental.noalias.scope.decl ?"); + const auto *ScopeListMV = dyn_cast<MetadataAsValue>( + II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg)); + Assert(ScopeListMV != nullptr, + "llvm.experimental.noalias.scope.decl must have a MetadataAsValue " + "argument", + II); + + const auto *ScopeListMD = dyn_cast<MDNode>(ScopeListMV->getMetadata()); + Assert(ScopeListMD != nullptr, "!id.scope.list must point to an MDNode", + II); + Assert(ScopeListMD->getNumOperands() == 1, + "!id.scope.list must point to a list with a single scope", II); + } + + // Only check the domination rule when requested. Once all passes have been + // adapted this option can go away. + if (!VerifyNoAliasScopeDomination) + return; + + // Now sort the intrinsics based on the scope MDNode so that declarations of + // the same scopes are next to each other. + auto GetScope = [](IntrinsicInst *II) { + const auto *ScopeListMV = cast<MetadataAsValue>( + II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg)); + return &cast<MDNode>(ScopeListMV->getMetadata())->getOperand(0); + }; + + // We are sorting on MDNode pointers here. For valid input IR this is ok. + // TODO: Sort on Metadata ID to avoid non-deterministic error messages. + auto Compare = [GetScope](IntrinsicInst *Lhs, IntrinsicInst *Rhs) { + return GetScope(Lhs) < GetScope(Rhs); + }; + + llvm::sort(NoAliasScopeDecls, Compare); + + // Go over the intrinsics and check that for the same scope, they are not + // dominating each other. + auto ItCurrent = NoAliasScopeDecls.begin(); + while (ItCurrent != NoAliasScopeDecls.end()) { + auto CurScope = GetScope(*ItCurrent); + auto ItNext = ItCurrent; + do { + ++ItNext; + } while (ItNext != NoAliasScopeDecls.end() && + GetScope(*ItNext) == CurScope); + + // [ItCurrent, ItNext) represents the declarations for the same scope. + // Ensure they are not dominating each other.. but only if it is not too + // expensive. + if (ItNext - ItCurrent < 32) + for (auto *I : llvm::make_range(ItCurrent, ItNext)) + for (auto *J : llvm::make_range(ItCurrent, ItNext)) + if (I != J) + Assert(!DT.dominates(I, J), + "llvm.experimental.noalias.scope.decl dominates another one " + "with the same scope", + I); + ItCurrent = ItNext; + } +} + //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// |