aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-24 22:00:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-24 22:00:03 +0000
commit480093f4440d54b30b3025afeac24b48f2ba7a2e (patch)
tree162e72994062888647caf0d875428db9445491a8 /contrib/llvm-project/llvm/lib/IR
parent489b1cf2ecf5b9b4a394857987014bfb09067726 (diff)
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
downloadsrc-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')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/AbstractCallSite.cpp19
-rw-r--r--contrib/llvm-project/llvm/lib/IR/AsmWriter.cpp65
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Attributes.cpp36
-rw-r--r--contrib/llvm-project/llvm/lib/IR/AutoUpgrade.cpp77
-rw-r--r--contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp60
-rw-r--r--contrib/llvm-project/llvm/lib/IR/ConstantRange.cpp150
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Constants.cpp96
-rw-r--r--contrib/llvm-project/llvm/lib/IR/ConstantsContext.h2
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Core.cpp22
-rw-r--r--contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp31
-rw-r--r--contrib/llvm-project/llvm/lib/IR/DataLayout.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/IR/DebugInfo.cpp13
-rw-r--r--contrib/llvm-project/llvm/lib/IR/DebugInfoMetadata.cpp56
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Dominators.cpp6
-rw-r--r--contrib/llvm-project/llvm/lib/IR/FPEnv.cpp78
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Function.cpp30
-rw-r--r--contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp66
-rw-r--r--contrib/llvm-project/llvm/lib/IR/IRPrintingPasses.cpp38
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Instruction.cpp1
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Instructions.cpp67
-rw-r--r--contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp131
-rw-r--r--contrib/llvm-project/llvm/lib/IR/LLVMContext.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/IR/LLVMContextImpl.h12
-rw-r--r--contrib/llvm-project/llvm/lib/IR/LegacyPassManager.cpp280
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Metadata.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Module.cpp16
-rw-r--r--contrib/llvm-project/llvm/lib/IR/ModuleSummaryIndex.cpp56
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Pass.cpp45
-rw-r--r--contrib/llvm-project/llvm/lib/IR/RemarkStreamer.cpp33
-rw-r--r--contrib/llvm-project/llvm/lib/IR/SafepointIRVerifier.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/IR/TypeFinder.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/IR/User.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Value.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Verifier.cpp213
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);