diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-24 22:00:03 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-24 22:00:03 +0000 |
commit | 480093f4440d54b30b3025afeac24b48f2ba7a2e (patch) | |
tree | 162e72994062888647caf0d875428db9445491a8 /contrib/llvm-project/llvm/lib/IR | |
parent | 489b1cf2ecf5b9b4a394857987014bfb09067726 (diff) | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-480093f4440d54b30b3025afeac24b48f2ba7a2e.tar.gz src-480093f4440d54b30b3025afeac24b48f2ba7a2e.zip |
Merge ^/vendor/lvm-project/master up to its last change (upstream commit
e26a78e70), and resolve conflicts.
Notes
Notes:
svn path=/projects/clang1000-import/; revision=357095
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR')
34 files changed, 967 insertions, 764 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/AbstractCallSite.cpp b/contrib/llvm-project/llvm/lib/IR/AbstractCallSite.cpp index b7a81030f41c..19b35665c3fa 100644 --- a/contrib/llvm-project/llvm/lib/IR/AbstractCallSite.cpp +++ b/contrib/llvm-project/llvm/lib/IR/AbstractCallSite.cpp @@ -33,6 +33,25 @@ STATISTIC(NumInvalidAbstractCallSitesUnknownCallee, STATISTIC(NumInvalidAbstractCallSitesNoCallback, "Number of invalid abstract call sites created (no callback)"); +void AbstractCallSite::getCallbackUses(ImmutableCallSite ICS, + SmallVectorImpl<const Use *> &CBUses) { + const Function *Callee = ICS.getCalledFunction(); + if (!Callee) + return; + + MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback); + if (!CallbackMD) + return; + + for (const MDOperand &Op : CallbackMD->operands()) { + MDNode *OpMD = cast<MDNode>(Op.get()); + auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0)); + uint64_t CBCalleeIdx = + cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue(); + CBUses.push_back(ICS.arg_begin() + CBCalleeIdx); + } +} + /// Create an abstract call site from a use. AbstractCallSite::AbstractCallSite(const Use *U) : CS(U->getUser()) { diff --git a/contrib/llvm-project/llvm/lib/IR/AsmWriter.cpp b/contrib/llvm-project/llvm/lib/IR/AsmWriter.cpp index b0c26e0ecaf5..acf0e4afef27 100644 --- a/contrib/llvm-project/llvm/lib/IR/AsmWriter.cpp +++ b/contrib/llvm-project/llvm/lib/IR/AsmWriter.cpp @@ -353,6 +353,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::CXX_FAST_TLS: Out << "cxx_fast_tlscc"; break; case CallingConv::GHC: Out << "ghccc"; break; case CallingConv::Tail: Out << "tailcc"; break; + case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break; case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break; case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break; case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break; @@ -363,6 +364,9 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break; case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break; case CallingConv::AArch64_VectorCall: Out << "aarch64_vector_pcs"; break; + case CallingConv::AArch64_SVE_VectorCall: + Out << "aarch64_sve_vector_pcs"; + break; case CallingConv::MSP430_INTR: Out << "msp430_intrcc"; break; case CallingConv::AVR_INTR: Out << "avr_intrcc "; break; case CallingConv::AVR_SIGNAL: Out << "avr_signalcc "; break; @@ -2053,7 +2057,7 @@ static void writeDIModule(raw_ostream &Out, const DIModule *N, Printer.printString("name", N->getName()); Printer.printString("configMacros", N->getConfigurationMacros()); Printer.printString("includePath", N->getIncludePath()); - Printer.printString("isysroot", N->getISysRoot()); + Printer.printString("sysroot", N->getSysRoot()); Out << ")"; } @@ -2395,6 +2399,8 @@ public: void writeAllMDNodes(); void writeMDNode(unsigned Slot, const MDNode *Node); + void writeAttribute(const Attribute &Attr, bool InAttrGroup = false); + void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false); void writeAllAttributeGroups(); void printTypeIdentities(); @@ -2527,8 +2533,10 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, // Print the type TypePrinter.print(Operand->getType(), Out); // Print parameter attributes list - if (Attrs.hasAttributes()) - Out << ' ' << Attrs.getAsString(); + if (Attrs.hasAttributes()) { + Out << ' '; + writeAttributeSet(Attrs); + } Out << ' '; // Print the operand WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule); @@ -2951,13 +2959,14 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) { FunctionSummary::FFlags FFlags = FS->fflags(); if (FFlags.ReadNone | FFlags.ReadOnly | FFlags.NoRecurse | - FFlags.ReturnDoesNotAlias | FFlags.NoInline) { + FFlags.ReturnDoesNotAlias | FFlags.NoInline | FFlags.AlwaysInline) { Out << ", funcFlags: ("; Out << "readNone: " << FFlags.ReadNone; Out << ", readOnly: " << FFlags.ReadOnly; Out << ", noRecurse: " << FFlags.NoRecurse; Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias; Out << ", noInline: " << FFlags.NoInline; + Out << ", alwaysInline: " << FFlags.AlwaysInline; Out << ")"; } if (!FS->calls().empty()) { @@ -3395,9 +3404,6 @@ void AssemblyWriter::printTypeIdentities() { /// printFunction - Print all aspects of a function. void AssemblyWriter::printFunction(const Function *F) { - // Print out the return type and name. - Out << '\n'; - if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); if (F->isMaterializable()) @@ -3460,8 +3466,10 @@ void AssemblyWriter::printFunction(const Function *F) { TypePrinter.print(FT->getParamType(I), Out); AttributeSet ArgAttrs = Attrs.getParamAttributes(I); - if (ArgAttrs.hasAttributes()) - Out << ' ' << ArgAttrs.getAsString(); + if (ArgAttrs.hasAttributes()) { + Out << ' '; + writeAttributeSet(ArgAttrs); + } } } else { // The arguments are meaningful here, print them in detail. @@ -3547,8 +3555,10 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) { TypePrinter.print(Arg->getType(), Out); // Output parameter attributes list - if (Attrs.hasAttributes()) - Out << ' ' << Attrs.getAsString(); + if (Attrs.hasAttributes()) { + Out << ' '; + writeAttributeSet(Attrs); + } // Output name, if available... if (Arg->hasName()) { @@ -3563,6 +3573,7 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) { /// printBasicBlock - This member is called for each basic block in a method. void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { + assert(BB && BB->getParent() && "block without parent!"); bool IsEntryBlock = BB == &BB->getParent()->getEntryBlock(); if (BB->hasName()) { // Print out the label if it exists... Out << "\n"; @@ -3577,10 +3588,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { Out << "<badref>:"; } - if (!BB->getParent()) { - Out.PadToColumn(50); - Out << "; Error: Block without parent!"; - } else if (!IsEntryBlock) { + if (!IsEntryBlock) { // Output predecessors for the block. Out.PadToColumn(50); Out << ";"; @@ -4126,6 +4134,33 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) { WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule); } +void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) { + if (!Attr.isTypeAttribute()) { + Out << Attr.getAsString(InAttrGroup); + return; + } + + assert(Attr.hasAttribute(Attribute::ByVal) && "unexpected type attr"); + + Out << "byval"; + if (Type *Ty = Attr.getValueAsType()) { + Out << '('; + TypePrinter.print(Ty, Out); + Out << ')'; + } +} + +void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet, + bool InAttrGroup) { + bool FirstAttr = true; + for (const auto &Attr : AttrSet) { + if (!FirstAttr) + Out << ' '; + writeAttribute(Attr, InAttrGroup); + FirstAttr = false; + } +} + void AssemblyWriter::writeAllAttributeGroups() { std::vector<std::pair<AttributeSet, unsigned>> asVec; asVec.resize(Machine.as_size()); diff --git a/contrib/llvm-project/llvm/lib/IR/Attributes.cpp b/contrib/llvm-project/llvm/lib/IR/Attributes.cpp index cc370e628e9a..5ca99c981739 100644 --- a/contrib/llvm-project/llvm/lib/IR/Attributes.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Attributes.cpp @@ -618,7 +618,7 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, return *this; AttrBuilder B(AS); - for (const auto I : *this) + for (const auto &I : *this) B.addAttribute(I); return get(C, B); @@ -725,7 +725,7 @@ AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs) sizeof(AvailableAttrs) * CHAR_BIT, "Too many attributes"); - for (const auto I : *this) { + for (const auto &I : *this) { if (!I.isStringAttribute()) { Attribute::AttrKind Kind = I.getKindAsEnum(); AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8); @@ -745,7 +745,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end()); llvm::sort(SortedAttrs); - for (const auto Attr : SortedAttrs) + for (const auto &Attr : SortedAttrs) Attr.Profile(ID); void *InsertPoint; @@ -813,7 +813,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { } bool AttributeSetNode::hasAttribute(StringRef Kind) const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Kind)) return true; return false; @@ -821,7 +821,7 @@ bool AttributeSetNode::hasAttribute(StringRef Kind) const { Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { if (hasAttribute(Kind)) { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Kind)) return I; } @@ -829,42 +829,42 @@ Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { } Attribute AttributeSetNode::getAttribute(StringRef Kind) const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Kind)) return I; return {}; } MaybeAlign AttributeSetNode::getAlignment() const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Attribute::Alignment)) return I.getAlignment(); return None; } MaybeAlign AttributeSetNode::getStackAlignment() const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Attribute::StackAlignment)) return I.getStackAlignment(); return None; } Type *AttributeSetNode::getByValType() const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Attribute::ByVal)) return I.getValueAsType(); return 0; } uint64_t AttributeSetNode::getDereferenceableBytes() const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Attribute::Dereferenceable)) return I.getDereferenceableBytes(); return 0; } uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Attribute::DereferenceableOrNull)) return I.getDereferenceableOrNullBytes(); return 0; @@ -872,7 +872,7 @@ uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const { std::pair<unsigned, Optional<unsigned>> AttributeSetNode::getAllocSizeArgs() const { - for (const auto I : *this) + for (const auto &I : *this) if (I.hasAttribute(Attribute::AllocSize)) return I.getAllocSizeArgs(); return std::make_pair(0, 0); @@ -914,7 +914,7 @@ AttributeListImpl::AttributeListImpl(LLVMContext &C, "Too many attributes"); static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U, "function should be stored in slot 0"); - for (const auto I : Sets[0]) { + for (const auto &I : Sets[0]) { if (!I.isStringAttribute()) { Attribute::AttrKind Kind = I.getKindAsEnum(); AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8); @@ -1030,7 +1030,7 @@ AttributeList::get(LLVMContext &C, MaxIndex = Attrs[Attrs.size() - 2].first; SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1); - for (const auto Pair : Attrs) + for (const auto &Pair : Attrs) AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second; return getImpl(C, AttrVec); @@ -1098,7 +1098,7 @@ AttributeList AttributeList::get(LLVMContext &C, unsigned Index, AttributeList AttributeList::get(LLVMContext &C, unsigned Index, ArrayRef<StringRef> Kinds) { SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; - for (const auto K : Kinds) + for (const auto &K : Kinds) Attrs.emplace_back(Index, Attribute::get(C, K)); return get(C, Attrs); } @@ -1111,7 +1111,7 @@ AttributeList AttributeList::get(LLVMContext &C, return Attrs[0]; unsigned MaxSize = 0; - for (const auto List : Attrs) + for (const auto &List : Attrs) MaxSize = std::max(MaxSize, List.getNumAttrSets()); // If every list was empty, there is no point in merging the lists. @@ -1121,7 +1121,7 @@ AttributeList AttributeList::get(LLVMContext &C, SmallVector<AttributeSet, 8> NewAttrSets(MaxSize); for (unsigned I = 0; I < MaxSize; ++I) { AttrBuilder CurBuilder; - for (const auto List : Attrs) + for (const auto &List : Attrs) CurBuilder.merge(List.getAttributes(I - 1)); NewAttrSets[I] = AttributeSet::get(C, CurBuilder); } @@ -1659,7 +1659,7 @@ bool AttrBuilder::hasAttributes() const { bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const { AttributeSet AS = AL.getAttributes(Index); - for (const auto Attr : AS) { + for (const auto &Attr : AS) { if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { if (contains(Attr.getKindAsEnum())) return true; diff --git a/contrib/llvm-project/llvm/lib/IR/AutoUpgrade.cpp b/contrib/llvm-project/llvm/lib/IR/AutoUpgrade.cpp index 79f580d0e14d..6e2beeb839b6 100644 --- a/contrib/llvm-project/llvm/lib/IR/AutoUpgrade.cpp +++ b/contrib/llvm-project/llvm/lib/IR/AutoUpgrade.cpp @@ -22,6 +22,9 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsARM.h" +#include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" @@ -559,14 +562,33 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer); return true; } + if (Name.startswith("arm.neon.vqadds.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::sadd_sat, + F->arg_begin()->getType()); + return true; + } + if (Name.startswith("arm.neon.vqaddu.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::uadd_sat, + F->arg_begin()->getType()); + return true; + } + if (Name.startswith("arm.neon.vqsubs.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ssub_sat, + F->arg_begin()->getType()); + return true; + } + if (Name.startswith("arm.neon.vqsubu.")) { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::usub_sat, + F->arg_begin()->getType()); + return true; + } if (Name.startswith("aarch64.neon.addp")) { if (F->arg_size() != 2) break; // Invalid IR. - auto fArgs = F->getFunctionType()->params(); - VectorType *ArgTy = dyn_cast<VectorType>(fArgs[0]); - if (ArgTy && ArgTy->getElementType()->isFloatingPointTy()) { + VectorType *Ty = dyn_cast<VectorType>(F->getReturnType()); + if (Ty && Ty->getElementType()->isFloatingPointTy()) { NewFn = Intrinsic::getDeclaration(F->getParent(), - Intrinsic::aarch64_neon_faddp, fArgs); + Intrinsic::aarch64_neon_faddp, Ty); return true; } } @@ -3877,15 +3899,36 @@ void llvm::UpgradeARCRuntime(Module &M) { FunctionType *NewFuncTy = NewFn->getFunctionType(); SmallVector<Value *, 2> Args; + // Don't upgrade the intrinsic if it's not valid to bitcast the return + // value to the return type of the old function. + if (NewFuncTy->getReturnType() != CI->getType() && + !CastInst::castIsValid(Instruction::BitCast, CI, + NewFuncTy->getReturnType())) + continue; + + bool InvalidCast = false; + for (unsigned I = 0, E = CI->getNumArgOperands(); I != E; ++I) { Value *Arg = CI->getArgOperand(I); + // Bitcast argument to the parameter type of the new function if it's // not a variadic argument. - if (I < NewFuncTy->getNumParams()) + if (I < NewFuncTy->getNumParams()) { + // Don't upgrade the intrinsic if it's not valid to bitcast the argument + // to the parameter type of the new function. + if (!CastInst::castIsValid(Instruction::BitCast, Arg, + NewFuncTy->getParamType(I))) { + InvalidCast = true; + break; + } Arg = Builder.CreateBitCast(Arg, NewFuncTy->getParamType(I)); + } Args.push_back(Arg); } + if (InvalidCast) + continue; + // Create a call instruction that calls the new function. CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args); NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind()); @@ -4119,9 +4162,7 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { // If X86, and the datalayout matches the expected format, add pointer size // address spaces to the datalayout. - Triple::ArchType Arch = Triple(TT).getArch(); - if ((Arch != llvm::Triple::x86 && Arch != llvm::Triple::x86_64) || - DL.contains(AddrSpaces)) + if (!Triple(TT).isX86() || DL.contains(AddrSpaces)) return DL; SmallVector<StringRef, 4> Groups; @@ -4133,3 +4174,23 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { std::string Res = (Groups[1] + AddrSpaces + Groups[3]).toStringRef(Buf).str(); return Res; } + +void llvm::UpgradeFramePointerAttributes(AttrBuilder &B) { + StringRef FramePointer; + if (B.contains("no-frame-pointer-elim")) { + // The value can be "true" or "false". + for (const auto &I : B.td_attrs()) + if (I.first == "no-frame-pointer-elim") + FramePointer = I.second == "true" ? "all" : "none"; + B.removeAttribute("no-frame-pointer-elim"); + } + if (B.contains("no-frame-pointer-elim-non-leaf")) { + // The value is ignored. "no-frame-pointer-elim"="true" takes priority. + if (FramePointer != "all") + FramePointer = "non-leaf"; + B.removeAttribute("no-frame-pointer-elim-non-leaf"); + } + + if (!FramePointer.empty()) + B.addAttribute("frame-pointer", FramePointer); +} diff --git a/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp index 71fa795ec294..6e24f03c4cfd 100644 --- a/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp +++ b/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp @@ -792,13 +792,36 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, if (isa<UndefValue>(Val) || isa<UndefValue>(Idx)) return UndefValue::get(Val->getType()->getVectorElementType()); - if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) { - // ee({w,x,y,z}, wrong_value) -> undef - if (CIdx->uge(Val->getType()->getVectorNumElements())) - return UndefValue::get(Val->getType()->getVectorElementType()); - return Val->getAggregateElement(CIdx->getZExtValue()); + auto *CIdx = dyn_cast<ConstantInt>(Idx); + if (!CIdx) + return nullptr; + + // ee({w,x,y,z}, wrong_value) -> undef + if (CIdx->uge(Val->getType()->getVectorNumElements())) + return UndefValue::get(Val->getType()->getVectorElementType()); + + // ee (gep (ptr, idx0, ...), idx) -> gep (ee (ptr, idx), ee (idx0, idx), ...) + if (auto *CE = dyn_cast<ConstantExpr>(Val)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + SmallVector<Constant *, 8> Ops; + Ops.reserve(CE->getNumOperands()); + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { + Constant *Op = CE->getOperand(i); + if (Op->getType()->isVectorTy()) { + Constant *ScalarOp = ConstantExpr::getExtractElement(Op, Idx); + if (!ScalarOp) + return nullptr; + Ops.push_back(ScalarOp); + } else + Ops.push_back(Op); + } + return CE->getWithOperands(Ops, CE->getType()->getVectorElementType(), + false, + Ops[0]->getType()->getPointerElementType()); + } } - return nullptr; + + return Val->getAggregateElement(CIdx); } Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, @@ -810,6 +833,12 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx); if (!CIdx) return nullptr; + // Do not iterate on scalable vector. The num of elements is unknown at + // compile-time. + VectorType *ValTy = cast<VectorType>(Val->getType()); + if (ValTy->isScalable()) + return nullptr; + unsigned NumElts = Val->getType()->getVectorNumElements(); if (CIdx->uge(NumElts)) return UndefValue::get(Val->getType()); @@ -844,6 +873,12 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, // Don't break the bitcode reader hack. if (isa<ConstantExpr>(Mask)) return nullptr; + // Do not iterate on scalable vector. The num of elements is unknown at + // compile-time. + VectorType *ValTy = cast<VectorType>(V1->getType()); + if (ValTy->isScalable()) + return nullptr; + unsigned SrcNumElts = V1->getType()->getVectorNumElements(); // Loop over the shuffle mask, evaluating each element. @@ -965,6 +1000,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, Constant *C2) { assert(Instruction::isBinaryOp(Opcode) && "Non-binary instruction detected"); + // Simplify BinOps with their identity values first. They are no-ops and we + // can always return the other value, including undef or poison values. + // FIXME: remove unnecessary duplicated identity patterns below. + // FIXME: Use AllowRHSConstant with getBinOpIdentity to handle additional ops, + // like X << 0 = X. + Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, C1->getType()); + if (Identity) { + if (C1 == Identity) + return C2; + if (C2 == Identity) + return C1; + } + // Handle scalar UndefValue. Vectors are always evaluated per element. bool HasScalarUndef = !C1->getType()->isVectorTy() && (isa<UndefValue>(C1) || isa<UndefValue>(C2)); diff --git a/contrib/llvm-project/llvm/lib/IR/ConstantRange.cpp b/contrib/llvm-project/llvm/lib/IR/ConstantRange.cpp index 642bf0f39342..3d25cb5bfbdf 100644 --- a/contrib/llvm-project/llvm/lib/IR/ConstantRange.cpp +++ b/contrib/llvm-project/llvm/lib/IR/ConstantRange.cpp @@ -64,11 +64,11 @@ ConstantRange ConstantRange::fromKnownBits(const KnownBits &Known, // For unsigned ranges, or signed ranges with known sign bit, create a simple // range between the smallest and largest possible value. if (!IsSigned || Known.isNegative() || Known.isNonNegative()) - return ConstantRange(Known.One, ~Known.Zero + 1); + return ConstantRange(Known.getMinValue(), Known.getMaxValue() + 1); // If we don't know the sign bit, pick the lower bound as a negative number // and the upper bound as a non-negative one. - APInt Lower = Known.One, Upper = ~Known.Zero; + APInt Lower = Known.getMinValue(), Upper = Known.getMaxValue(); Lower.setSignBit(); Upper.clearSignBit(); return ConstantRange(Lower, Upper + 1); @@ -641,7 +641,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp, if (getBitWidth() == ResultBitWidth) return *this; else - return getFull(); + return getFull(ResultBitWidth); case Instruction::UIToFP: { // TODO: use input range if available auto BW = getBitWidth(); @@ -662,7 +662,7 @@ ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp, case Instruction::PtrToInt: case Instruction::AddrSpaceCast: // Conservatively return getFull set. - return getFull(); + return getFull(ResultBitWidth); }; } @@ -816,6 +816,23 @@ ConstantRange ConstantRange::binaryOp(Instruction::BinaryOps BinOp, } } +ConstantRange ConstantRange::overflowingBinaryOp(Instruction::BinaryOps BinOp, + const ConstantRange &Other, + unsigned NoWrapKind) const { + assert(Instruction::isBinaryOp(BinOp) && "Binary operators only!"); + + switch (BinOp) { + case Instruction::Add: + return addWithNoWrap(Other, NoWrapKind); + case Instruction::Sub: + return subWithNoWrap(Other, NoWrapKind); + default: + // Don't know about this Overflowing Binary Operation. + // Conservatively fallback to plain binop handling. + return binaryOp(BinOp, Other); + } +} + ConstantRange ConstantRange::add(const ConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet()) @@ -849,41 +866,17 @@ ConstantRange ConstantRange::addWithNoWrap(const ConstantRange &Other, using OBO = OverflowingBinaryOperator; ConstantRange Result = add(Other); - auto addWithNoUnsignedWrap = [this](const ConstantRange &Other) { - APInt LMin = getUnsignedMin(), LMax = getUnsignedMax(); - APInt RMin = Other.getUnsignedMin(), RMax = Other.getUnsignedMax(); - bool Overflow; - APInt NewMin = LMin.uadd_ov(RMin, Overflow); - if (Overflow) - return getEmpty(); - APInt NewMax = LMax.uadd_sat(RMax); - return getNonEmpty(std::move(NewMin), std::move(NewMax) + 1); - }; - - auto addWithNoSignedWrap = [this](const ConstantRange &Other) { - APInt LMin = getSignedMin(), LMax = getSignedMax(); - APInt RMin = Other.getSignedMin(), RMax = Other.getSignedMax(); - if (LMin.isNonNegative()) { - bool Overflow; - APInt Temp = LMin.sadd_ov(RMin, Overflow); - if (Overflow) - return getEmpty(); - } - if (LMax.isNegative()) { - bool Overflow; - APInt Temp = LMax.sadd_ov(RMax, Overflow); - if (Overflow) - return getEmpty(); - } - APInt NewMin = LMin.sadd_sat(RMin); - APInt NewMax = LMax.sadd_sat(RMax); - return getNonEmpty(std::move(NewMin), std::move(NewMax) + 1); - }; + // If an overflow happens for every value pair in these two constant ranges, + // we must return Empty set. In this case, we get that for free, because we + // get lucky that intersection of add() with uadd_sat()/sadd_sat() results + // in an empty set. if (NoWrapKind & OBO::NoSignedWrap) - Result = Result.intersectWith(addWithNoSignedWrap(Other), RangeType); + Result = Result.intersectWith(sadd_sat(Other), RangeType); + if (NoWrapKind & OBO::NoUnsignedWrap) - Result = Result.intersectWith(addWithNoUnsignedWrap(Other), RangeType); + Result = Result.intersectWith(uadd_sat(Other), RangeType); + return Result; } @@ -907,6 +900,36 @@ ConstantRange::sub(const ConstantRange &Other) const { return X; } +ConstantRange ConstantRange::subWithNoWrap(const ConstantRange &Other, + unsigned NoWrapKind, + PreferredRangeType RangeType) const { + // Calculate the range for "X - Y" which is guaranteed not to wrap(overflow). + // (X is from this, and Y is from Other) + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + if (isFullSet() && Other.isFullSet()) + return getFull(); + + using OBO = OverflowingBinaryOperator; + ConstantRange Result = sub(Other); + + // If an overflow happens for every value pair in these two constant ranges, + // we must return Empty set. In signed case, we get that for free, because we + // get lucky that intersection of sub() with ssub_sat() results in an + // empty set. But for unsigned we must perform the overflow check manually. + + if (NoWrapKind & OBO::NoSignedWrap) + Result = Result.intersectWith(ssub_sat(Other), RangeType); + + if (NoWrapKind & OBO::NoUnsignedWrap) { + if (getUnsignedMax().ult(Other.getUnsignedMin())) + return getEmpty(); // Always overflows. + Result = Result.intersectWith(usub_sat(Other), RangeType); + } + + return Result; +} + ConstantRange ConstantRange::multiply(const ConstantRange &Other) const { // TODO: If either operand is a single element and the multiply is known to @@ -1310,6 +1333,61 @@ ConstantRange ConstantRange::ssub_sat(const ConstantRange &Other) const { return getNonEmpty(std::move(NewL), std::move(NewU)); } +ConstantRange ConstantRange::umul_sat(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + + APInt NewL = getUnsignedMin().umul_sat(Other.getUnsignedMin()); + APInt NewU = getUnsignedMax().umul_sat(Other.getUnsignedMax()) + 1; + return getNonEmpty(std::move(NewL), std::move(NewU)); +} + +ConstantRange ConstantRange::smul_sat(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + + // Because we could be dealing with negative numbers here, the lower bound is + // the smallest of the cartesian product of the lower and upper ranges; + // for example: + // [-1,4) * [-2,3) = min(-1*-2, -1*2, 3*-2, 3*2) = -6. + // Similarly for the upper bound, swapping min for max. + + APInt this_min = getSignedMin().sext(getBitWidth() * 2); + APInt this_max = getSignedMax().sext(getBitWidth() * 2); + APInt Other_min = Other.getSignedMin().sext(getBitWidth() * 2); + APInt Other_max = Other.getSignedMax().sext(getBitWidth() * 2); + + auto L = {this_min * Other_min, this_min * Other_max, this_max * Other_min, + this_max * Other_max}; + auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); }; + + // Note that we wanted to perform signed saturating multiplication, + // so since we performed plain multiplication in twice the bitwidth, + // we need to perform signed saturating truncation. + return getNonEmpty(std::min(L, Compare).truncSSat(getBitWidth()), + std::max(L, Compare).truncSSat(getBitWidth()) + 1); +} + +ConstantRange ConstantRange::ushl_sat(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + + APInt NewL = getUnsignedMin().ushl_sat(Other.getUnsignedMin()); + APInt NewU = getUnsignedMax().ushl_sat(Other.getUnsignedMax()) + 1; + return getNonEmpty(std::move(NewL), std::move(NewU)); +} + +ConstantRange ConstantRange::sshl_sat(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + + APInt Min = getSignedMin(), Max = getSignedMax(); + APInt ShAmtMin = Other.getUnsignedMin(), ShAmtMax = Other.getUnsignedMax(); + APInt NewL = Min.sshl_sat(Min.isNonNegative() ? ShAmtMin : ShAmtMax); + APInt NewU = Max.sshl_sat(Max.isNegative() ? ShAmtMin : ShAmtMax) + 1; + return getNonEmpty(std::move(NewL), std::move(NewU)); +} + ConstantRange ConstantRange::inverse() const { if (isFullSet()) return getEmpty(); diff --git a/contrib/llvm-project/llvm/lib/IR/Constants.cpp b/contrib/llvm-project/llvm/lib/IR/Constants.cpp index f792f01efc1a..054375aab6c3 100644 --- a/contrib/llvm-project/llvm/lib/IR/Constants.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Constants.cpp @@ -31,6 +31,7 @@ #include <algorithm> using namespace llvm; +using namespace PatternMatch; //===----------------------------------------------------------------------===// // Constant Class @@ -149,6 +150,30 @@ bool Constant::isOneValue() const { return false; } +bool Constant::isNotOneValue() const { + // Check for 1 integers + if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) + return !CI->isOneValue(); + + // Check for FP which are bitcasted from 1 integers + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) + return !CFP->getValueAPF().bitcastToAPInt().isOneValue(); + + // Check that vectors don't contain 1 + if (this->getType()->isVectorTy()) { + unsigned NumElts = this->getType()->getVectorNumElements(); + for (unsigned i = 0; i != NumElts; ++i) { + Constant *Elt = this->getAggregateElement(i); + if (!Elt || !Elt->isNotOneValue()) + return false; + } + return true; + } + + // It *may* contain 1, we can't tell. + return false; +} + bool Constant::isMinSignedValue() const { // Check for INT_MIN integers if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) @@ -255,14 +280,18 @@ bool Constant::isElementWiseEqual(Value *Y) const { // Are they fully identical? if (this == Y) return true; - // They may still be identical element-wise (if they have `undef`s). - auto *Cy = dyn_cast<Constant>(Y); - if (!Cy) + + // The input value must be a vector constant with the same type. + Type *Ty = getType(); + if (!isa<Constant>(Y) || !Ty->isVectorTy() || Ty != Y->getType()) return false; - return PatternMatch::match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ, - const_cast<Constant *>(this), - Cy), - PatternMatch::m_One()); + + // They may still be identical element-wise (if they have `undef`s). + // FIXME: This crashes on FP vector constants. + return match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ, + const_cast<Constant *>(this), + cast<Constant>(Y)), + m_One()); } bool Constant::containsUndefElement() const { @@ -595,6 +624,28 @@ void Constant::removeDeadConstantUsers() const { } } +Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) { + assert(C && Replacement && "Expected non-nullptr constant arguments"); + Type *Ty = C->getType(); + if (match(C, m_Undef())) { + assert(Ty == Replacement->getType() && "Expected matching types"); + return Replacement; + } + + // Don't know how to deal with this constant. + if (!Ty->isVectorTy()) + return C; + + unsigned NumElts = Ty->getVectorNumElements(); + SmallVector<Constant *, 32> NewC(NumElts); + for (unsigned i = 0; i != NumElts; ++i) { + Constant *EltC = C->getAggregateElement(i); + assert((!EltC || EltC->getType() == Replacement->getType()) && + "Expected matching types"); + NewC[i] = EltC && match(EltC, m_Undef()) ? Replacement : EltC; + } + return ConstantVector::get(NewC); +} //===----------------------------------------------------------------------===// @@ -1396,24 +1447,41 @@ void ConstantVector::destroyConstantImpl() { getType()->getContext().pImpl->VectorConstants.remove(this); } -Constant *Constant::getSplatValue() const { +Constant *Constant::getSplatValue(bool AllowUndefs) const { assert(this->getType()->isVectorTy() && "Only valid for vectors!"); if (isa<ConstantAggregateZero>(this)) return getNullValue(this->getType()->getVectorElementType()); if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) return CV->getSplatValue(); if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - return CV->getSplatValue(); + return CV->getSplatValue(AllowUndefs); return nullptr; } -Constant *ConstantVector::getSplatValue() const { +Constant *ConstantVector::getSplatValue(bool AllowUndefs) const { // Check out first element. Constant *Elt = getOperand(0); // Then make sure all remaining elements point to the same value. - for (unsigned I = 1, E = getNumOperands(); I < E; ++I) - if (getOperand(I) != Elt) + for (unsigned I = 1, E = getNumOperands(); I < E; ++I) { + Constant *OpC = getOperand(I); + if (OpC == Elt) + continue; + + // Strict mode: any mismatch is not a splat. + if (!AllowUndefs) return nullptr; + + // Allow undefs mode: ignore undefined elements. + if (isa<UndefValue>(OpC)) + continue; + + // If we do not have a defined element yet, use the current operand. + if (isa<UndefValue>(Elt)) + Elt = OpC; + + if (OpC != Elt) + return nullptr; + } return Elt; } @@ -2165,7 +2233,7 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask)) return FC; // Fold a few common cases. - unsigned NElts = Mask->getType()->getVectorNumElements(); + ElementCount NElts = Mask->getType()->getVectorElementCount(); Type *EltTy = V1->getType()->getVectorElementType(); Type *ShufTy = VectorType::get(EltTy, NElts); @@ -2982,7 +3050,7 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) { NewOps, this, From, To, NumUpdated, OperandNo); } -Instruction *ConstantExpr::getAsInstruction() { +Instruction *ConstantExpr::getAsInstruction() const { SmallVector<Value *, 4> ValueOperands(op_begin(), op_end()); ArrayRef<Value*> Ops(ValueOperands); diff --git a/contrib/llvm-project/llvm/lib/IR/ConstantsContext.h b/contrib/llvm-project/llvm/lib/IR/ConstantsContext.h index 1ec9087551f8..f5e2481f3903 100644 --- a/contrib/llvm-project/llvm/lib/IR/ConstantsContext.h +++ b/contrib/llvm-project/llvm/lib/IR/ConstantsContext.h @@ -149,7 +149,7 @@ public: ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) : ConstantExpr(VectorType::get( cast<VectorType>(C1->getType())->getElementType(), - cast<VectorType>(C3->getType())->getNumElements()), + cast<VectorType>(C3->getType())->getElementCount()), Instruction::ShuffleVector, &Op<0>(), 3) { Op<0>() = C1; diff --git a/contrib/llvm-project/llvm/lib/IR/Core.cpp b/contrib/llvm-project/llvm/lib/IR/Core.cpp index a5f46b16e600..04e34a90a9bc 100644 --- a/contrib/llvm-project/llvm/lib/IR/Core.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Core.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -47,7 +48,6 @@ void llvm::initializeCore(PassRegistry &Registry) { initializeDominatorTreeWrapperPassPass(Registry); initializePrintModulePassWrapperPass(Registry); initializePrintFunctionPassWrapperPass(Registry); - initializePrintBasicBlockPassPass(Registry); initializeSafepointIRVerifierPass(Registry); initializeVerifierLegacyPassPass(Registry); } @@ -147,9 +147,9 @@ LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID, // After r362128, byval attributes need to have a type attribute. Provide a // NULL one until a proper API is added for this. return wrap(Attribute::getWithByValType(Ctx, NULL)); - } else { - return wrap(Attribute::get(Ctx, AttrKind, Val)); } + + return wrap(Attribute::get(Ctx, AttrKind, Val)); } unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A) { @@ -3442,15 +3442,16 @@ LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef LLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Len, unsigned Align) { - return wrap(unwrap(B)->CreateMemSet(unwrap(Ptr), unwrap(Val), unwrap(Len), Align)); + return wrap(unwrap(B)->CreateMemSet(unwrap(Ptr), unwrap(Val), unwrap(Len), + MaybeAlign(Align))); } LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size) { - return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), DstAlign, - unwrap(Src), SrcAlign, + return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Src), MaybeAlign(SrcAlign), unwrap(Size))); } @@ -3458,8 +3459,8 @@ LLVMValueRef LLVMBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size) { - return wrap(unwrap(B)->CreateMemMove(unwrap(Dst), DstAlign, - unwrap(Src), SrcAlign, + return wrap(unwrap(B)->CreateMemMove(unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Src), MaybeAlign(SrcAlign), unwrap(Size))); } @@ -3898,6 +3899,11 @@ LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef B, LLVMValueRef AggVal, Index, Name)); } +LLVMValueRef LLVMBuildFreeze(LLVMBuilderRef B, LLVMValueRef Val, + const char *Name) { + return wrap(unwrap(B)->CreateFreeze(unwrap(Val), Name)); +} + LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef B, LLVMValueRef Val, const char *Name) { return wrap(unwrap(B)->CreateIsNull(unwrap(Val), Name)); diff --git a/contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp b/contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp index 5d5671227430..c89f404e4296 100644 --- a/contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp +++ b/contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp @@ -11,15 +11,16 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/DIBuilder.h" -#include "llvm/IR/IRBuilder.h" #include "LLVMContextImpl.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" using namespace llvm; @@ -305,10 +306,11 @@ DIDerivedType *DIBuilder::createReferenceType( DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, DIFile *File, unsigned LineNo, - DIScope *Context) { + DIScope *Context, + uint32_t AlignInBits) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File, - LineNo, getNonCompileUnitScope(Context), Ty, 0, 0, - 0, None, DINode::FlagZero); + LineNo, getNonCompileUnitScope(Context), Ty, 0, + AlignInBits, 0, None, DINode::FlagZero); } DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) { @@ -638,14 +640,15 @@ static void checkGlobalVariableScope(DIScope *Context) { DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, - unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr, - MDNode *Decl, MDTuple *templateParams, uint32_t AlignInBits) { + unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, + bool isDefined, DIExpression *Expr, + MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits) { checkGlobalVariableScope(Context); auto *GV = DIGlobalVariable::getDistinct( VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, true, cast_or_null<DIDerivedType>(Decl), - templateParams, AlignInBits); + LineNumber, Ty, IsLocalToUnit, isDefined, cast_or_null<DIDerivedType>(Decl), + TemplateParams, AlignInBits); if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); @@ -655,14 +658,14 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, - unsigned LineNumber, DIType *Ty, bool isLocalToUnit, MDNode *Decl, - MDTuple *templateParams, uint32_t AlignInBits) { + unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl, + MDTuple *TemplateParams, uint32_t AlignInBits) { checkGlobalVariableScope(Context); return DIGlobalVariable::getTemporary( VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, false, - cast_or_null<DIDerivedType>(Decl), templateParams, AlignInBits) + LineNumber, Ty, IsLocalToUnit, false, + cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits) .release(); } @@ -827,9 +830,9 @@ DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name, DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, - StringRef ISysRoot) { + StringRef SysRoot) { return DIModule::get(VMContext, getNonCompileUnitScope(Scope), Name, - ConfigurationMacros, IncludePath, ISysRoot); + ConfigurationMacros, IncludePath, SysRoot); } DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope, diff --git a/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp b/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp index 5fe7a2e94b6a..94e0740663cc 100644 --- a/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp +++ b/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp @@ -768,13 +768,13 @@ unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const { IntegerType *DataLayout::getIntPtrType(LLVMContext &C, unsigned AddressSpace) const { - return IntegerType::get(C, getIndexSizeInBits(AddressSpace)); + return IntegerType::get(C, getPointerSizeInBits(AddressSpace)); } Type *DataLayout::getIntPtrType(Type *Ty) const { assert(Ty->isPtrOrPtrVectorTy() && "Expected a pointer or pointer vector type."); - unsigned NumBits = getIndexTypeSizeInBits(Ty); + unsigned NumBits = getPointerTypeSizeInBits(Ty); IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); if (VectorType *VecTy = dyn_cast<VectorType>(Ty)) return VectorType::get(IntTy, VecTy->getNumElements()); diff --git a/contrib/llvm-project/llvm/lib/IR/DebugInfo.cpp b/contrib/llvm-project/llvm/lib/IR/DebugInfo.cpp index 1bbe6b85d260..fe8311923109 100644 --- a/contrib/llvm-project/llvm/lib/IR/DebugInfo.cpp +++ b/contrib/llvm-project/llvm/lib/IR/DebugInfo.cpp @@ -782,12 +782,12 @@ LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope, const char *Name, size_t NameLen, const char *ConfigMacros, size_t ConfigMacrosLen, const char *IncludePath, size_t IncludePathLen, - const char *ISysRoot, size_t ISysRootLen) { + const char *SysRoot, size_t SysRootLen) { return wrap(unwrap(Builder)->createModule( unwrapDI<DIScope>(ParentScope), StringRef(Name, NameLen), StringRef(ConfigMacros, ConfigMacrosLen), StringRef(IncludePath, IncludePathLen), - StringRef(ISysRoot, ISysRootLen))); + StringRef(SysRoot, SysRootLen))); } LLVMMetadataRef LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder, @@ -1108,11 +1108,10 @@ LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, - LLVMMetadataRef Scope) { + LLVMMetadataRef Scope, uint32_t AlignInBits) { return wrap(unwrap(Builder)->createTypedef( - unwrapDI<DIType>(Type), {Name, NameLen}, - unwrapDI<DIFile>(File), LineNo, - unwrapDI<DIScope>(Scope))); + unwrapDI<DIType>(Type), {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, + unwrapDI<DIScope>(Scope), AlignInBits)); } LLVMMetadataRef @@ -1290,7 +1289,7 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression( return wrap(unwrap(Builder)->createGlobalVariableExpression( unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen}, unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit, - unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl), + true, unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl), nullptr, AlignInBits)); } diff --git a/contrib/llvm-project/llvm/lib/IR/DebugInfoMetadata.cpp b/contrib/llvm-project/llvm/lib/IR/DebugInfoMetadata.cpp index 94ec3abfa7a2..d3ecd9b0e03d 100644 --- a/contrib/llvm-project/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/contrib/llvm-project/llvm/lib/IR/DebugInfoMetadata.cpp @@ -23,6 +23,9 @@ using namespace llvm; +const DIExpression::FragmentInfo DebugVariable::DefaultFragment = { + std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()}; + DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode) @@ -712,12 +715,12 @@ DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope, DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, - MDString *IncludePath, MDString *ISysRoot, + MDString *IncludePath, MDString *SysRoot, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP( - DIModule, (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)); - Metadata *Ops[] = {Scope, Name, ConfigurationMacros, IncludePath, ISysRoot}; + DIModule, (Scope, Name, ConfigurationMacros, IncludePath, SysRoot)); + Metadata *Ops[] = {Scope, Name, ConfigurationMacros, IncludePath, SysRoot}; DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIModule, Ops); } @@ -929,17 +932,22 @@ bool DIExpression::isValid() const { } bool DIExpression::isImplicit() const { - unsigned N = getNumElements(); - if (isValid() && N > 0) { - switch (getElement(N-1)) { - case dwarf::DW_OP_stack_value: - case dwarf::DW_OP_LLVM_tag_offset: - return true; - case dwarf::DW_OP_LLVM_fragment: - return N > 1 && getElement(N-2) == dwarf::DW_OP_stack_value; - default: break; + if (!isValid()) + return false; + + if (getNumElements() == 0) + return false; + + for (const auto &It : expr_ops()) { + switch (It.getOp()) { + default: + break; + case dwarf::DW_OP_stack_value: + case dwarf::DW_OP_LLVM_tag_offset: + return true; } } + return false; } @@ -1013,6 +1021,8 @@ bool DIExpression::extractIfOffset(int64_t &Offset) const { const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr, unsigned &AddrClass) { + // FIXME: This seems fragile. Nothing that verifies that these elements + // actually map to ops and not operands. const unsigned PatternSize = 4; if (Expr->Elements.size() >= PatternSize && Expr->Elements[PatternSize - 4] == dwarf::DW_OP_constu && @@ -1141,10 +1151,14 @@ Optional<DIExpression *> DIExpression::createFragmentExpression( for (auto Op : Expr->expr_ops()) { switch (Op.getOp()) { default: break; + case dwarf::DW_OP_shr: + case dwarf::DW_OP_shra: + case dwarf::DW_OP_shl: case dwarf::DW_OP_plus: + case dwarf::DW_OP_plus_uconst: case dwarf::DW_OP_minus: - // We can't safely split arithmetic into multiple fragments because we - // can't express carry-over between fragments. + // We can't safely split arithmetic or shift operations into multiple + // fragments because we can't express carry-over between fragments. // // FIXME: We *could* preserve the lowest fragment of a constant offset // operation if the offset fits into SizeInBits. @@ -1182,6 +1196,20 @@ bool DIExpression::isConstant() const { return true; } +DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize, + bool Signed) { + dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned; + DIExpression::ExtOps Ops{{dwarf::DW_OP_LLVM_convert, FromSize, TK, + dwarf::DW_OP_LLVM_convert, ToSize, TK}}; + return Ops; +} + +DIExpression *DIExpression::appendExt(const DIExpression *Expr, + unsigned FromSize, unsigned ToSize, + bool Signed) { + return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed)); +} + DIGlobalVariableExpression * DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression, StorageType Storage, diff --git a/contrib/llvm-project/llvm/lib/IR/Dominators.cpp b/contrib/llvm-project/llvm/lib/IR/Dominators.cpp index 910a41050b94..03dc4da273a3 100644 --- a/contrib/llvm-project/llvm/lib/IR/Dominators.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Dominators.cpp @@ -21,6 +21,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/PassManager.h" +#include "llvm/InitializePasses.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GenericDomTreeConstruction.h" @@ -357,6 +358,11 @@ PreservedAnalyses DominatorTreeVerifierPass::run(Function &F, //===----------------------------------------------------------------------===// char DominatorTreeWrapperPass::ID = 0; + +DominatorTreeWrapperPass::DominatorTreeWrapperPass() : FunctionPass(ID) { + initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry()); +} + INITIALIZE_PASS(DominatorTreeWrapperPass, "domtree", "Dominator Tree Construction", true, true) diff --git a/contrib/llvm-project/llvm/lib/IR/FPEnv.cpp b/contrib/llvm-project/llvm/lib/IR/FPEnv.cpp new file mode 100644 index 000000000000..008852658232 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/IR/FPEnv.cpp @@ -0,0 +1,78 @@ +//===-- FPEnv.cpp ---- FP Environment -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// @file +/// This file contains the implementations of entities that describe floating +/// point environment. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/StringSwitch.h" +#include "llvm/IR/FPEnv.h" + +namespace llvm { + +Optional<fp::RoundingMode> StrToRoundingMode(StringRef RoundingArg) { + // For dynamic rounding mode, we use round to nearest but we will set the + // 'exact' SDNodeFlag so that the value will not be rounded. + return StringSwitch<Optional<fp::RoundingMode>>(RoundingArg) + .Case("round.dynamic", fp::rmDynamic) + .Case("round.tonearest", fp::rmToNearest) + .Case("round.downward", fp::rmDownward) + .Case("round.upward", fp::rmUpward) + .Case("round.towardzero", fp::rmTowardZero) + .Default(None); +} + +Optional<StringRef> RoundingModeToStr(fp::RoundingMode UseRounding) { + Optional<StringRef> RoundingStr = None; + switch (UseRounding) { + case fp::rmDynamic: + RoundingStr = "round.dynamic"; + break; + case fp::rmToNearest: + RoundingStr = "round.tonearest"; + break; + case fp::rmDownward: + RoundingStr = "round.downward"; + break; + case fp::rmUpward: + RoundingStr = "round.upward"; + break; + case fp::rmTowardZero: + RoundingStr = "round.towardzero"; + break; + } + return RoundingStr; +} + +Optional<fp::ExceptionBehavior> StrToExceptionBehavior(StringRef ExceptionArg) { + return StringSwitch<Optional<fp::ExceptionBehavior>>(ExceptionArg) + .Case("fpexcept.ignore", fp::ebIgnore) + .Case("fpexcept.maytrap", fp::ebMayTrap) + .Case("fpexcept.strict", fp::ebStrict) + .Default(None); +} + +Optional<StringRef> ExceptionBehaviorToStr(fp::ExceptionBehavior UseExcept) { + Optional<StringRef> ExceptStr = None; + switch (UseExcept) { + case fp::ebStrict: + ExceptStr = "fpexcept.strict"; + break; + case fp::ebIgnore: + ExceptStr = "fpexcept.ignore"; + break; + case fp::ebMayTrap: + ExceptStr = "fpexcept.maytrap"; + break; + } + return ExceptStr; +} + +}
\ No newline at end of file diff --git a/contrib/llvm-project/llvm/lib/IR/Function.cpp b/contrib/llvm-project/llvm/lib/IR/Function.cpp index 3f70d2c904e5..54612250b0d6 100644 --- a/contrib/llvm-project/llvm/lib/IR/Function.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Function.cpp @@ -30,8 +30,21 @@ #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsAMDGPU.h" +#include "llvm/IR/IntrinsicsARM.h" +#include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsHexagon.h" +#include "llvm/IR/IntrinsicsMips.h" +#include "llvm/IR/IntrinsicsNVPTX.h" +#include "llvm/IR/IntrinsicsPowerPC.h" +#include "llvm/IR/IntrinsicsR600.h" +#include "llvm/IR/IntrinsicsRISCV.h" +#include "llvm/IR/IntrinsicsS390.h" +#include "llvm/IR/IntrinsicsWebAssembly.h" +#include "llvm/IR/IntrinsicsX86.h" +#include "llvm/IR/IntrinsicsXCore.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" @@ -113,6 +126,11 @@ unsigned Argument::getParamAlignment() const { return getParent()->getParamAlignment(getArgNo()); } +MaybeAlign Argument::getParamAlign() const { + assert(getType()->isPointerTy() && "Only pointers have alignments"); + return getParent()->getParamAlign(getArgNo()); +} + Type *Argument::getParamByValType() const { assert(getType()->isPointerTy() && "Only pointers have byval types"); return getParent()->getParamByValType(getArgNo()); @@ -560,7 +578,8 @@ Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) { const auto MatchSize = strlen(NameTable[Idx]); assert(Name.size() >= MatchSize && "Expected either exact or prefix match"); bool IsExactMatch = Name.size() == MatchSize; - return IsExactMatch || isOverloaded(ID) ? ID : Intrinsic::not_intrinsic; + return IsExactMatch || Intrinsic::isOverloaded(ID) ? ID + : Intrinsic::not_intrinsic; } void Function::recalculateIntrinsicID() { @@ -639,7 +658,7 @@ static std::string getMangledTypeStr(Type* Ty) { StringRef Intrinsic::getName(ID id) { assert(id < num_intrinsics && "Invalid intrinsic ID!"); - assert(!isOverloaded(id) && + assert(!Intrinsic::isOverloaded(id) && "This version of getName does not support overloading"); return IntrinsicNameTable[id]; } @@ -1533,6 +1552,11 @@ void Function::setEntryCount(ProfileCount Count, auto PrevCount = getEntryCount(); assert(!PrevCount.hasValue() || PrevCount.getType() == Count.getType()); #endif + + auto ImportGUIDs = getImportGUIDs(); + if (S == nullptr && ImportGUIDs.size()) + S = &ImportGUIDs; + MDBuilder MDB(getContext()); setMetadata( LLVMContext::MD_prof, diff --git a/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp b/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp index b782012e9731..30b558a655cb 100644 --- a/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp +++ b/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp @@ -96,10 +96,10 @@ static InvokeInst *createInvokeHelper(Function *Invokee, BasicBlock *NormalDest, return II; } -CallInst *IRBuilderBase:: -CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, - bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag, - MDNode *NoAliasTag) { +CallInst *IRBuilderBase::CreateMemSet(Value *Ptr, Value *Val, Value *Size, + MaybeAlign Align, bool isVolatile, + MDNode *TBAATag, MDNode *ScopeTag, + MDNode *NoAliasTag) { Ptr = getCastedInt8PtrValue(Ptr); Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)}; Type *Tys[] = { Ptr->getType(), Size->getType() }; @@ -108,8 +108,8 @@ CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, CallInst *CI = createCallHelper(TheFn, Ops, this); - if (Align > 0) - cast<MemSetInst>(CI)->setDestAlignment(Align); + if (Align) + cast<MemSetInst>(CI)->setDestAlignment(Align->value()); // Set the TBAA info if present. if (TBAATag) @@ -125,10 +125,8 @@ CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, } CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet( - Value *Ptr, Value *Val, Value *Size, unsigned Align, uint32_t ElementSize, + Value *Ptr, Value *Val, Value *Size, Align Alignment, uint32_t ElementSize, MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) { - assert(Align >= ElementSize && - "Pointer alignment must be at least element size."); Ptr = getCastedInt8PtrValue(Ptr); Value *Ops[] = {Ptr, Val, Size, getInt32(ElementSize)}; @@ -139,7 +137,7 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet( CallInst *CI = createCallHelper(TheFn, Ops, this); - cast<AtomicMemSetInst>(CI)->setDestAlignment(Align); + cast<AtomicMemSetInst>(CI)->setDestAlignment(Alignment); // Set the TBAA info if present. if (TBAATag) @@ -154,12 +152,21 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet( return CI; } -CallInst *IRBuilderBase:: -CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, - Value *Size, bool isVolatile, MDNode *TBAATag, - MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) { - assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2"); - assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2"); +CallInst *IRBuilderBase::CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, + unsigned SrcAlign, Value *Size, + bool isVolatile, MDNode *TBAATag, + MDNode *TBAAStructTag, MDNode *ScopeTag, + MDNode *NoAliasTag) { + return CreateMemCpy(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign), + Size, isVolatile, TBAATag, TBAAStructTag, ScopeTag, + NoAliasTag); +} + +CallInst *IRBuilderBase::CreateMemCpy(Value *Dst, MaybeAlign DstAlign, + Value *Src, MaybeAlign SrcAlign, + Value *Size, bool isVolatile, + MDNode *TBAATag, MDNode *TBAAStructTag, + MDNode *ScopeTag, MDNode *NoAliasTag) { Dst = getCastedInt8PtrValue(Dst); Src = getCastedInt8PtrValue(Src); @@ -171,10 +178,10 @@ CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, CallInst *CI = createCallHelper(TheFn, Ops, this); auto* MCI = cast<MemCpyInst>(CI); - if (DstAlign > 0) - MCI->setDestAlignment(DstAlign); - if (SrcAlign > 0) - MCI->setSourceAlignment(SrcAlign); + if (DstAlign) + MCI->setDestAlignment(*DstAlign); + if (SrcAlign) + MCI->setSourceAlignment(*SrcAlign); // Set the TBAA info if present. if (TBAATag) @@ -234,12 +241,11 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy( return CI; } -CallInst *IRBuilderBase:: -CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, - Value *Size, bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag, - MDNode *NoAliasTag) { - assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2"); - assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2"); +CallInst *IRBuilderBase::CreateMemMove(Value *Dst, MaybeAlign DstAlign, + Value *Src, MaybeAlign SrcAlign, + Value *Size, bool isVolatile, + MDNode *TBAATag, MDNode *ScopeTag, + MDNode *NoAliasTag) { Dst = getCastedInt8PtrValue(Dst); Src = getCastedInt8PtrValue(Src); @@ -251,10 +257,10 @@ CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, CallInst *CI = createCallHelper(TheFn, Ops, this); auto *MMI = cast<MemMoveInst>(CI); - if (DstAlign > 0) - MMI->setDestAlignment(DstAlign); - if (SrcAlign > 0) - MMI->setSourceAlignment(SrcAlign); + if (DstAlign) + MMI->setDestAlignment(*DstAlign); + if (SrcAlign) + MMI->setSourceAlignment(*SrcAlign); // Set the TBAA info if present. if (TBAATag) diff --git a/contrib/llvm-project/llvm/lib/IR/IRPrintingPasses.cpp b/contrib/llvm-project/llvm/lib/IR/IRPrintingPasses.cpp index 953cf9410162..03657ff8d9d4 100644 --- a/contrib/llvm-project/llvm/lib/IR/IRPrintingPasses.cpp +++ b/contrib/llvm-project/llvm/lib/IR/IRPrintingPasses.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -56,7 +57,7 @@ PreservedAnalyses PrintFunctionPass::run(Function &F, if (forcePrintModuleIR()) OS << Banner << " (function: " << F.getName() << ")\n" << *F.getParent(); else - OS << Banner << static_cast<Value &>(F); + OS << Banner << '\n' << static_cast<Value &>(F); } return PreservedAnalyses::all(); } @@ -109,28 +110,6 @@ public: StringRef getPassName() const override { return "Print Function IR"; } }; -class PrintBasicBlockPass : public BasicBlockPass { - raw_ostream &Out; - std::string Banner; - -public: - static char ID; - PrintBasicBlockPass() : BasicBlockPass(ID), Out(dbgs()) {} - PrintBasicBlockPass(raw_ostream &Out, const std::string &Banner) - : BasicBlockPass(ID), Out(Out), Banner(Banner) {} - - bool runOnBasicBlock(BasicBlock &BB) override { - Out << Banner << BB; - return false; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesAll(); - } - - StringRef getPassName() const override { return "Print BasicBlock IR"; } -}; - } char PrintModulePassWrapper::ID = 0; @@ -139,9 +118,6 @@ INITIALIZE_PASS(PrintModulePassWrapper, "print-module", char PrintFunctionPassWrapper::ID = 0; INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function", "Print function to stderr", false, true) -char PrintBasicBlockPass::ID = 0; -INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false, - true) ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, const std::string &Banner, @@ -154,15 +130,9 @@ FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, return new PrintFunctionPassWrapper(OS, Banner); } -BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream &OS, - const std::string &Banner) { - return new PrintBasicBlockPass(OS, Banner); -} - bool llvm::isIRPrintingPass(Pass *P) { const char *PID = (const char*)P->getPassID(); - return (PID == &PrintModulePassWrapper::ID) - || (PID == &PrintFunctionPassWrapper::ID) - || (PID == &PrintBasicBlockPass::ID); + return (PID == &PrintModulePassWrapper::ID) || + (PID == &PrintFunctionPassWrapper::ID); } diff --git a/contrib/llvm-project/llvm/lib/IR/Instruction.cpp b/contrib/llvm-project/llvm/lib/IR/Instruction.cpp index b157c7bb34bf..7da169712896 100644 --- a/contrib/llvm-project/llvm/lib/IR/Instruction.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Instruction.cpp @@ -368,6 +368,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case InsertValue: return "insertvalue"; case LandingPad: return "landingpad"; case CleanupPad: return "cleanuppad"; + case Freeze: return "freeze"; default: return "<Invalid operator> "; } diff --git a/contrib/llvm-project/llvm/lib/IR/Instructions.cpp b/contrib/llvm-project/llvm/lib/IR/Instructions.cpp index 245c7628b08e..c264277fa53c 100644 --- a/contrib/llvm-project/llvm/lib/IR/Instructions.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Instructions.cpp @@ -1217,30 +1217,31 @@ AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, Instruction *InsertBefore) - : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/0, Name, InsertBefore) {} + : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/None, Name, InsertBefore) { +} AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, BasicBlock *InsertAtEnd) - : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/0, Name, InsertAtEnd) {} + : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/None, Name, InsertAtEnd) {} AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, - unsigned Align, const Twine &Name, + MaybeAlign Align, const Twine &Name, Instruction *InsertBefore) - : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, - getAISize(Ty->getContext(), ArraySize), InsertBefore), - AllocatedType(Ty) { + : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, + getAISize(Ty->getContext(), ArraySize), InsertBefore), + AllocatedType(Ty) { setAlignment(MaybeAlign(Align)); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); } AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, - unsigned Align, const Twine &Name, + MaybeAlign Align, const Twine &Name, BasicBlock *InsertAtEnd) - : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, - getAISize(Ty->getContext(), ArraySize), InsertAtEnd), + : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, + getAISize(Ty->getContext(), ArraySize), InsertAtEnd), AllocatedType(Ty) { - setAlignment(MaybeAlign(Align)); + setAlignment(Align); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); } @@ -1341,11 +1342,7 @@ void LoadInst::setAlignment(MaybeAlign Align) { "Alignment is greater than MaximumAlignment!"); setInstructionSubclassData((getSubclassDataFromInstruction() & ~(31 << 1)) | (encode(Align) << 1)); - if (Align) - assert(getAlignment() == Align->value() && - "Alignment representation error!"); - else - assert(getAlignment() == 0 && "Alignment representation error!"); + assert(getAlign() == Align && "Alignment representation error!"); } //===----------------------------------------------------------------------===// @@ -1415,16 +1412,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, MaybeAlign Align, AssertOK(); } -void StoreInst::setAlignment(MaybeAlign Align) { - assert((!Align || *Align <= MaximumAlignment) && +void StoreInst::setAlignment(MaybeAlign Alignment) { + assert((!Alignment || *Alignment <= MaximumAlignment) && "Alignment is greater than MaximumAlignment!"); setInstructionSubclassData((getSubclassDataFromInstruction() & ~(31 << 1)) | - (encode(Align) << 1)); - if (Align) - assert(getAlignment() == Align->value() && - "Alignment representation error!"); - else - assert(getAlignment() == 0 && "Alignment representation error!"); + (encode(Alignment) << 1)); + assert(getAlign() == Alignment && "Alignment representation error!"); } //===----------------------------------------------------------------------===// @@ -2047,7 +2040,7 @@ bool ShuffleVectorInst::isExtractSubvectorMask(ArrayRef<int> Mask, SubIndex = Offset; } - if (0 <= SubIndex) { + if (0 <= SubIndex && SubIndex + (int)Mask.size() <= NumSrcElts) { Index = SubIndex; return true; } @@ -4091,6 +4084,22 @@ void IndirectBrInst::removeDestination(unsigned idx) { } //===----------------------------------------------------------------------===// +// FreezeInst Implementation +//===----------------------------------------------------------------------===// + +FreezeInst::FreezeInst(Value *S, + const Twine &Name, Instruction *InsertBefore) + : UnaryInstruction(S->getType(), Freeze, S, InsertBefore) { + setName(Name); +} + +FreezeInst::FreezeInst(Value *S, + const Twine &Name, BasicBlock *InsertAtEnd) + : UnaryInstruction(S->getType(), Freeze, S, InsertAtEnd) { + setName(Name); +} + +//===----------------------------------------------------------------------===// // cloneImpl() implementations //===----------------------------------------------------------------------===// @@ -4126,9 +4135,9 @@ InsertValueInst *InsertValueInst::cloneImpl() const { } AllocaInst *AllocaInst::cloneImpl() const { - AllocaInst *Result = new AllocaInst(getAllocatedType(), - getType()->getAddressSpace(), - (Value *)getOperand(0), getAlignment()); + AllocaInst *Result = + new AllocaInst(getAllocatedType(), getType()->getAddressSpace(), + (Value *)getOperand(0), MaybeAlign(getAlignment())); Result->setUsedWithInAlloca(isUsedWithInAlloca()); Result->setSwiftError(isSwiftError()); return Result; @@ -4306,3 +4315,7 @@ UnreachableInst *UnreachableInst::cloneImpl() const { LLVMContext &Context = getContext(); return new UnreachableInst(Context); } + +FreezeInst *FreezeInst::cloneImpl() const { + return new FreezeInst(getOperand(0)); +} diff --git a/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp b/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp index 26ed46a9cd91..b23742b83c12 100644 --- a/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp +++ b/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp @@ -102,8 +102,7 @@ Value *InstrProfIncrementInst::getStep() const { return ConstantInt::get(Type::getInt64Ty(Context), 1); } -Optional<ConstrainedFPIntrinsic::RoundingMode> -ConstrainedFPIntrinsic::getRoundingMode() const { +Optional<fp::RoundingMode> ConstrainedFPIntrinsic::getRoundingMode() const { unsigned NumOperands = getNumArgOperands(); Metadata *MD = cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata(); @@ -112,43 +111,7 @@ ConstrainedFPIntrinsic::getRoundingMode() const { return StrToRoundingMode(cast<MDString>(MD)->getString()); } -Optional<ConstrainedFPIntrinsic::RoundingMode> -ConstrainedFPIntrinsic::StrToRoundingMode(StringRef RoundingArg) { - // For dynamic rounding mode, we use round to nearest but we will set the - // 'exact' SDNodeFlag so that the value will not be rounded. - return StringSwitch<Optional<RoundingMode>>(RoundingArg) - .Case("round.dynamic", rmDynamic) - .Case("round.tonearest", rmToNearest) - .Case("round.downward", rmDownward) - .Case("round.upward", rmUpward) - .Case("round.towardzero", rmTowardZero) - .Default(None); -} - -Optional<StringRef> -ConstrainedFPIntrinsic::RoundingModeToStr(RoundingMode UseRounding) { - Optional<StringRef> RoundingStr = None; - switch (UseRounding) { - case ConstrainedFPIntrinsic::rmDynamic: - RoundingStr = "round.dynamic"; - break; - case ConstrainedFPIntrinsic::rmToNearest: - RoundingStr = "round.tonearest"; - break; - case ConstrainedFPIntrinsic::rmDownward: - RoundingStr = "round.downward"; - break; - case ConstrainedFPIntrinsic::rmUpward: - RoundingStr = "round.upward"; - break; - case ConstrainedFPIntrinsic::rmTowardZero: - RoundingStr = "round.towardzero"; - break; - } - return RoundingStr; -} - -Optional<ConstrainedFPIntrinsic::ExceptionBehavior> +Optional<fp::ExceptionBehavior> ConstrainedFPIntrinsic::getExceptionBehavior() const { unsigned NumOperands = getNumArgOperands(); Metadata *MD = @@ -158,59 +121,38 @@ ConstrainedFPIntrinsic::getExceptionBehavior() const { return StrToExceptionBehavior(cast<MDString>(MD)->getString()); } -Optional<ConstrainedFPIntrinsic::ExceptionBehavior> -ConstrainedFPIntrinsic::StrToExceptionBehavior(StringRef ExceptionArg) { - return StringSwitch<Optional<ExceptionBehavior>>(ExceptionArg) - .Case("fpexcept.ignore", ebIgnore) - .Case("fpexcept.maytrap", ebMayTrap) - .Case("fpexcept.strict", ebStrict) - .Default(None); -} - -Optional<StringRef> -ConstrainedFPIntrinsic::ExceptionBehaviorToStr(ExceptionBehavior UseExcept) { - Optional<StringRef> ExceptStr = None; - switch (UseExcept) { - case ConstrainedFPIntrinsic::ebStrict: - ExceptStr = "fpexcept.strict"; - break; - case ConstrainedFPIntrinsic::ebIgnore: - ExceptStr = "fpexcept.ignore"; - break; - case ConstrainedFPIntrinsic::ebMayTrap: - ExceptStr = "fpexcept.maytrap"; - break; - } - return ExceptStr; +FCmpInst::Predicate +ConstrainedFPCmpIntrinsic::getPredicate() const { + Metadata *MD = + cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); + if (!MD || !isa<MDString>(MD)) + return FCmpInst::BAD_FCMP_PREDICATE; + return StringSwitch<FCmpInst::Predicate>(cast<MDString>(MD)->getString()) + .Case("oeq", FCmpInst::FCMP_OEQ) + .Case("ogt", FCmpInst::FCMP_OGT) + .Case("oge", FCmpInst::FCMP_OGE) + .Case("olt", FCmpInst::FCMP_OLT) + .Case("ole", FCmpInst::FCMP_OLE) + .Case("one", FCmpInst::FCMP_ONE) + .Case("ord", FCmpInst::FCMP_ORD) + .Case("uno", FCmpInst::FCMP_UNO) + .Case("ueq", FCmpInst::FCMP_UEQ) + .Case("ugt", FCmpInst::FCMP_UGT) + .Case("uge", FCmpInst::FCMP_UGE) + .Case("ult", FCmpInst::FCMP_ULT) + .Case("ule", FCmpInst::FCMP_ULE) + .Case("une", FCmpInst::FCMP_UNE) + .Default(FCmpInst::BAD_FCMP_PREDICATE); } bool ConstrainedFPIntrinsic::isUnaryOp() const { switch (getIntrinsicID()) { default: return false; - case Intrinsic::experimental_constrained_fptosi: - case Intrinsic::experimental_constrained_fptoui: - case Intrinsic::experimental_constrained_fptrunc: - case Intrinsic::experimental_constrained_fpext: - 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_lrint: - case Intrinsic::experimental_constrained_llrint: - case Intrinsic::experimental_constrained_rint: - case Intrinsic::experimental_constrained_nearbyint: - case Intrinsic::experimental_constrained_ceil: - case Intrinsic::experimental_constrained_floor: - case Intrinsic::experimental_constrained_lround: - case Intrinsic::experimental_constrained_llround: - case Intrinsic::experimental_constrained_round: - case Intrinsic::experimental_constrained_trunc: - return true; +#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \ + case Intrinsic::INTRINSIC: \ + return NARG == 1; +#include "llvm/IR/ConstrainedOps.def" } } @@ -218,8 +160,21 @@ bool ConstrainedFPIntrinsic::isTernaryOp() const { switch (getIntrinsicID()) { default: return false; - case Intrinsic::experimental_constrained_fma: - return true; +#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \ + case Intrinsic::INTRINSIC: \ + return NARG == 3; +#include "llvm/IR/ConstrainedOps.def" + } +} + +bool ConstrainedFPIntrinsic::classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { +#define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC, DAGN) \ + case Intrinsic::INTRINSIC: +#include "llvm/IR/ConstrainedOps.def" + return true; + default: + return false; } } diff --git a/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp b/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp index 5e8772186a2a..cb13b27aa50f 100644 --- a/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp +++ b/contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp @@ -62,6 +62,11 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { "gc-transition operand bundle id drifted!"); (void)GCTransitionEntry; + auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget"); + assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget && + "cfguardtarget operand bundle id drifted!"); + (void)CFGuardTargetEntry; + SyncScope::ID SingleThreadSSID = pImpl->getOrInsertSyncScopeID("singlethread"); assert(SingleThreadSSID == SyncScope::SingleThread && diff --git a/contrib/llvm-project/llvm/lib/IR/LLVMContextImpl.h b/contrib/llvm-project/llvm/lib/IR/LLVMContextImpl.h index 78cf707e0e74..6f5d5752b38d 100644 --- a/contrib/llvm-project/llvm/lib/IR/LLVMContextImpl.h +++ b/contrib/llvm-project/llvm/lib/IR/LLVMContextImpl.h @@ -819,27 +819,27 @@ template <> struct MDNodeKeyImpl<DIModule> { MDString *Name; MDString *ConfigurationMacros; MDString *IncludePath; - MDString *ISysRoot; + MDString *SysRoot; MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, - MDString *IncludePath, MDString *ISysRoot) + MDString *IncludePath, MDString *SysRoot) : Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros), - IncludePath(IncludePath), ISysRoot(ISysRoot) {} + IncludePath(IncludePath), SysRoot(SysRoot) {} MDNodeKeyImpl(const DIModule *N) : Scope(N->getRawScope()), Name(N->getRawName()), ConfigurationMacros(N->getRawConfigurationMacros()), - IncludePath(N->getRawIncludePath()), ISysRoot(N->getRawISysRoot()) {} + IncludePath(N->getRawIncludePath()), SysRoot(N->getRawSysRoot()) {} bool isKeyOf(const DIModule *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && ConfigurationMacros == RHS->getRawConfigurationMacros() && IncludePath == RHS->getRawIncludePath() && - ISysRoot == RHS->getRawISysRoot(); + SysRoot == RHS->getRawSysRoot(); } unsigned getHashValue() const { return hash_combine(Scope, Name, - ConfigurationMacros, IncludePath, ISysRoot); + ConfigurationMacros, IncludePath, SysRoot); } }; diff --git a/contrib/llvm-project/llvm/lib/IR/LegacyPassManager.cpp b/contrib/llvm-project/llvm/lib/IR/LegacyPassManager.cpp index 3a03c493100b..90239bb76298 100644 --- a/contrib/llvm-project/llvm/lib/IR/LegacyPassManager.cpp +++ b/contrib/llvm-project/llvm/lib/IR/LegacyPassManager.cpp @@ -314,64 +314,6 @@ void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { OS << "'\n"; } - -namespace { -//===----------------------------------------------------------------------===// -// BBPassManager -// -/// BBPassManager manages BasicBlockPass. It batches all the -/// pass together and sequence them to process one basic block before -/// processing next basic block. -class BBPassManager : public PMDataManager, public FunctionPass { - -public: - static char ID; - explicit BBPassManager() - : PMDataManager(), FunctionPass(ID) {} - - /// Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the function, and if so, return true. - bool runOnFunction(Function &F) override; - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const override { - Info.setPreservesAll(); - } - - bool doInitialization(Module &M) override; - bool doInitialization(Function &F); - bool doFinalization(Module &M) override; - bool doFinalization(Function &F); - - PMDataManager *getAsPMDataManager() override { return this; } - Pass *getAsPass() override { return this; } - - StringRef getPassName() const override { return "BasicBlock Pass Manager"; } - - // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) override { - dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - BP->dumpPassStructure(Offset + 1); - dumpLastUses(BP, Offset+1); - } - } - - BasicBlockPass *getContainedPass(unsigned N) { - assert(N < PassVector.size() && "Pass number out of range!"); - BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]); - return BP; - } - - PassManagerType getPassManagerType() const override { - return PMT_BasicBlockPassManager; - } -}; - -char BBPassManager::ID = 0; -} // End anonymous namespace - namespace llvm { namespace legacy { //===----------------------------------------------------------------------===// @@ -434,6 +376,11 @@ public: FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]); return FP; } + + void dumpPassStructure(unsigned Offset) override { + for (unsigned I = 0; I < getNumContainedManagers(); ++I) + getContainedManager(I)->dumpPassStructure(Offset); + } }; void FunctionPassManagerImpl::anchor() {} @@ -1249,9 +1196,6 @@ void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, break; } switch (S2) { - case ON_BASICBLOCK_MSG: - dbgs() << "' on BasicBlock '" << Msg << "'...\n"; - break; case ON_FUNCTION_MSG: dbgs() << "' on Function '" << Msg << "'...\n"; break; @@ -1368,117 +1312,6 @@ Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, } //===----------------------------------------------------------------------===// -// BBPassManager implementation - -/// Execute all of the passes scheduled for execution by invoking -/// runOnBasicBlock method. Keep track of whether any of the passes modifies -/// the function, and if so, return true. -bool BBPassManager::runOnFunction(Function &F) { - if (F.isDeclaration()) - return false; - - bool Changed = doInitialization(F); - Module &M = *F.getParent(); - - unsigned InstrCount, BBSize = 0; - StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount; - bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); - if (EmitICRemark) - InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount); - - for (BasicBlock &BB : F) { - // Collect the initial size of the basic block. - if (EmitICRemark) - BBSize = BB.size(); - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, BB.getName()); - dumpRequiredSet(BP); - - initializeAnalysisImpl(BP); - - { - // If the pass crashes, remember this. - PassManagerPrettyStackEntry X(BP, BB); - TimeRegion PassTimer(getPassTimer(BP)); - LocalChanged |= BP->runOnBasicBlock(BB); - if (EmitICRemark) { - unsigned NewSize = BB.size(); - // Update the size of the basic block, emit a remark, and update the - // size of the module. - if (NewSize != BBSize) { - int64_t Delta = - static_cast<int64_t>(NewSize) - static_cast<int64_t>(BBSize); - emitInstrCountChangedRemark(BP, M, Delta, InstrCount, - FunctionToInstrCount, &F); - InstrCount = static_cast<int64_t>(InstrCount) + Delta; - BBSize = NewSize; - } - } - } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, - BB.getName()); - dumpPreservedSet(BP); - dumpUsedSet(BP); - - verifyPreservedAnalysis(BP); - removeNotPreservedAnalysis(BP); - recordAvailableAnalysis(BP); - removeDeadPasses(BP, BB.getName(), ON_BASICBLOCK_MSG); - } - } - - return doFinalization(F) || Changed; -} - -// Implement doInitialization and doFinalization -bool BBPassManager::doInitialization(Module &M) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - return Changed; -} - -bool BBPassManager::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - return Changed; -} - -bool BBPassManager::doInitialization(Function &F) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - Changed |= BP->doInitialization(F); - } - - return Changed; -} - -bool BBPassManager::doFinalization(Function &F) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - Changed |= BP->doFinalization(F); - } - - return Changed; -} - - -//===----------------------------------------------------------------------===// // FunctionPassManager implementation /// Create new Function pass manager @@ -1793,13 +1626,12 @@ MPPassManager::runOnModule(Module &M) { /// RequiredPass is run on the fly by Pass Manager when P requests it /// through getAnalysis interface. void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { + assert(RequiredPass && "No required pass?"); assert(P->getPotentialPassManagerType() == PMT_ModulePassManager && "Unable to handle Pass that requires lower level Analysis pass"); assert((P->getPotentialPassManagerType() < RequiredPass->getPotentialPassManagerType()) && "Unable to handle Pass that requires lower level Analysis pass"); - if (!RequiredPass) - return; FunctionPassManagerImpl *FPP = OnTheFlyManagers[P]; if (!FPP) { @@ -1944,114 +1776,42 @@ LLVM_DUMP_METHOD void PMStack::dump() const { void ModulePass::assignPassManager(PMStack &PMS, PassManagerType PreferredType) { // Find Module Pass Manager - while (!PMS.empty()) { - PassManagerType TopPMType = PMS.top()->getPassManagerType(); - if (TopPMType == PreferredType) - break; // We found desired pass manager - else if (TopPMType > PMT_ModulePassManager) - PMS.pop(); // Pop children pass managers - else - break; - } - assert(!PMS.empty() && "Unable to find appropriate Pass Manager"); + PassManagerType T; + while ((T = PMS.top()->getPassManagerType()) > PMT_ModulePassManager && + T != PreferredType) + PMS.pop(); PMS.top()->add(this); } /// Find appropriate Function Pass Manager or Call Graph Pass Manager /// in the PM Stack and add self into that manager. void FunctionPass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - + PassManagerType /*PreferredType*/) { // Find Function Pass Manager - while (!PMS.empty()) { - if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) - PMS.pop(); - else - break; - } + PMDataManager *PM; + while (PM = PMS.top(), PM->getPassManagerType() > PMT_FunctionPassManager) + PMS.pop(); // Create new Function Pass Manager if needed. - FPPassManager *FPP; - if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) { - FPP = (FPPassManager *)PMS.top(); - } else { - assert(!PMS.empty() && "Unable to create Function Pass Manager"); - PMDataManager *PMD = PMS.top(); - + if (PM->getPassManagerType() != PMT_FunctionPassManager) { // [1] Create new Function Pass Manager - FPP = new FPPassManager(); + auto *FPP = new FPPassManager; FPP->populateInheritedAnalysis(PMS); // [2] Set up new manager's top level manager - PMTopLevelManager *TPM = PMD->getTopLevelManager(); - TPM->addIndirectPassManager(FPP); + PM->getTopLevelManager()->addIndirectPassManager(FPP); // [3] Assign manager to manage this new manager. This may create // and push new managers into PMS - FPP->assignPassManager(PMS, PMD->getPassManagerType()); + FPP->assignPassManager(PMS, PM->getPassManagerType()); // [4] Push new manager into PMS PMS.push(FPP); + PM = FPP; } // Assign FPP as the manager of this pass. - FPP->add(this); -} - -void BasicBlockPass::preparePassManager(PMStack &PMS) { - // Find BBPassManager - while (!PMS.empty() && - PMS.top()->getPassManagerType() > PMT_BasicBlockPassManager) - PMS.pop(); - - // If this pass is destroying high level information that is used - // by other passes that are managed by BBPM then do not insert - // this pass in current BBPM. Use new BBPassManager. - if (PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager && - !PMS.top()->preserveHigherLevelAnalysis(this)) - PMS.pop(); -} - -/// Find appropriate Basic Pass Manager or Call Graph Pass Manager -/// in the PM Stack and add self into that manager. -void BasicBlockPass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - while (!PMS.empty() && - PMS.top()->getPassManagerType() > PMT_BasicBlockPassManager) - PMS.pop(); - - BBPassManager *BBP; - - // Basic Pass Manager is a leaf pass manager. It does not handle - // any other pass manager. - if (!PMS.empty() && - PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) { - BBP = (BBPassManager *)PMS.top(); - } else { - // If leaf manager is not Basic Block Pass manager then create new - // basic Block Pass manager. - assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager"); - PMDataManager *PMD = PMS.top(); - - // [1] Create new Basic Block Manager - BBP = new BBPassManager(); - BBP->populateInheritedAnalysis(PMS); - - // [2] Set up new manager's top level manager - // Basic Block Pass Manager does not live by itself - PMTopLevelManager *TPM = PMD->getTopLevelManager(); - TPM->addIndirectPassManager(BBP); - - // [3] Assign manager to manage this new manager. This may create - // and push new managers into PMS - BBP->assignPassManager(PMS, PreferredType); - - // [4] Push new manager into PMS - PMS.push(BBP); - } - - // Assign BBP as the manager of this pass. - BBP->add(this); + PM->add(this); } PassManagerBase::~PassManagerBase() {} diff --git a/contrib/llvm-project/llvm/lib/IR/Metadata.cpp b/contrib/llvm-project/llvm/lib/IR/Metadata.cpp index 62c2aa86f3b0..de092894d30c 100644 --- a/contrib/llvm-project/llvm/lib/IR/Metadata.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Metadata.cpp @@ -489,7 +489,9 @@ void *MDNode::operator new(size_t Size, unsigned NumOps) { return Ptr; } -void MDNode::operator delete(void *Mem) { +// Repress memory sanitization, due to use-after-destroy by operator +// delete. Bug report 24578 identifies this issue. +LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE void MDNode::operator delete(void *Mem) { MDNode *N = static_cast<MDNode *>(Mem); size_t OpSize = N->NumOperands * sizeof(MDOperand); OpSize = alignTo(OpSize, alignof(uint64_t)); @@ -1260,6 +1262,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { void Instruction::setAAMetadata(const AAMDNodes &N) { setMetadata(LLVMContext::MD_tbaa, N.TBAA); + setMetadata(LLVMContext::MD_tbaa_struct, N.TBAAStruct); setMetadata(LLVMContext::MD_alias_scope, N.Scope); setMetadata(LLVMContext::MD_noalias, N.NoAlias); } diff --git a/contrib/llvm-project/llvm/lib/IR/Module.cpp b/contrib/llvm-project/llvm/lib/IR/Module.cpp index 25efd009194f..271ae126d722 100644 --- a/contrib/llvm-project/llvm/lib/IR/Module.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Module.cpp @@ -381,6 +381,22 @@ void Module::debug_compile_units_iterator::SkipNoDebugCUs() { ++Idx; } +iterator_range<Module::global_object_iterator> Module::global_objects() { + return concat<GlobalObject>(functions(), globals()); +} +iterator_range<Module::const_global_object_iterator> +Module::global_objects() const { + return concat<const GlobalObject>(functions(), globals()); +} + +iterator_range<Module::global_value_iterator> Module::global_values() { + return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs()); +} +iterator_range<Module::const_global_value_iterator> +Module::global_values() const { + return concat<const GlobalValue>(functions(), globals(), aliases(), ifuncs()); +} + //===----------------------------------------------------------------------===// // Methods to control the materialization of GlobalValues in the Module. // diff --git a/contrib/llvm-project/llvm/lib/IR/ModuleSummaryIndex.cpp b/contrib/llvm-project/llvm/lib/IR/ModuleSummaryIndex.cpp index 9f347d8da01d..180f96269a13 100644 --- a/contrib/llvm-project/llvm/lib/IR/ModuleSummaryIndex.cpp +++ b/contrib/llvm-project/llvm/lib/IR/ModuleSummaryIndex.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/SCCIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -26,6 +27,10 @@ STATISTIC(ReadOnlyLiveGVars, STATISTIC(WriteOnlyLiveGVars, "Number of live global variables marked write only"); +static cl::opt<bool> PropagateAttrs("propagate-attrs", cl::init(true), + cl::Hidden, + cl::desc("Propagate attributes in index")); + FunctionSummary FunctionSummary::ExternalNode = FunctionSummary::makeDummyFunctionSummary({}); @@ -61,6 +66,8 @@ std::pair<unsigned, unsigned> FunctionSummary::specialRefCounts() const { return {RORefCnt, WORefCnt}; } +constexpr uint64_t ModuleSummaryIndex::BitcodeSummaryVersion; + // Collect for the given module the list of function it defines // (GUID -> Summary). void ModuleSummaryIndex::collectDefinedFunctionsForModule( @@ -155,6 +162,8 @@ static void propagateAttributesToRefs(GlobalValueSummary *S) { // See internalizeGVsAfterImport. void ModuleSummaryIndex::propagateAttributes( const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) { + if (!PropagateAttrs) + return; for (auto &P : *this) for (auto &S : P.second.SummaryList) { if (!isGlobalValueLive(S.get())) @@ -172,14 +181,16 @@ void ModuleSummaryIndex::propagateAttributes( // assembly leading it to be in the @llvm.*used). if (auto *GVS = dyn_cast<GlobalVarSummary>(S->getBaseObject())) // Here we intentionally pass S.get() not GVS, because S could be - // an alias. - if (!canImportGlobalVar(S.get()) || + // an alias. We don't analyze references here, because we have to + // know exactly if GV is readonly to do so. + if (!canImportGlobalVar(S.get(), /* AnalyzeRefs */ false) || GUIDPreservedSymbols.count(P.first)) { GVS->setReadOnly(false); GVS->setWriteOnly(false); } propagateAttributesToRefs(S.get()); } + setWithAttributePropagation(); if (llvm::AreStatisticsEnabled()) for (auto &P : *this) if (P.second.SummaryList.size()) @@ -193,6 +204,37 @@ void ModuleSummaryIndex::propagateAttributes( } } +bool ModuleSummaryIndex::canImportGlobalVar(GlobalValueSummary *S, + bool AnalyzeRefs) const { + auto HasRefsPreventingImport = [this](const GlobalVarSummary *GVS) { + // We don't analyze GV references during attribute propagation, so + // GV with non-trivial initializer can be marked either read or + // write-only. + // Importing definiton of readonly GV with non-trivial initializer + // allows us doing some extra optimizations (like converting indirect + // calls to direct). + // Definition of writeonly GV with non-trivial initializer should also + // be imported. Not doing so will result in: + // a) GV internalization in source module (because it's writeonly) + // b) Importing of GV declaration to destination module as a result + // of promotion. + // c) Link error (external declaration with internal definition). + // However we do not promote objects referenced by writeonly GV + // initializer by means of converting it to 'zeroinitializer' + return !isReadOnly(GVS) && !isWriteOnly(GVS) && GVS->refs().size(); + }; + auto *GVS = cast<GlobalVarSummary>(S->getBaseObject()); + + // Global variable with non-trivial initializer can be imported + // if it's readonly. This gives us extra opportunities for constant + // folding and converting indirect calls to direct calls. We don't + // analyze GV references during attribute propagation, because we + // don't know yet if it is readonly or not. + return !GlobalValue::isInterposableLinkage(S->linkage()) && + !S->notEligibleToImport() && + (!AnalyzeRefs || !HasRefsPreventingImport(GVS)); +} + // TODO: write a graphviz dumper for SCCs (see ModuleSummaryIndex::exportToDot) // then delete this function and update its tests LLVM_DUMP_METHOD @@ -202,7 +244,7 @@ void ModuleSummaryIndex::dumpSCCs(raw_ostream &O) { !I.isAtEnd(); ++I) { O << "SCC (" << utostr(I->size()) << " node" << (I->size() == 1 ? "" : "s") << ") {\n"; - for (const ValueInfo V : *I) { + for (const ValueInfo &V : *I) { FunctionSummary *F = nullptr; if (V.getSummaryList().size()) F = cast<FunctionSummary>(V.getSummaryList().front().get()); @@ -298,7 +340,7 @@ static std::string fflagsToString(FunctionSummary::FFlags F) { auto FlagValue = [](unsigned V) { return V ? '1' : '0'; }; char FlagRep[] = {FlagValue(F.ReadNone), FlagValue(F.ReadOnly), FlagValue(F.NoRecurse), FlagValue(F.ReturnDoesNotAlias), - FlagValue(F.NoInline), 0}; + FlagValue(F.NoInline), FlagValue(F.AlwaysInline), 0}; return FlagRep; } @@ -363,7 +405,9 @@ static bool hasWriteOnlyFlag(const GlobalValueSummary *S) { return false; } -void ModuleSummaryIndex::exportToDot(raw_ostream &OS) const { +void ModuleSummaryIndex::exportToDot( + raw_ostream &OS, + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) const { std::vector<Edge> CrossModuleEdges; DenseMap<GlobalValue::GUID, std::vector<uint64_t>> NodeMap; using GVSOrderedMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>; @@ -443,6 +487,8 @@ void ModuleSummaryIndex::exportToDot(raw_ostream &OS) const { A.addComment("dsoLocal"); if (Flags.CanAutoHide) A.addComment("canAutoHide"); + if (GUIDPreservedSymbols.count(SummaryIt.first)) + A.addComment("preserved"); auto VI = getValueInfo(SummaryIt.first); A.add("label", getNodeLabel(VI, SummaryIt.second)); diff --git a/contrib/llvm-project/llvm/lib/IR/Pass.cpp b/contrib/llvm-project/llvm/lib/IR/Pass.cpp index 699a7e17c0cb..dbdbbf4cf35e 100644 --- a/contrib/llvm-project/llvm/lib/IR/Pass.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Pass.cpp @@ -176,51 +176,6 @@ bool FunctionPass::skipFunction(const Function &F) const { return false; } -//===----------------------------------------------------------------------===// -// BasicBlockPass Implementation -// - -Pass *BasicBlockPass::createPrinterPass(raw_ostream &OS, - const std::string &Banner) const { - return createPrintBasicBlockPass(OS, Banner); -} - -bool BasicBlockPass::doInitialization(Function &) { - // By default, don't do anything. - return false; -} - -bool BasicBlockPass::doFinalization(Function &) { - // By default, don't do anything. - return false; -} - -static std::string getDescription(const BasicBlock &BB) { - return "basic block (" + BB.getName().str() + ") in function (" + - BB.getParent()->getName().str() + ")"; -} - -bool BasicBlockPass::skipBasicBlock(const BasicBlock &BB) const { - const Function *F = BB.getParent(); - if (!F) - return false; - OptPassGate &Gate = F->getContext().getOptPassGate(); - if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(BB))) - return true; - if (F->hasOptNone()) { - // Report this only once per function. - if (&BB == &F->getEntryBlock()) - LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName() - << "' on function " << F->getName() << "\n"); - return true; - } - return false; -} - -PassManagerType BasicBlockPass::getPotentialPassManagerType() const { - return PMT_BasicBlockPassManager; -} - const PassInfo *Pass::lookupPassInfo(const void *TI) { return PassRegistry::getPassRegistry()->getPassInfo(TI); } diff --git a/contrib/llvm-project/llvm/lib/IR/RemarkStreamer.cpp b/contrib/llvm-project/llvm/lib/IR/RemarkStreamer.cpp index 0fcc06b961f3..cdbcc4f456c5 100644 --- a/contrib/llvm-project/llvm/lib/IR/RemarkStreamer.cpp +++ b/contrib/llvm-project/llvm/lib/IR/RemarkStreamer.cpp @@ -18,9 +18,17 @@ #include "llvm/Remarks/BitstreamRemarkSerializer.h" #include "llvm/Remarks/RemarkFormat.h" #include "llvm/Remarks/RemarkSerializer.h" +#include "llvm/Support/CommandLine.h" using namespace llvm; +static cl::opt<cl::boolOrDefault> EnableRemarksSection( + "remarks-section", + cl::desc( + "Emit a section containing remark diagnostics metadata. By default, " + "this is enabled for the following formats: yaml-strtab, bitstream."), + cl::init(cl::BOU_UNSET), cl::Hidden); + RemarkStreamer::RemarkStreamer( std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer, Optional<StringRef> FilenameIn) @@ -104,6 +112,31 @@ void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) { RemarkSerializer->emit(R); } +bool RemarkStreamer::needsSection() const { + if (EnableRemarksSection == cl::BOU_TRUE) + return true; + + if (EnableRemarksSection == cl::BOU_FALSE) + return false; + + assert(EnableRemarksSection == cl::BOU_UNSET); + + // We only need a section if we're in separate mode. + if (RemarkSerializer->Mode != remarks::SerializerMode::Separate) + return false; + + // Only some formats need a section: + // * bitstream + // * yaml-strtab + switch (RemarkSerializer->SerializerFormat) { + case remarks::Format::YAMLStrTab: + case remarks::Format::Bitstream: + return true; + default: + return false; + } +} + char RemarkSetupFileError::ID = 0; char RemarkSetupPatternError::ID = 0; char RemarkSetupFormatError::ID = 0; diff --git a/contrib/llvm-project/llvm/lib/IR/SafepointIRVerifier.cpp b/contrib/llvm-project/llvm/lib/IR/SafepointIRVerifier.cpp index c90347ec48fd..f9578394a827 100644 --- a/contrib/llvm-project/llvm/lib/IR/SafepointIRVerifier.cpp +++ b/contrib/llvm-project/llvm/lib/IR/SafepointIRVerifier.cpp @@ -30,6 +30,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/SafepointIRVerifier.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SetOperations.h" @@ -38,14 +39,14 @@ #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" -#include "llvm/IR/Value.h" -#include "llvm/IR/SafepointIRVerifier.h" #include "llvm/IR/Statepoint.h" -#include "llvm/Support/Debug.h" +#include "llvm/IR/Value.h" +#include "llvm/InitializePasses.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #define DEBUG_TYPE "safepoint-ir-verifier" diff --git a/contrib/llvm-project/llvm/lib/IR/TypeFinder.cpp b/contrib/llvm-project/llvm/lib/IR/TypeFinder.cpp index 2e2c194860cd..403ae45756a1 100644 --- a/contrib/llvm-project/llvm/lib/IR/TypeFinder.cpp +++ b/contrib/llvm-project/llvm/lib/IR/TypeFinder.cpp @@ -77,7 +77,7 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { } for (const auto &NMD : M.named_metadata()) - for (const auto &MDOp : NMD.operands()) + for (const auto *MDOp : NMD.operands()) incorporateMDNode(MDOp); } diff --git a/contrib/llvm-project/llvm/lib/IR/User.cpp b/contrib/llvm-project/llvm/lib/IR/User.cpp index 33a3686c94a1..4a3eba9e8cf7 100644 --- a/contrib/llvm-project/llvm/lib/IR/User.cpp +++ b/contrib/llvm-project/llvm/lib/IR/User.cpp @@ -162,7 +162,9 @@ void *User::operator new(size_t Size) { // User operator delete Implementation //===----------------------------------------------------------------------===// -void User::operator delete(void *Usr) { +// Repress memory sanitization, due to use-after-destroy by operator +// delete. Bug report 24578 identifies this issue. +LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE void User::operator delete(void *Usr) { // Hung off uses use a single Use* before the User, while other subclasses // use a Use[] allocated prior to the user. User *Obj = static_cast<User *>(Usr); diff --git a/contrib/llvm-project/llvm/lib/IR/Value.cpp b/contrib/llvm-project/llvm/lib/IR/Value.cpp index 3c8a5b536695..cf9d08f6fc02 100644 --- a/contrib/llvm-project/llvm/lib/IR/Value.cpp +++ b/contrib/llvm-project/llvm/lib/IR/Value.cpp @@ -13,8 +13,8 @@ #include "llvm/IR/Value.h" #include "LLVMContextImpl.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallString.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -29,6 +29,7 @@ #include "llvm/IR/Statepoint.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueSymbolTable.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" diff --git a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp index b17fc433ed74..d15b70d71b47 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" @@ -1506,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: @@ -1555,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, @@ -1702,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); @@ -1842,6 +1844,25 @@ 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-entry")) { + StringRef S0 = Attrs + .getAttribute(AttributeList::FunctionIndex, + "patchable-function-entry") + .getValueAsString(); + StringRef S = S0; + unsigned N; + if (S.getAsInteger(10, N)) + CheckFailed( + "\"patchable-function-entry\" takes an unsigned integer: " + S0, V); + } } void Verifier::verifyFunctionMetadata( @@ -2975,10 +2996,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(); @@ -2997,6 +3018,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); } } @@ -4291,38 +4318,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_fptosi: - case Intrinsic::experimental_constrained_fptoui: - 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_lrint: - case Intrinsic::experimental_constrained_llrint: - 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_lround: - case Intrinsic::experimental_constrained_llround: - 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 @@ -4691,28 +4689,32 @@ 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_sat: { + 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; } @@ -4749,83 +4751,54 @@ 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); + switch (FPI.getIntrinsicID()) { case Intrinsic::experimental_constrained_lrint: case Intrinsic::experimental_constrained_llrint: { - Assert((NumOperands == 3), "invalid arguments for constrained FP intrinsic", - &FPI); Type *ValTy = FPI.getArgOperand(0)->getType(); Type *ResultTy = FPI.getType(); Assert(!ValTy->isVectorTy() && !ResultTy->isVectorTy(), "Intrinsic does not support vectors", &FPI); - HasExceptionMD = true; - HasRoundingMD = true; } break; case Intrinsic::experimental_constrained_lround: case Intrinsic::experimental_constrained_llround: { - Assert((NumOperands == 2), "invalid arguments for constrained FP intrinsic", - &FPI); Type *ValTy = FPI.getArgOperand(0)->getType(); Type *ResultTy = FPI.getType(); Assert(!ValTy->isVectorTy() && !ResultTy->isVectorTy(), "Intrinsic does not support vectors", &FPI); - HasExceptionMD = true; break; } - case Intrinsic::experimental_constrained_fma: - Assert((NumOperands == 5), "invalid arguments for constrained FP intrinsic", - &FPI); - HasExceptionMD = true; - HasRoundingMD = true; - 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_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: { - Assert((NumOperands == 2), - "invalid arguments for constrained FP intrinsic", &FPI); - HasExceptionMD = true; - Value *Operand = FPI.getArgOperand(0); uint64_t NumSrcElem = 0; Assert(Operand->getType()->isFPOrFPVectorTy(), @@ -4847,18 +4820,30 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &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_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); } - HasExceptionMD = true; + } break; + case Intrinsic::experimental_constrained_fptrunc: + case Intrinsic::experimental_constrained_fpext: { Value *Operand = FPI.getArgOperand(0); Type *OperandTy = Operand->getType(); Value *Result = &FPI; @@ -4889,7 +4874,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 @@ -4897,10 +4882,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); |