diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
| commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
| tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /include/llvm/IR | |
| parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
Notes
Diffstat (limited to 'include/llvm/IR')
73 files changed, 11005 insertions, 1810 deletions
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index fc04fe71cbf0..0092f49e49ad 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -21,8 +21,7 @@ namespace llvm { -template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; +template <typename NodeTy> class SymbolTableListTraits; /// \brief LLVM Argument representation /// @@ -36,7 +35,7 @@ class Argument : public Value, public ilist_node<Argument> { virtual void anchor(); Function *Parent; - friend class SymbolTableListTraits<Argument, Function>; + friend class SymbolTableListTraits<Argument>; void setParent(Function *parent); public: @@ -64,8 +63,8 @@ public: /// containing function, return the number of bytes known to be /// dereferenceable. Otherwise, zero is returned. uint64_t getDereferenceableBytes() const; - - /// \brief If this argument has the dereferenceable_or_null attribute on + + /// \brief If this argument has the dereferenceable_or_null attribute on /// it in its containing function, return the number of bytes known to be /// dereferenceable. Otherwise, zero is returned. uint64_t getDereferenceableOrNullBytes() const; diff --git a/include/llvm/IR/AssemblyAnnotationWriter.h b/include/llvm/IR/AssemblyAnnotationWriter.h index 19e32a2dcdcc..6e1f5c43e12e 100644 --- a/include/llvm/IR/AssemblyAnnotationWriter.h +++ b/include/llvm/IR/AssemblyAnnotationWriter.h @@ -27,7 +27,6 @@ class formatted_raw_ostream; class AssemblyAnnotationWriter { public: - virtual ~AssemblyAnnotationWriter(); /// emitFunctionAnnot - This may be implemented to emit a string right before @@ -50,7 +49,7 @@ public: /// emitInstructionAnnot - This may be implemented to emit a string right /// before an instruction is emitted. - virtual void emitInstructionAnnot(const Instruction *, + virtual void emitInstructionAnnot(const Instruction *, formatted_raw_ostream &) {} /// printInfoComment - This may be implemented to emit a comment to the diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 4d6d7da1fa5b..0e3373165407 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -33,6 +33,7 @@ class AttributeSetImpl; class AttributeSetNode; class Constant; template<typename T> struct DenseMapInfo; +class Function; class LLVMContext; class Type; @@ -64,65 +65,15 @@ public: enum AttrKind { // IR-Level Attributes None, ///< No attributes have been set - Alignment, ///< Alignment of parameter (5 bits) - ///< stored as log2 of alignment with +1 bias - ///< 0 means unaligned (different from align(1)) - AlwaysInline, ///< inline=always - Builtin, ///< Callee is recognized as a builtin, despite - ///< nobuiltin attribute on its declaration. - ByVal, ///< Pass structure by value - InAlloca, ///< Pass structure in an alloca - Cold, ///< Marks function as being in a cold path. - Convergent, ///< Can only be moved to control-equivalent blocks - InlineHint, ///< Source said inlining was desirable - InReg, ///< Force argument to be passed in register - JumpTable, ///< Build jump-instruction tables and replace refs. - MinSize, ///< Function must be optimized for size first - Naked, ///< Naked function - Nest, ///< Nested function static chain - NoAlias, ///< Considered to not alias after call - NoBuiltin, ///< Callee isn't recognized as a builtin - NoCapture, ///< Function creates no aliases of pointer - NoDuplicate, ///< Call cannot be duplicated - NoImplicitFloat, ///< Disable implicit floating point insts - NoInline, ///< inline=never - NonLazyBind, ///< Function is called early and/or - ///< often, so lazy binding isn't worthwhile - NonNull, ///< Pointer is known to be not null - Dereferenceable, ///< Pointer is known to be dereferenceable - DereferenceableOrNull, ///< Pointer is either null or dereferenceable - NoRedZone, ///< Disable redzone - NoReturn, ///< Mark the function as not returning - NoUnwind, ///< Function doesn't unwind stack - OptimizeForSize, ///< opt_size - OptimizeNone, ///< Function must not be optimized. - ReadNone, ///< Function does not access memory - ReadOnly, ///< Function only reads from memory - ArgMemOnly, ///< Funciton can access memory only using pointers - ///< based on its arguments. - Returned, ///< Return value is always equal to this argument - ReturnsTwice, ///< Function can return twice - SExt, ///< Sign extended before/after call - StackAlignment, ///< Alignment of stack for function (3 bits) - ///< stored as log2 of alignment with +1 bias 0 - ///< means unaligned (different from - ///< alignstack=(1)) - StackProtect, ///< Stack protection. - StackProtectReq, ///< Stack protection required. - StackProtectStrong, ///< Strong Stack protection. - SafeStack, ///< Safe Stack protection. - StructRet, ///< Hidden pointer to structure to return - SanitizeAddress, ///< AddressSanitizer is on. - SanitizeThread, ///< ThreadSanitizer is on. - SanitizeMemory, ///< MemorySanitizer is on. - UWTable, ///< Function must be in a unwind table - ZExt, ///< Zero extended before/after call - + #define GET_ATTR_ENUM + #include "llvm/IR/Attributes.inc" EndAttrKinds ///< Sentinal value useful for loops }; + private: AttributeImpl *pImpl; Attribute(AttributeImpl *A) : pImpl(A) {} + public: Attribute() : pImpl(nullptr) {} @@ -189,11 +140,11 @@ public: unsigned getStackAlignment() const; /// \brief Returns the number of dereferenceable bytes from the - /// dereferenceable attribute (or zero if unknown). + /// dereferenceable attribute. uint64_t getDereferenceableBytes() const; /// \brief Returns the number of dereferenceable_or_null bytes from the - /// dereferenceable_or_null attribute (or zero if unknown). + /// dereferenceable_or_null attribute. uint64_t getDereferenceableOrNullBytes() const; /// \brief The Attribute is converted to a string of equivalent mnemonic. This @@ -226,6 +177,7 @@ public: ReturnIndex = 0U, FunctionIndex = ~0U }; + private: friend class AttrBuilder; friend class AttributeSetImpl; @@ -249,8 +201,8 @@ private: ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs); - explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {} + public: AttributeSet() : pImpl(nullptr) {} @@ -276,6 +228,11 @@ public: AttributeSet addAttribute(LLVMContext &C, unsigned Index, StringRef Kind, StringRef Value) const; + /// Add an attribute to the attribute set at the given indices. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices, + Attribute A) const; + /// \brief Add attributes to the attribute set at the given index. Because /// attribute sets are immutable, this returns a new set. AttributeSet addAttributes(LLVMContext &C, unsigned Index, @@ -284,13 +241,13 @@ public: /// \brief Remove the specified attribute at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. - AttributeSet removeAttribute(LLVMContext &C, unsigned Index, + AttributeSet removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Attr) const; /// \brief Remove the specified attributes at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. - AttributeSet removeAttributes(LLVMContext &C, unsigned Index, + AttributeSet removeAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const; /// \brief Remove the specified attributes at the specified index from this @@ -439,6 +396,7 @@ class AttrBuilder { uint64_t StackAlignment; uint64_t DerefBytes; uint64_t DerefOrNullBytes; + public: AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0), @@ -511,8 +469,8 @@ public: /// \brief Retrieve the stack alignment attribute, if it exists. uint64_t getStackAlignment() const { return StackAlignment; } - /// \brief Retrieve the number of dereferenceable bytes, if the dereferenceable - /// attribute exists (zero is returned otherwise). + /// \brief Retrieve the number of dereferenceable bytes, if the + /// dereferenceable attribute exists (zero is returned otherwise). uint64_t getDereferenceableBytes() const { return DerefBytes; } /// \brief Retrieve the number of dereferenceable_or_null bytes, if the @@ -573,7 +531,14 @@ public: namespace AttributeFuncs { /// \brief Which attributes cannot be applied to a type. -AttrBuilder typeIncompatible(const Type *Ty); +AttrBuilder typeIncompatible(Type *Ty); + +/// \returns Return true if the two functions have compatible target-independent +/// attributes for inlining purposes. +bool areInlineCompatible(const Function &Caller, const Function &Callee); + +/// \brief Merge caller's and callee's attributes. +void mergeAttributesForInlining(Function &Caller, const Function &Callee); } // end AttributeFuncs namespace diff --git a/include/llvm/IR/Attributes.td b/include/llvm/IR/Attributes.td new file mode 100644 index 000000000000..797cd55427b3 --- /dev/null +++ b/include/llvm/IR/Attributes.td @@ -0,0 +1,192 @@ +/// Attribute base class. +class Attr<string S> { + // String representation of this attribute in the IR. + string AttrString = S; +} + +/// Enum attribute. +class EnumAttr<string S> : Attr<S>; + +/// StringBool attribute. +class StrBoolAttr<string S> : Attr<S>; + +/// Target-independent enum attributes. + +/// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias. +/// 0 means unaligned (different from align(1)). +def Alignment : EnumAttr<"align">; + +/// inline=always. +def AlwaysInline : EnumAttr<"alwaysinline">; + +/// Function can access memory only using pointers based on its arguments. +def ArgMemOnly : EnumAttr<"argmemonly">; + +/// Callee is recognized as a builtin, despite nobuiltin attribute on its +/// declaration. +def Builtin : EnumAttr<"builtin">; + +/// Pass structure by value. +def ByVal : EnumAttr<"byval">; + +/// Marks function as being in a cold path. +def Cold : EnumAttr<"cold">; + +/// Can only be moved to control-equivalent blocks. +def Convergent : EnumAttr<"convergent">; + +/// Pointer is known to be dereferenceable. +def Dereferenceable : EnumAttr<"dereferenceable">; + +/// Pointer is either null or dereferenceable. +def DereferenceableOrNull : EnumAttr<"dereferenceable_or_null">; + +/// Function may only access memory that is inaccessible from IR. +def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">; + +/// Function may only access memory that is either inaccessible from the IR, +/// or pointed to by its pointer arguments. +def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">; + +/// Pass structure in an alloca. +def InAlloca : EnumAttr<"inalloca">; + +/// Source said inlining was desirable. +def InlineHint : EnumAttr<"inlinehint">; + +/// Force argument to be passed in register. +def InReg : EnumAttr<"inreg">; + +/// Build jump-instruction tables and replace refs. +def JumpTable : EnumAttr<"jumptable">; + +/// Function must be optimized for size first. +def MinSize : EnumAttr<"minsize">; + +/// Naked function. +def Naked : EnumAttr<"naked">; + +/// Nested function static chain. +def Nest : EnumAttr<"nest">; + +/// Considered to not alias after call. +def NoAlias : EnumAttr<"noalias">; + +/// Callee isn't recognized as a builtin. +def NoBuiltin : EnumAttr<"nobuiltin">; + +/// Function creates no aliases of pointer. +def NoCapture : EnumAttr<"nocapture">; + +/// Call cannot be duplicated. +def NoDuplicate : EnumAttr<"noduplicate">; + +/// Disable implicit floating point insts. +def NoImplicitFloat : EnumAttr<"noimplicitfloat">; + +/// inline=never. +def NoInline : EnumAttr<"noinline">; + +/// Function is called early and/or often, so lazy binding isn't worthwhile. +def NonLazyBind : EnumAttr<"nonlazybind">; + +/// Pointer is known to be not null. +def NonNull : EnumAttr<"nonnull">; + +/// The function does not recurse. +def NoRecurse : EnumAttr<"norecurse">; + +/// Disable redzone. +def NoRedZone : EnumAttr<"noredzone">; + +/// Mark the function as not returning. +def NoReturn : EnumAttr<"noreturn">; + +/// Function doesn't unwind stack. +def NoUnwind : EnumAttr<"nounwind">; + +/// opt_size. +def OptimizeForSize : EnumAttr<"optsize">; + +/// Function must not be optimized. +def OptimizeNone : EnumAttr<"optnone">; + +/// Function does not access memory. +def ReadNone : EnumAttr<"readnone">; + +/// Function only reads from memory. +def ReadOnly : EnumAttr<"readonly">; + +/// Return value is always equal to this argument. +def Returned : EnumAttr<"returned">; + +/// Function can return twice. +def ReturnsTwice : EnumAttr<"returns_twice">; + +/// Safe Stack protection. +def SafeStack : EnumAttr<"safestack">; + +/// Sign extended before/after call. +def SExt : EnumAttr<"signext">; + +/// Alignment of stack for function (3 bits) stored as log2 of alignment with +/// +1 bias 0 means unaligned (different from alignstack=(1)). +def StackAlignment : EnumAttr<"alignstack">; + +/// Stack protection. +def StackProtect : EnumAttr<"ssp">; + +/// Stack protection required. +def StackProtectReq : EnumAttr<"sspreq">; + +/// Strong Stack protection. +def StackProtectStrong : EnumAttr<"sspstrong">; + +/// Hidden pointer to structure to return. +def StructRet : EnumAttr<"sret">; + +/// AddressSanitizer is on. +def SanitizeAddress : EnumAttr<"sanitize_address">; + +/// ThreadSanitizer is on. +def SanitizeThread : EnumAttr<"sanitize_thread">; + +/// MemorySanitizer is on. +def SanitizeMemory : EnumAttr<"sanitize_memory">; + +/// Function must be in a unwind table. +def UWTable : EnumAttr<"uwtable">; + +/// Zero extended before/after call. +def ZExt : EnumAttr<"zeroext">; + +/// Target-independent string attributes. +def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">; +def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">; +def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">; +def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">; + +class CompatRule<string F> { + // The name of the function called to check the attribute of the caller and + // callee and decide whether inlining should be allowed. The function's + // signature must match "bool(const Function&, const Function &)", where the + // first parameter is the reference to the caller and the second parameter is + // the reference to the callee. It must return false if the attributes of the + // caller and callee are incompatible, and true otherwise. + string CompatFunc = F; +} + +def : CompatRule<"isEqual<SanitizeAddressAttr>">; +def : CompatRule<"isEqual<SanitizeThreadAttr>">; +def : CompatRule<"isEqual<SanitizeMemoryAttr>">; + +class MergeRule<string F> { + // The name of the function called to merge the attributes of the caller and + // callee. The function's signature must match + // "void(Function&, const Function &)", where the first parameter is the + // reference to the caller and the second parameter is the reference to the + // callee. + string MergeFunc = F; +} + +def : MergeRule<"adjustCallerSSPLevel">; diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 66581bfedbe6..c6b54d308ce6 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -30,22 +30,9 @@ class LLVMContext; class BlockAddress; class Function; -// Traits for intrusive list of basic blocks... -template<> struct ilist_traits<BasicBlock> - : public SymbolTableListTraits<BasicBlock, Function> { - - BasicBlock *createSentinel() const; - static void destroySentinel(BasicBlock*) {} - - BasicBlock *provideInitialHead() const { return createSentinel(); } - BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); } - static void noteHead(BasicBlock*, BasicBlock*) {} - - static ValueSymbolTable *getSymTab(Function *ItemParent); -private: - mutable ilist_half_node<BasicBlock> Sentinel; -}; - +template <> +struct SymbolTableListSentinelTraits<BasicBlock> + : public ilist_half_embedded_sentinel_traits<BasicBlock> {}; /// \brief LLVM Basic Block Representation /// @@ -63,16 +50,17 @@ private: /// modifying a program. However, the verifier will ensure that basic blocks /// are "well formed". class BasicBlock : public Value, // Basic blocks are data objects also - public ilist_node<BasicBlock> { + public ilist_node_with_parent<BasicBlock, Function> { friend class BlockAddress; public: - typedef iplist<Instruction> InstListType; + typedef SymbolTableList<Instruction> InstListType; + private: InstListType InstList; Function *Parent; void setParent(Function *parent); - friend class SymbolTableListTraits<BasicBlock, Function>; + friend class SymbolTableListTraits<BasicBlock>; BasicBlock(const BasicBlock &) = delete; void operator=(const BasicBlock &) = delete; @@ -171,7 +159,7 @@ public: /// \brief Unlink 'this' from the containing function and delete it. /// // \returns an iterator pointing to the element after the erased one. - iplist<BasicBlock>::iterator eraseFromParent(); + SymbolTableList<BasicBlock>::iterator eraseFromParent(); /// \brief Unlink this basic block from its current function and insert it /// into the function that \p MovePos lives in, right before \p MovePos. @@ -253,7 +241,7 @@ public: InstListType &getInstList() { return InstList; } /// \brief Returns a pointer to a member of the instruction list. - static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) { + static InstListType BasicBlock::*getSublistAccess(Instruction*) { return &BasicBlock::InstList; } @@ -283,6 +271,8 @@ public: /// should be called while the predecessor still refers to this block. void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false); + bool canSplitPredecessors() const; + /// \brief Split the basic block into two basic blocks at the specified /// instruction. /// @@ -300,6 +290,9 @@ public: /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); + BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") { + return splitBasicBlock(I->getIterator(), BBName); + } /// \brief Returns true if there are any uses of this basic block other than /// direct branches, switches, etc. to it. @@ -309,6 +302,9 @@ public: /// basic block \p New instead of to it. void replaceSuccessorsPhiUsesWith(BasicBlock *New); + /// \brief Return true if this basic block is an exception handling block. + bool isEHPad() const { return getFirstNonPHI()->isEHPad(); } + /// \brief Return true if this basic block is a landing pad. /// /// Being a ``landing pad'' means that the basic block is the destination of @@ -337,12 +333,6 @@ private: } }; -// createSentinel is used to get hold of the node that marks the end of the -// list... (same trick used here as in ilist_traits<Instruction>) -inline BasicBlock *ilist_traits<BasicBlock>::createSentinel() const { - return static_cast<BasicBlock*>(&Sentinel); -} - // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef) diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index f78220a52033..e9bf09333a23 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -107,149 +107,13 @@ inline pred_const_range predecessors(const BasicBlock *BB) { } //===----------------------------------------------------------------------===// -// BasicBlock succ_iterator definition +// BasicBlock succ_iterator helpers //===----------------------------------------------------------------------===// -template <class Term_, class BB_> // Successor Iterator -class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB_, - int, BB_ *, BB_ *> { - typedef std::iterator<std::random_access_iterator_tag, BB_, int, BB_ *, BB_ *> - super; - -public: - typedef typename super::pointer pointer; - typedef typename super::reference reference; - -private: - Term_ Term; - unsigned idx; - typedef SuccIterator<Term_, BB_> Self; - - inline bool index_is_valid(int idx) { - return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); - } - - /// \brief Proxy object to allow write access in operator[] - class SuccessorProxy { - Self it; - - public: - explicit SuccessorProxy(const Self &it) : it(it) {} - - SuccessorProxy(const SuccessorProxy&) = default; - - SuccessorProxy &operator=(SuccessorProxy r) { - *this = reference(r); - return *this; - } - - SuccessorProxy &operator=(reference r) { - it.Term->setSuccessor(it.idx, r); - return *this; - } - - operator reference() const { return *it; } - }; - -public: - explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator - } - inline SuccIterator(Term_ T, bool) // end iterator - : Term(T) { - if (Term) - idx = Term->getNumSuccessors(); - else - // Term == NULL happens, if a basic block is not fully constructed and - // consequently getTerminator() returns NULL. In this case we construct a - // SuccIterator which describes a basic block that has zero successors. - // Defining SuccIterator for incomplete and malformed CFGs is especially - // useful for debugging. - idx = 0; - } - - /// getSuccessorIndex - This is used to interface between code that wants to - /// operate on terminator instructions directly. - unsigned getSuccessorIndex() const { return idx; } - - inline bool operator==(const Self& x) const { return idx == x.idx; } - inline bool operator!=(const Self& x) const { return !operator==(x); } - - inline reference operator*() const { return Term->getSuccessor(idx); } - inline pointer operator->() const { return operator*(); } - - inline Self& operator++() { ++idx; return *this; } // Preincrement - - inline Self operator++(int) { // Postincrement - Self tmp = *this; ++*this; return tmp; - } - - inline Self& operator--() { --idx; return *this; } // Predecrement - inline Self operator--(int) { // Postdecrement - Self tmp = *this; --*this; return tmp; - } - - inline bool operator<(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx < x.idx; - } - - inline bool operator<=(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx <= x.idx; - } - inline bool operator>=(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx >= x.idx; - } - - inline bool operator>(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx > x.idx; - } - - inline Self& operator+=(int Right) { - unsigned new_idx = idx + Right; - assert(index_is_valid(new_idx) && "Iterator index out of bound"); - idx = new_idx; - return *this; - } - - inline Self operator+(int Right) const { - Self tmp = *this; - tmp += Right; - return tmp; - } - - inline Self& operator-=(int Right) { - return operator+=(-Right); - } - - inline Self operator-(int Right) const { - return operator+(-Right); - } - - inline int operator-(const Self& x) const { - assert(Term == x.Term && "Cannot work on iterators of different blocks!"); - int distance = idx - x.idx; - return distance; - } - - inline SuccessorProxy operator[](int offset) { - Self tmp = *this; - tmp += offset; - return SuccessorProxy(tmp); - } - - /// Get the source BB of this iterator. - inline BB_ *getSource() { - assert(Term && "Source not available, if basic block was malformed"); - return Term->getParent(); - } -}; - -typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator; -typedef SuccIterator<const TerminatorInst*, - const BasicBlock> succ_const_iterator; +typedef TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock> + succ_iterator; +typedef TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock> + succ_const_iterator; typedef llvm::iterator_range<succ_iterator> succ_range; typedef llvm::iterator_range<succ_const_iterator> succ_const_range; @@ -275,8 +139,8 @@ inline succ_const_range successors(const BasicBlock *BB) { return succ_const_range(succ_begin(BB), succ_end(BB)); } - -template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > { +template <typename T, typename U> +struct isPodLike<TerminatorInst::SuccIterator<T, U>> { static const bool value = isPodLike<T>::value; }; diff --git a/include/llvm/IR/CMakeLists.txt b/include/llvm/IR/CMakeLists.txt index dd8e04f1510c..eade87e05bc9 100644 --- a/include/llvm/IR/CMakeLists.txt +++ b/include/llvm/IR/CMakeLists.txt @@ -1,5 +1,6 @@ -set(LLVM_TARGET_DEFINITIONS Intrinsics.td) +set(LLVM_TARGET_DEFINITIONS Attributes.td) +tablegen(LLVM Attributes.inc -gen-attrs) +set(LLVM_TARGET_DEFINITIONS Intrinsics.td) tablegen(LLVM Intrinsics.gen -gen-intrinsic) - add_public_tablegen_target(intrinsics_gen) diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 2841781e8a9e..f4b8a8a5a1c9 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -41,6 +41,7 @@ template <typename FunTy = const Function, typename BBTy = const BasicBlock, typename ValTy = const Value, typename UserTy = const User, + typename UseTy = const Use, typename InstrTy = const Instruction, typename CallTy = const CallInst, typename InvokeTy = const InvokeInst, @@ -69,6 +70,7 @@ private: } return CallSiteBase(); } + public: /// isCall - true if a CallInst is enclosed. /// Note that !isCall() does not mean it is an InvokeInst enclosed, @@ -116,6 +118,43 @@ public: /// Determine whether this Use is the callee operand's Use. bool isCallee(const Use *U) const { return getCallee() == U; } + /// \brief Determine whether the passed iterator points to an argument + /// operand. + bool isArgOperand(Value::const_user_iterator UI) const { + return isArgOperand(&UI.getUse()); + } + + /// \brief Determine whether the passed use points to an argument operand. + bool isArgOperand(const Use *U) const { + assert(getInstruction() == U->getUser()); + return arg_begin() <= U && U < arg_end(); + } + + /// \brief Determine whether the passed iterator points to a bundle operand. + bool isBundleOperand(Value::const_user_iterator UI) const { + return isBundleOperand(&UI.getUse()); + } + + /// \brief Determine whether the passed use points to a bundle operand. + bool isBundleOperand(const Use *U) const { + assert(getInstruction() == U->getUser()); + if (!hasOperandBundles()) + return false; + unsigned OperandNo = U - (*this)->op_begin(); + return getBundleOperandsStartIndex() <= OperandNo && + OperandNo < getBundleOperandsEndIndex(); + } + + /// \brief Determine whether the passed iterator points to a data operand. + bool isDataOperand(Value::const_user_iterator UI) const { + return isDataOperand(&UI.getUse()); + } + + /// \brief Determine whether the passed use points to a data operand. + bool isDataOperand(const Use *U) const { + return data_operands_begin() <= U && U < data_operands_end(); + } + ValTy *getArgument(unsigned ArgNo) const { assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); return *(arg_begin() + ArgNo); @@ -137,8 +176,7 @@ public: /// it. unsigned getArgumentNo(const Use *U) const { assert(getInstruction() && "Not a call or invoke instruction!"); - assert(arg_begin() <= U && U < arg_end() - && "Argument # out of range!"); + assert(isArgOperand(U) && "Argument # out of range!"); return U - arg_begin(); } @@ -146,21 +184,55 @@ public: /// arguments at this call site. typedef IterTy arg_iterator; - /// arg_begin/arg_end - Return iterators corresponding to the actual argument - /// list for a call site. - IterTy arg_begin() const { - assert(getInstruction() && "Not a call or invoke instruction!"); - // Skip non-arguments - return (*this)->op_begin(); - } - - IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); } iterator_range<IterTy> args() const { - return iterator_range<IterTy>(arg_begin(), arg_end()); + return make_range(arg_begin(), arg_end()); } bool arg_empty() const { return arg_end() == arg_begin(); } unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); } + /// Given a value use iterator, returns the data operand that corresponds to + /// it. + /// Iterator must actually correspond to a data operand. + unsigned getDataOperandNo(Value::const_user_iterator UI) const { + return getDataOperandNo(&UI.getUse()); + } + + /// Given a use for a data operand, get the data operand number that + /// corresponds to it. + unsigned getDataOperandNo(const Use *U) const { + assert(getInstruction() && "Not a call or invoke instruction!"); + assert(isDataOperand(U) && "Data operand # out of range!"); + return U - data_operands_begin(); + } + + /// Type of iterator to use when looping over data operands at this call site + /// (see below). + typedef IterTy data_operand_iterator; + + /// data_operands_begin/data_operands_end - Return iterators iterating over + /// the call / invoke argument list and bundle operands. For invokes, this is + /// the set of instruction operands except the invoke target and the two + /// successor blocks; and for calls this is the set of instruction operands + /// except the call target. + + IterTy data_operands_begin() const { + assert(getInstruction() && "Not a call or invoke instruction!"); + return (*this)->op_begin(); + } + IterTy data_operands_end() const { + assert(getInstruction() && "Not a call or invoke instruction!"); + return (*this)->op_end() - (isCall() ? 1 : 3); + } + iterator_range<IterTy> data_ops() const { + return make_range(data_operands_begin(), data_operands_end()); + } + bool data_operands_empty() const { + return data_operands_end() == data_operands_begin(); + } + unsigned data_operands_size() const { + return std::distance(data_operands_begin(), data_operands_end()); + } + /// getType - Return the type of the instruction that generated this call site /// Type *getType() const { return (*this)->getType(); } @@ -197,11 +269,11 @@ public: CALLSITE_DELEGATE_GETTER(getNumArgOperands()); } - ValTy *getArgOperand(unsigned i) const { + ValTy *getArgOperand(unsigned i) const { CALLSITE_DELEGATE_GETTER(getArgOperand(i)); } - bool isInlineAsm() const { + bool isInlineAsm() const { if (isCall()) return cast<CallInst>(getInstruction())->isInlineAsm(); return false; @@ -243,6 +315,17 @@ public: CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); } + /// \brief Return true if the data operand at index \p i directly or + /// indirectly has the attribute \p A. + /// + /// Normal call or invoke arguments have per operand attributes, as specified + /// in the attribute set attached to this instruction, while operand bundle + /// operands may have some attributes implied by the type of its containing + /// operand bundle. + bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const { + CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, A)); + } + /// @brief Extract the alignment for a call or parameter (0=unknown). uint16_t getParamAlignment(uint16_t i) const { CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); @@ -253,13 +336,20 @@ public: uint64_t getDereferenceableBytes(uint16_t i) const { CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i)); } - + /// @brief Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). uint64_t getDereferenceableOrNullBytes(uint16_t i) const { CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i)); } - + + /// @brief Determine if the parameter or return value is marked with NoAlias + /// attribute. + /// @param n The parameter to check. 1 is the first parameter, 0 is the return + bool doesNotAlias(unsigned n) const { + CALLSITE_DELEGATE_GETTER(doesNotAlias(n)); + } + /// \brief Return true if the call should not be treated as a call to a /// builtin. bool isNoBuiltin() const { @@ -315,12 +405,62 @@ public: CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); } + unsigned getNumOperandBundles() const { + CALLSITE_DELEGATE_GETTER(getNumOperandBundles()); + } + + bool hasOperandBundles() const { + CALLSITE_DELEGATE_GETTER(hasOperandBundles()); + } + + unsigned getBundleOperandsStartIndex() const { + CALLSITE_DELEGATE_GETTER(getBundleOperandsStartIndex()); + } + + unsigned getBundleOperandsEndIndex() const { + CALLSITE_DELEGATE_GETTER(getBundleOperandsEndIndex()); + } + + unsigned getNumTotalBundleOperands() const { + CALLSITE_DELEGATE_GETTER(getNumTotalBundleOperands()); + } + + OperandBundleUse getOperandBundleAt(unsigned Index) const { + CALLSITE_DELEGATE_GETTER(getOperandBundleAt(Index)); + } + + Optional<OperandBundleUse> getOperandBundle(StringRef Name) const { + CALLSITE_DELEGATE_GETTER(getOperandBundle(Name)); + } + + Optional<OperandBundleUse> getOperandBundle(uint32_t ID) const { + CALLSITE_DELEGATE_GETTER(getOperandBundle(ID)); + } + + IterTy arg_begin() const { + CALLSITE_DELEGATE_GETTER(arg_begin()); + } + + IterTy arg_end() const { + CALLSITE_DELEGATE_GETTER(arg_end()); + } + #undef CALLSITE_DELEGATE_GETTER #undef CALLSITE_DELEGATE_SETTER - /// @brief Determine whether this argument is not captured. - bool doesNotCapture(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::NoCapture); + void getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> &Defs) const { + const Instruction *II = getInstruction(); + // Since this is actually a getter that "looks like" a setter, don't use the + // above macros to avoid confusion. + if (isCall()) + cast<CallInst>(II)->getOperandBundlesAsDefs(Defs); + else + cast<InvokeInst>(II)->getOperandBundlesAsDefs(Defs); + } + + /// @brief Determine whether this data operand is not captured. + bool doesNotCapture(unsigned OpNo) const { + return dataOperandHasImpliedAttr(OpNo + 1, Attribute::NoCapture); } /// @brief Determine whether this argument is passed by value. @@ -345,13 +485,13 @@ public: return paramHasAttr(arg_size(), Attribute::InAlloca); } - bool doesNotAccessMemory(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ReadNone); + bool doesNotAccessMemory(unsigned OpNo) const { + return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone); } - bool onlyReadsMemory(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) || - paramHasAttr(ArgNo + 1, Attribute::ReadNone); + bool onlyReadsMemory(unsigned OpNo) const { + return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadOnly) || + dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone); } /// @brief Return true if the return value is known to be not null. @@ -378,13 +518,6 @@ public: } private: - unsigned getArgumentEndOffset() const { - if (isCall()) - return 1; // Skip Callee - else - return 3; // Skip BB, BB, Callee - } - IterTy getCallee() const { if (isCall()) // Skip Callee return cast<CallInst>(getInstruction())->op_end() - 1; @@ -393,7 +526,7 @@ private: } }; -class CallSite : public CallSiteBase<Function, BasicBlock, Value, User, +class CallSite : public CallSiteBase<Function, BasicBlock, Value, User, Use, Instruction, CallInst, InvokeInst, User::op_iterator> { public: diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 9872e6ec794d..bc050928266e 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -69,6 +69,12 @@ namespace CallingConv { // (almost) all registers. PreserveAll = 15, + // Swift - Calling convention for Swift. + Swift = 16, + + // CXX_FAST_TLS - Calling convention for access functions. + CXX_FAST_TLS = 17, + // Target - This is the start of the target-specific calling conventions, // e.g. fastcall and thiscall on X86. FirstTargetCC = 64, @@ -144,7 +150,26 @@ namespace CallingConv { /// \brief MSVC calling convention that passes vectors and vector aggregates /// in SSE registers. - X86_VectorCall = 80 + X86_VectorCall = 80, + + /// \brief Calling convention used by HipHop Virtual Machine (HHVM) to + /// perform calls to and from translation cache, and for calling PHP + /// functions. + /// HHVM calling convention supports tail/sibling call elimination. + HHVM = 81, + + /// \brief HHVM calling convention for invoking C/C++ helpers. + HHVM_C = 82, + + /// X86_INTR - x86 hardware interrupt context. Callee may take one or two + /// parameters, where the 1st represents a pointer to hardware context frame + /// and the 2nd represents hardware error code, the presence of the later + /// depends on the interrupt vector taken. Valid for both 32- and 64-bit + /// subtargets. + X86_INTR = 83, + + /// The highest possible calling convention ID. Must be some 2^k - 1. + MaxID = 1023 }; } // End CallingConv namespace diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h index 4d4c15fb68cd..fb79e13af3a5 100644 --- a/include/llvm/IR/Comdat.h +++ b/include/llvm/IR/Comdat.h @@ -42,7 +42,7 @@ public: SelectionKind getSelectionKind() const { return SK; } void setSelectionKind(SelectionKind Val) { SK = Val; } StringRef getName() const; - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, bool IsForDebug = false) const; void dump() const; private: diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 019b4343a133..bb88905aa57a 100644 --- a/include/llvm/IR/Constant.h +++ b/include/llvm/IR/Constant.h @@ -24,18 +24,18 @@ namespace llvm { /// This is an important base class in LLVM. It provides the common facilities /// of all constant values in an LLVM program. A constant is a value that is /// immutable at runtime. Functions are constants because their address is -/// immutable. Same with global variables. -/// +/// immutable. Same with global variables. +/// /// All constants share the capabilities provided in this class. All constants /// can have a null value. They can have an operand list. Constants can be /// simple (integer and floating point values), complex (arrays and structures), -/// or expression based (computations yielding a constant value composed of +/// or expression based (computations yielding a constant value composed of /// only certain operators and other constant values). -/// -/// Note that Constants are immutable (once created they never change) -/// and are fully shared by structural equivalence. This means that two -/// structurally equivalent constants will always have the same address. -/// Constants are created on demand as needed and never deleted: thus clients +/// +/// Note that Constants are immutable (once created they never change) +/// and are fully shared by structural equivalence. This means that two +/// structurally equivalent constants will always have the same address. +/// Constants are created on demand as needed and never deleted: thus clients /// don't have to worry about the lifetime of the objects. /// @brief LLVM Constant Representation class Constant : public User { @@ -59,7 +59,7 @@ public: /// getAllOnesValue. bool isAllOnesValue() const; - /// isNegativeZeroValue - Return true if the value is what would be returned + /// isNegativeZeroValue - Return true if the value is what would be returned /// by getZeroValueForNegation. bool isNegativeZeroValue() const; @@ -85,29 +85,14 @@ public: /// isConstantUsed - Return true if the constant has users other than constant /// exprs and other dangling things. bool isConstantUsed() const; - - enum PossibleRelocationsTy { - NoRelocation = 0, - LocalRelocation = 1, - GlobalRelocations = 2 - }; - - /// getRelocationInfo - This method classifies the entry according to - /// whether or not it may generate a relocation entry. This must be - /// conservative, so if it might codegen to a relocatable entry, it should say - /// so. The return values are: - /// - /// NoRelocation: This constant pool entry is guaranteed to never have a - /// relocation applied to it (because it holds a simple constant like - /// '4'). - /// LocalRelocation: This entry has relocations, but the entries are - /// guaranteed to be resolvable by the static linker, so the dynamic - /// linker will never see them. - /// GlobalRelocations: This entry may have arbitrary relocations. + + /// This method classifies the entry according to whether or not it may + /// generate a relocation entry. This must be conservative, so if it might + /// codegen to a relocatable entry, it should say so. /// - /// FIXME: This really should not be in VMCore. - PossibleRelocationsTy getRelocationInfo() const; - + /// FIXME: This really should not be in IR. + bool needsRelocation() const; + /// getAggregateElement - For aggregates (struct/array/vector) return the /// constant that corresponds to the specified element if possible, or null if /// not. This can return null if the element index is a ConstantExpr, or if @@ -159,8 +144,8 @@ public: /// getIntegerValue - Return the value for an integer or pointer constant, /// or a vector thereof, with the given scalar value. - static Constant *getIntegerValue(Type* Ty, const APInt &V); - + static Constant *getIntegerValue(Type *Ty, const APInt &V); + /// removeDeadConstantUsers - If there are any dead constant users dangling /// off of this constant, remove them. This method is useful for clients /// that want to check to see if a global is unused, but don't want to deal diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 9ded3ca36a70..fb596a3bf16e 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -82,6 +82,17 @@ public: static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other); + /// Return the largest range containing all X such that "X BinOpC C" does not + /// wrap (overflow). + /// + /// Example: + /// typedef OverflowingBinaryOperator OBO; + /// makeNoWrapRegion(Add, i8 1, OBO::NoSignedWrap) == [-128, 127) + /// makeNoWrapRegion(Add, i8 1, OBO::NoUnsignedWrap) == [0, -1) + /// makeNoWrapRegion(Add, i8 0, OBO::NoUnsignedWrap) == Full Set + static ConstantRange makeNoWrapRegion(Instruction::BinaryOps BinOp, + const APInt &C, unsigned NoWrapKind); + /// Return the lower value for this range. /// const APInt &getLower() const { return Lower; } @@ -207,7 +218,7 @@ public: /// Make this range have the bit width given by \p BitWidth. The /// value is zero extended, truncated, or left alone to make it that width. ConstantRange zextOrTrunc(uint32_t BitWidth) const; - + /// Make this range have the bit width given by \p BitWidth. The /// value is sign extended, truncated, or left alone to make it that width. ConstantRange sextOrTrunc(uint32_t BitWidth) const; @@ -258,7 +269,7 @@ public: /// Return a new range that is the logical not of the current set. /// ConstantRange inverse() const; - + /// Print out the bounds to a stream. /// void print(raw_ostream &OS) const; diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index 0c7a84fc8bfe..a5a20c9c5701 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -590,7 +590,7 @@ public: /// formed with a vector or array of the specified element type. /// ConstantDataArray only works with normal float and int types that are /// stored densely in memory, not with things like i42 or x86_f80. - static bool isElementTypeCompatible(const Type *Ty); + static bool isElementTypeCompatible(Type *Ty); /// getElementAsInteger - If this is a sequential container of integers (of /// any size), return the specified element in the low bits of a uint64_t. @@ -795,7 +795,32 @@ public: } }; +//===----------------------------------------------------------------------===// +/// ConstantTokenNone - a constant token which is empty +/// +class ConstantTokenNone : public Constant { + void *operator new(size_t, unsigned) = delete; + ConstantTokenNone(const ConstantTokenNone &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + +protected: + explicit ConstantTokenNone(LLVMContext &Context) + : Constant(Type::getTokenTy(Context), ConstantTokenNoneVal, nullptr, 0) {} + // allocate space for exactly zero operands + void *operator new(size_t s) { return User::operator new(s, 0); } + +public: + /// Return the ConstantTokenNone. + static ConstantTokenNone *get(LLVMContext &Context); + /// @brief Methods to support type inquiry through isa, cast, and dyn_cast. + static bool classof(const Value *V) { + return V->getValueID() == ConstantTokenNoneVal; + } +}; /// BlockAddress - The address of a basic block. /// @@ -1175,7 +1200,8 @@ public: /// gets constant-folded, the type changes, or the expression is otherwise /// canonicalized. This parameter should almost always be \c false. Constant *getWithOperands(ArrayRef<Constant *> Ops, Type *Ty, - bool OnlyIfReduced = false) const; + bool OnlyIfReduced = false, + Type *SrcTy = nullptr) const; /// getAsInstruction - Returns an Instruction which implements the same /// operation as this ConstantExpr. The instruction is not linked to any basic diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index aa43c02d5cd8..aeec39541154 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -158,7 +158,9 @@ namespace llvm { /// Create debugging information entry for a c++ /// style reference or rvalue reference type. - DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy); + DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy, + uint64_t SizeInBits = 0, + uint64_t AlignInBits = 0); /// Create debugging information entry for a typedef. /// \param Ty Original type. @@ -375,15 +377,20 @@ namespace llvm { DIType *UnderlyingType, StringRef UniqueIdentifier = ""); /// Create subroutine type. - /// \param File File in which this subroutine is defined. /// \param ParameterTypes An array of subroutine parameter types. This /// includes return type at 0th index. /// \param Flags E.g.: LValueReference. /// These flags are used to emit dwarf attributes. - DISubroutineType *createSubroutineType(DIFile *File, - DITypeRefArray ParameterTypes, + DISubroutineType *createSubroutineType(DITypeRefArray ParameterTypes, unsigned Flags = 0); + /// Create an external type reference. + /// \param Tag Dwarf TAG. + /// \param File File in which the type is defined. + /// \param UniqueIdentifier A unique identifier for the type. + DICompositeType *createExternalTypeRef(unsigned Tag, DIFile *File, + StringRef UniqueIdentifier); + /// Create a new DIType* with "artificial" flag set. DIType *createArtificialType(DIType *Ty); @@ -450,26 +457,36 @@ namespace llvm { unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val, MDNode *Decl = nullptr); - /// Create a new descriptor for the specified - /// local variable. - /// \param Tag Dwarf TAG. Usually DW_TAG_auto_variable or - /// DW_TAG_arg_variable. - /// \param Scope Variable scope. - /// \param Name Variable name. - /// \param File File where this variable is defined. - /// \param LineNo Line number. - /// \param Ty Variable Type - /// \param AlwaysPreserve Boolean. Set to true if debug info for this - /// variable should be preserved in optimized build. - /// \param Flags Flags, e.g. artificial variable. - /// \param ArgNo If this variable is an argument then this argument's - /// number. 1 indicates 1st argument. - DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope, - StringRef Name, DIFile *File, - unsigned LineNo, DIType *Ty, + /// Create a new descriptor for an auto variable. This is a local variable + /// that is not a subprogram parameter. + /// + /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually + /// leads to a \a DISubprogram. + /// + /// If \c AlwaysPreserve, this variable will be referenced from its + /// containing subprogram, and will survive some optimizations. + DILocalVariable *createAutoVariable(DIScope *Scope, StringRef Name, + DIFile *File, unsigned LineNo, + DIType *Ty, bool AlwaysPreserve = false, - unsigned Flags = 0, - unsigned ArgNo = 0); + unsigned Flags = 0); + + /// Create a new descriptor for a parameter variable. + /// + /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually + /// leads to a \a DISubprogram. + /// + /// \c ArgNo is the index (starting from \c 1) of this variable in the + /// subprogram parameters. \c ArgNo should not conflict with other + /// parameters of the same subprogram. + /// + /// If \c AlwaysPreserve, this variable will be referenced from its + /// containing subprogram, and will survive some optimizations. + DILocalVariable *createParameterVariable(DIScope *Scope, StringRef Name, + unsigned ArgNo, DIFile *File, + unsigned LineNo, DIType *Ty, + bool AlwaysPreserve = false, + unsigned Flags = 0); /// Create a new descriptor for the specified /// variable which has a complex address expression for its address. @@ -499,15 +516,15 @@ namespace llvm { /// \param Flags e.g. is this function prototyped or not. /// These flags are used to emit dwarf attributes. /// \param isOptimized True if optimization is ON. - /// \param Fn llvm::Function pointer. - /// \param TParam Function template parameters. - DISubprogram * - createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned LineNo, DISubroutineType *Ty, - bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, - unsigned Flags = 0, bool isOptimized = false, - Function *Fn = nullptr, MDNode *TParam = nullptr, - MDNode *Decl = nullptr); + /// \param TParams Function template parameters. + DISubprogram *createFunction(DIScope *Scope, StringRef Name, + StringRef LinkageName, DIFile *File, + unsigned LineNo, DISubroutineType *Ty, + bool isLocalToUnit, bool isDefinition, + unsigned ScopeLine, unsigned Flags = 0, + bool isOptimized = false, + DITemplateParameterArray TParams = nullptr, + DISubprogram *Decl = nullptr); /// Identical to createFunction, /// except that the resulting DbgNode is meant to be RAUWed. @@ -515,18 +532,19 @@ namespace llvm { DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags = 0, - bool isOptimized = false, Function *Fn = nullptr, - MDNode *TParam = nullptr, MDNode *Decl = nullptr); + bool isOptimized = false, DITemplateParameterArray TParams = nullptr, + DISubprogram *Decl = nullptr); /// FIXME: this is added for dragonegg. Once we update dragonegg /// to call resolve function, this will be removed. - DISubprogram * - createFunction(DIScopeRef Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned LineNo, DISubroutineType *Ty, - bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, - unsigned Flags = 0, bool isOptimized = false, - Function *Fn = nullptr, MDNode *TParam = nullptr, - MDNode *Decl = nullptr); + DISubprogram *createFunction(DIScopeRef Scope, StringRef Name, + StringRef LinkageName, DIFile *File, + unsigned LineNo, DISubroutineType *Ty, + bool isLocalToUnit, bool isDefinition, + unsigned ScopeLine, unsigned Flags = 0, + bool isOptimized = false, + DITemplateParameterArray TParams = nullptr, + DISubprogram *Decl = nullptr); /// Create a new descriptor for the specified C++ method. /// See comments in \a DISubprogram* for descriptions of these fields. @@ -545,15 +563,14 @@ namespace llvm { /// \param Flags e.g. is this function prototyped or not. /// This flags are used to emit dwarf attributes. /// \param isOptimized True if optimization is ON. - /// \param Fn llvm::Function pointer. - /// \param TParam Function template parameters. + /// \param TParams Function template parameters. DISubprogram * createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0, DIType *VTableHolder = nullptr, unsigned Flags = 0, bool isOptimized = false, - Function *Fn = nullptr, MDNode *TParam = nullptr); + DITemplateParameterArray TParams = nullptr); /// This creates new descriptor for a namespace with the specified /// parent scope. @@ -685,7 +702,7 @@ namespace llvm { /// has a self-reference -- \a DIBuilder needs to track the array to /// resolve cycles. void replaceArrays(DICompositeType *&T, DINodeArray Elements, - DINodeArray TParems = DINodeArray()); + DINodeArray TParams = DINodeArray()); /// Replace a temporary node. /// diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index 892d6c9936c0..19a3a6661feb 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -475,7 +475,8 @@ inline LLVMTargetDataRef wrap(const DataLayout *P) { class StructLayout { uint64_t StructSize; unsigned StructAlignment; - unsigned NumElements; + bool IsPadded : 1; + unsigned NumElements : 31; uint64_t MemberOffsets[1]; // variable sized array! public: uint64_t getSizeInBytes() const { return StructSize; } @@ -484,6 +485,10 @@ public: unsigned getAlignment() const { return StructAlignment; } + /// Returns whether the struct has padding or not between its fields. + /// NB: Padding in nested element is not taken into account. + bool hasPadding() const { return IsPadded; } + /// \brief Given a valid byte offset into the structure, returns the structure /// index that contains it. unsigned getElementContainingOffset(uint64_t Offset) const; diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 5429648ade2c..4caceacbb58e 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -44,9 +44,6 @@ DISubprogram *getDISubprogram(const MDNode *Scope); /// \returns a valid subprogram, if found. Otherwise, return \c nullptr. DISubprogram *getDISubprogram(const Function *F); -/// \brief Find underlying composite type. -DICompositeTypeBase *getDICompositeType(DIType *T); - /// \brief Generate map by visiting all retained types. DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); @@ -108,23 +105,23 @@ public: typedef SmallVectorImpl<DIScope *>::const_iterator scope_iterator; iterator_range<compile_unit_iterator> compile_units() const { - return iterator_range<compile_unit_iterator>(CUs.begin(), CUs.end()); + return make_range(CUs.begin(), CUs.end()); } iterator_range<subprogram_iterator> subprograms() const { - return iterator_range<subprogram_iterator>(SPs.begin(), SPs.end()); + return make_range(SPs.begin(), SPs.end()); } iterator_range<global_variable_iterator> global_variables() const { - return iterator_range<global_variable_iterator>(GVs.begin(), GVs.end()); + return make_range(GVs.begin(), GVs.end()); } iterator_range<type_iterator> types() const { - return iterator_range<type_iterator>(TYs.begin(), TYs.end()); + return make_range(TYs.begin(), TYs.end()); } iterator_range<scope_iterator> scopes() const { - return iterator_range<scope_iterator>(Scopes.begin(), Scopes.end()); + return make_range(Scopes.begin(), Scopes.end()); } unsigned compile_unit_count() const { return CUs.size(); } @@ -146,8 +143,6 @@ private: bool TypeMapInitialized; }; -DenseMap<const Function *, DISubprogram *> makeSubprogramMap(const Module &M); - } // end namespace llvm #endif diff --git a/include/llvm/IR/DebugInfoFlags.def b/include/llvm/IR/DebugInfoFlags.def index d5de8683fd3b..9756c12264b4 100644 --- a/include/llvm/IR/DebugInfoFlags.def +++ b/include/llvm/IR/DebugInfoFlags.def @@ -32,5 +32,6 @@ HANDLE_DI_FLAG((1 << 11), Vector) HANDLE_DI_FLAG((1 << 12), StaticMember) HANDLE_DI_FLAG((1 << 13), LValueReference) HANDLE_DI_FLAG((1 << 14), RValueReference) +HANDLE_DI_FLAG((1 << 15), ExternalTypeRef) #undef HANDLE_DI_FLAG diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 9c5a95721d79..456313a70e83 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -20,15 +20,7 @@ // Helper macros for defining get() overrides. #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__ #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS -#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ - static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ - return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \ - } \ - static CLASS *getIfExists(LLVMContext &Context, \ - DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ - return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \ - /* ShouldCreate */ false); \ - } \ +#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \ static CLASS *getDistinct(LLVMContext &Context, \ DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \ @@ -38,6 +30,16 @@ return Temp##CLASS( \ getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \ } +#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ + static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ + return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \ + } \ + static CLASS *getIfExists(LLVMContext &Context, \ + DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ + return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \ + /* ShouldCreate */ false); \ + } \ + DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) namespace llvm { @@ -67,8 +69,8 @@ public: operator Metadata *() const { return const_cast<Metadata *>(MD); } - bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }; - bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }; + bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; } + bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; } /// \brief Create a reference. /// @@ -97,6 +99,7 @@ class DITypeRefArray { const MDTuple *N = nullptr; public: + DITypeRefArray() = default; DITypeRefArray(const MDTuple *N) : N(N) {} explicit operator bool() const { return get(); } @@ -574,6 +577,7 @@ public: bool isStaticMember() const { return getFlags() & FlagStaticMember; } bool isLValueReference() const { return getFlags() & FlagLValueReference; } bool isRValueReference() const { return getFlags() & FlagRValueReference; } + bool isExternalTypeRef() const { return getFlags() & FlagExternalTypeRef; } DITypeRef getRef() const { return DITypeRef::get(this); } @@ -646,45 +650,21 @@ public: } }; -/// \brief Base class for DIDerivedType and DICompositeType. -/// -/// TODO: Delete; they're not really related. -class DIDerivedTypeBase : public DIType { -protected: - DIDerivedTypeBase(LLVMContext &C, unsigned ID, StorageType Storage, - unsigned Tag, unsigned Line, uint64_t SizeInBits, - uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, - ArrayRef<Metadata *> Ops) - : DIType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, - Flags, Ops) {} - ~DIDerivedTypeBase() = default; - -public: - DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } - Metadata *getRawBaseType() const { return getOperand(3); } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == DIDerivedTypeKind || - MD->getMetadataID() == DICompositeTypeKind || - MD->getMetadataID() == DISubroutineTypeKind; - } -}; - /// \brief Derived types. /// /// This includes qualified types, pointers, references, friends, typedefs, and /// class members. /// /// TODO: Split out members (inheritance, fields, methods, etc.). -class DIDerivedType : public DIDerivedTypeBase { +class DIDerivedType : public DIType { friend class LLVMContextImpl; friend class MDNode; DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops) - : DIDerivedTypeBase(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, - AlignInBits, OffsetInBits, Flags, Ops) {} + : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, + AlignInBits, OffsetInBits, Flags, Ops) {} ~DIDerivedType() = default; static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag, @@ -732,6 +712,10 @@ public: TempDIDerivedType clone() const { return cloneImpl(); } + //// Get the base type this is derived from. + DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } + Metadata *getRawBaseType() const { return getOperand(3); } + /// \brief Get extra data associated with this derived type. /// /// Class type for pointer-to-members, objective-c property node for ivars, @@ -764,88 +748,23 @@ public: } }; -/// \brief Base class for DICompositeType and DISubroutineType. -/// -/// TODO: Delete; they're not really related. -class DICompositeTypeBase : public DIDerivedTypeBase { - unsigned RuntimeLang; - -protected: - DICompositeTypeBase(LLVMContext &C, unsigned ID, StorageType Storage, - unsigned Tag, unsigned Line, unsigned RuntimeLang, - uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - ArrayRef<Metadata *> Ops) - : DIDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, - OffsetInBits, Flags, Ops), - RuntimeLang(RuntimeLang) {} - ~DICompositeTypeBase() = default; - -public: - /// \brief Get the elements of the composite type. - /// - /// \note Calling this is only valid for \a DICompositeType. This assertion - /// can be removed once \a DISubroutineType has been separated from - /// "composite types". - DINodeArray getElements() const { - assert(!isa<DISubroutineType>(this) && "no elements for DISubroutineType"); - return cast_or_null<MDTuple>(getRawElements()); - } - DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); } - DITemplateParameterArray getTemplateParams() const { - return cast_or_null<MDTuple>(getRawTemplateParams()); - } - StringRef getIdentifier() const { return getStringOperand(7); } - unsigned getRuntimeLang() const { return RuntimeLang; } - - Metadata *getRawElements() const { return getOperand(4); } - Metadata *getRawVTableHolder() const { return getOperand(5); } - Metadata *getRawTemplateParams() const { return getOperand(6); } - MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); } - - /// \brief Replace operands. - /// - /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision - /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track - /// of its movement if necessary. - /// @{ - void replaceElements(DINodeArray Elements) { -#ifndef NDEBUG - for (DINode *Op : getElements()) - assert(std::find(Elements->op_begin(), Elements->op_end(), Op) && - "Lost a member during member list replacement"); -#endif - replaceOperandWith(4, Elements.get()); - } - void replaceVTableHolder(DITypeRef VTableHolder) { - replaceOperandWith(5, VTableHolder); - } - void replaceTemplateParams(DITemplateParameterArray TemplateParams) { - replaceOperandWith(6, TemplateParams.get()); - } - /// @} - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == DICompositeTypeKind || - MD->getMetadataID() == DISubroutineTypeKind; - } -}; - /// \brief Composite types. /// /// TODO: Detach from DerivedTypeBase (split out MDEnumType?). /// TODO: Create a custom, unrelated node for DW_TAG_array_type. -class DICompositeType : public DICompositeTypeBase { +class DICompositeType : public DIType { friend class LLVMContextImpl; friend class MDNode; + unsigned RuntimeLang; + DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops) - : DICompositeTypeBase(C, DICompositeTypeKind, Storage, Tag, Line, - RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, - Flags, Ops) {} + : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits, + AlignInBits, OffsetInBits, Flags, Ops), + RuntimeLang(RuntimeLang) {} ~DICompositeType() = default; static DICompositeType * @@ -903,6 +822,45 @@ public: TempDICompositeType clone() const { return cloneImpl(); } + DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } + DINodeArray getElements() const { + return cast_or_null<MDTuple>(getRawElements()); + } + DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); } + DITemplateParameterArray getTemplateParams() const { + return cast_or_null<MDTuple>(getRawTemplateParams()); + } + StringRef getIdentifier() const { return getStringOperand(7); } + unsigned getRuntimeLang() const { return RuntimeLang; } + + Metadata *getRawBaseType() const { return getOperand(3); } + Metadata *getRawElements() const { return getOperand(4); } + Metadata *getRawVTableHolder() const { return getOperand(5); } + Metadata *getRawTemplateParams() const { return getOperand(6); } + MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); } + + /// \brief Replace operands. + /// + /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision + /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track + /// of its movement if necessary. + /// @{ + void replaceElements(DINodeArray Elements) { +#ifndef NDEBUG + for (DINode *Op : getElements()) + assert(std::find(Elements->op_begin(), Elements->op_end(), Op) && + "Lost a member during member list replacement"); +#endif + replaceOperandWith(4, Elements.get()); + } + void replaceVTableHolder(DITypeRef VTableHolder) { + replaceOperandWith(5, VTableHolder); + } + void replaceTemplateParams(DITemplateParameterArray TemplateParams) { + replaceOperandWith(6, TemplateParams.get()); + } + /// @} + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DICompositeTypeKind; } @@ -918,17 +876,15 @@ template <class T> TypedDINodeRef<T> TypedDINodeRef<T>::get(const T *N) { /// \brief Type array for a subprogram. /// -/// TODO: Detach from CompositeType, and fold the array of types in directly -/// as operands. -class DISubroutineType : public DICompositeTypeBase { +/// TODO: Fold the array of types in directly as operands. +class DISubroutineType : public DIType { friend class LLVMContextImpl; friend class MDNode; DISubroutineType(LLVMContext &C, StorageType Storage, unsigned Flags, ArrayRef<Metadata *> Ops) - : DICompositeTypeBase(C, DISubroutineTypeKind, Storage, - dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags, - Ops) {} + : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, + 0, 0, 0, 0, Flags, Ops) {} ~DISubroutineType() = default; static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags, @@ -957,7 +913,7 @@ public: DITypeRefArray getTypeArray() const { return cast_or_null<MDTuple>(getRawTypeArray()); } - Metadata *getRawTypeArray() const { return getRawElements(); } + Metadata *getRawTypeArray() const { return getOperand(3); } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DISubroutineTypeKind; @@ -981,7 +937,9 @@ class DICompileUnit : public DIScope { : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), - DWOId(DWOId) {} + DWOId(DWOId) { + assert(Storage != Uniqued); + } ~DICompileUnit() = default; static DICompileUnit * @@ -991,15 +949,16 @@ class DICompileUnit : public DIScope { unsigned EmissionKind, DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes, DISubprogramArray Subprograms, DIGlobalVariableArray GlobalVariables, - DIImportedEntityArray ImportedEntities, uint64_t DWOId, - StorageType Storage, bool ShouldCreate = true) { + DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, + uint64_t DWOId, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, getCanonicalMDString(Context, SplitDebugFilename), EmissionKind, EnumTypes.get(), RetainedTypes.get(), Subprograms.get(), GlobalVariables.get(), - ImportedEntities.get(), DWOId, Storage, ShouldCreate); + ImportedEntities.get(), Macros.get(), DWOId, Storage, + ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, @@ -1007,40 +966,44 @@ class DICompileUnit : public DIScope { unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *Subprograms, Metadata *GlobalVariables, - Metadata *ImportedEntities, uint64_t DWOId, StorageType Storage, - bool ShouldCreate = true); + Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, + StorageType Storage, bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { return getTemporary( getContext(), getSourceLanguage(), getFile(), getProducer(), isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(), getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(), - getGlobalVariables(), getImportedEntities(), DWOId); + getGlobalVariables(), getImportedEntities(), getMacros(), DWOId); } + static void get() = delete; + static void getIfExists() = delete; + public: - DEFINE_MDNODE_GET(DICompileUnit, - (unsigned SourceLanguage, DIFile *File, StringRef Producer, - bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, - StringRef SplitDebugFilename, unsigned EmissionKind, - DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes, - DISubprogramArray Subprograms, - DIGlobalVariableArray GlobalVariables, - DIImportedEntityArray ImportedEntities, uint64_t DWOId), - (SourceLanguage, File, Producer, IsOptimized, Flags, - RuntimeVersion, SplitDebugFilename, EmissionKind, - EnumTypes, RetainedTypes, Subprograms, GlobalVariables, - ImportedEntities, DWOId)) - DEFINE_MDNODE_GET( + DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( + DICompileUnit, + (unsigned SourceLanguage, DIFile *File, StringRef Producer, + bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, + StringRef SplitDebugFilename, unsigned EmissionKind, + DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes, + DISubprogramArray Subprograms, DIGlobalVariableArray GlobalVariables, + DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, + uint64_t DWOId), + (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, + SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms, + GlobalVariables, ImportedEntities, Macros, DWOId)) + DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *Subprograms, - Metadata *GlobalVariables, Metadata *ImportedEntities, uint64_t DWOId), + Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, + uint64_t DWOId), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms, - GlobalVariables, ImportedEntities, DWOId)) + GlobalVariables, ImportedEntities, Macros, DWOId)) TempDICompileUnit clone() const { return cloneImpl(); } @@ -1066,7 +1029,11 @@ public: DIImportedEntityArray getImportedEntities() const { return cast_or_null<MDTuple>(getRawImportedEntities()); } - unsigned getDWOId() const { return DWOId; } + DIMacroNodeArray getMacros() const { + return cast_or_null<MDTuple>(getRawMacros()); + } + uint64_t getDWOId() const { return DWOId; } + void setDWOId(uint64_t DwoId) { DWOId = DwoId; } MDString *getRawProducer() const { return getOperandAs<MDString>(1); } MDString *getRawFlags() const { return getOperandAs<MDString>(2); } @@ -1078,6 +1045,7 @@ public: Metadata *getRawSubprograms() const { return getOperand(6); } Metadata *getRawGlobalVariables() const { return getOperand(7); } Metadata *getRawImportedEntities() const { return getOperand(8); } + Metadata *getRawMacros() const { return getOperand(9); } /// \brief Replace arrays. /// @@ -1100,6 +1068,7 @@ public: void replaceImportedEntities(DIImportedEntityArray N) { replaceOperandWith(8, N.get()); } + void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(9, N.get()); } /// @} static bool classof(const Metadata *MD) { @@ -1157,8 +1126,10 @@ class DILocation : public MDNode { } TempDILocation cloneImpl() const { - return getTemporary(getContext(), getLine(), getColumn(), getScope(), - getInlinedAt()); + // Get the raw scope/inlinedAt since it is possible to invoke this on + // a DILocation containing temporary metadata. + return getTemporary(getContext(), getLine(), getColumn(), getRawScope(), + getRawInlinedAt()); } // Disallow replacing operands. @@ -1276,14 +1247,13 @@ class DISubprogram : public DILocalScope { DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Constant *Function, DITemplateParameterArray TemplateParams, - DISubprogram *Declaration, DILocalVariableArray Variables, - StorageType Storage, bool ShouldCreate = true) { + DITemplateParameterArray TemplateParams, DISubprogram *Declaration, + DILocalVariableArray Variables, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, - Function ? ConstantAsMetadata::get(Function) : nullptr, TemplateParams.get(), Declaration, Variables.get(), Storage, ShouldCreate); } @@ -1292,17 +1262,16 @@ class DISubprogram : public DILocalScope { MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - unsigned Flags, bool IsOptimized, Metadata *Function, - Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, - StorageType Storage, bool ShouldCreate = true); + unsigned Flags, bool IsOptimized, Metadata *TemplateParams, + Metadata *Declaration, Metadata *Variables, StorageType Storage, + bool ShouldCreate = true); TempDISubprogram cloneImpl() const { - return getTemporary(getContext(), getScope(), getName(), getLinkageName(), - getFile(), getLine(), getType(), isLocalToUnit(), - isDefinition(), getScopeLine(), getContainingType(), - getVirtuality(), getVirtualIndex(), getFlags(), - isOptimized(), getFunctionConstant(), - getTemplateParams(), getDeclaration(), getVariables()); + return getTemporary( + getContext(), getScope(), getName(), getLinkageName(), getFile(), + getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(), + getContainingType(), getVirtuality(), getVirtualIndex(), getFlags(), + isOptimized(), getTemplateParams(), getDeclaration(), getVariables()); } public: @@ -1312,13 +1281,12 @@ public: bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Constant *Function = nullptr, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, DILocalVariableArray Variables = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, Function, TemplateParams, + VirtualIndex, Flags, IsOptimized, TemplateParams, Declaration, Variables)) DEFINE_MDNODE_GET( DISubprogram, @@ -1326,11 +1294,11 @@ public: unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Metadata *Function = nullptr, Metadata *TemplateParams = nullptr, - Metadata *Declaration = nullptr, Metadata *Variables = nullptr), + Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, + Metadata *Variables = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, - Function, TemplateParams, Declaration, Variables)) + TemplateParams, Declaration, Variables)) TempDISubprogram clone() const { return cloneImpl(); } @@ -1389,11 +1357,6 @@ public: return DITypeRef(getRawContainingType()); } - Constant *getFunctionConstant() const { - if (auto *C = cast_or_null<ConstantAsMetadata>(getRawFunction())) - return C->getValue(); - return nullptr; - } DITemplateParameterArray getTemplateParams() const { return cast_or_null<MDTuple>(getRawTemplateParams()); } @@ -1407,30 +1370,11 @@ public: Metadata *getRawScope() const { return getOperand(1); } Metadata *getRawType() const { return getOperand(5); } Metadata *getRawContainingType() const { return getOperand(6); } - Metadata *getRawFunction() const { return getOperand(7); } - Metadata *getRawTemplateParams() const { return getOperand(8); } - Metadata *getRawDeclaration() const { return getOperand(9); } - Metadata *getRawVariables() const { return getOperand(10); } - - /// \brief Get a pointer to the function this subprogram describes. - /// - /// This dyn_casts \a getFunctionConstant() to \a Function. - /// - /// FIXME: Should this be looking through bitcasts? - Function *getFunction() const; - - /// \brief Replace the function. - /// - /// If \a isUniqued() and not \a isResolved(), this could node will be - /// RAUW'ed and deleted out from under the caller. Use a \a TrackingMDRef if - /// that's a problem. - /// @{ - void replaceFunction(Function *F); - void replaceFunction(ConstantAsMetadata *MD) { replaceOperandWith(7, MD); } - void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); } - /// @} + Metadata *getRawTemplateParams() const { return getOperand(7); } + Metadata *getRawDeclaration() const { return getOperand(8); } + Metadata *getRawVariables() const { return getOperand(9); } - /// \brief Check if this subprogram decribes the given function. + /// \brief Check if this subprogram describes the given function. /// /// FIXME: Should this be looking through bitcasts? bool describes(const Function *F) const; @@ -1452,13 +1396,6 @@ public: Metadata *getRawScope() const { return getOperand(1); } - /// \brief Forwarding accessors to LexicalBlock. - /// - /// TODO: Remove these and update code to use \a DILexicalBlock directly. - /// @{ - inline unsigned getLine() const; - inline unsigned getColumn() const; - /// @} static bool classof(const Metadata *MD) { return MD->getMetadataID() == DILexicalBlockKind || MD->getMetadataID() == DILexicalBlockFileKind; @@ -1470,12 +1407,14 @@ class DILexicalBlock : public DILexicalBlockBase { friend class MDNode; unsigned Line; - unsigned Column; + uint16_t Column; DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line, unsigned Column, ArrayRef<Metadata *> Ops) : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line), - Column(Column) {} + Column(Column) { + assert(Column < (1u << 16) && "Expected 16-bit column"); + } ~DILexicalBlock() = default; static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope, @@ -1514,18 +1453,6 @@ public: } }; -unsigned DILexicalBlockBase::getLine() const { - if (auto *N = dyn_cast<DILexicalBlock>(this)) - return N->getLine(); - return 0; -} - -unsigned DILexicalBlockBase::getColumn() const { - if (auto *N = dyn_cast<DILexicalBlock>(this)) - return N->getColumn(); - return 0; -} - class DILexicalBlockFile : public DILexicalBlockBase { friend class LLVMContextImpl; friend class MDNode; @@ -1797,15 +1724,13 @@ public: }; /// \brief Base class for variables. -/// -/// TODO: Hardcode to DW_TAG_variable. class DIVariable : public DINode { unsigned Line; protected: - DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, - unsigned Line, ArrayRef<Metadata *> Ops) - : DINode(C, ID, Storage, Tag, Ops), Line(Line) {} + DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line, + ArrayRef<Metadata *> Ops) + : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {} ~DIVariable() = default; public: @@ -1850,8 +1775,7 @@ class DIGlobalVariable : public DIVariable { DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line, bool IsLocalToUnit, bool IsDefinition, ArrayRef<Metadata *> Ops) - : DIVariable(C, DIGlobalVariableKind, Storage, dwarf::DW_TAG_variable, - Line, Ops), + : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} ~DIGlobalVariable() = default; @@ -1923,8 +1847,6 @@ public: /// \brief Local variable. /// -/// TODO: Split between arguments and otherwise. -/// TODO: Use \c DW_TAG_variable instead of fake tags. /// TODO: Split up flags. class DILocalVariable : public DIVariable { friend class LLVMContextImpl; @@ -1933,42 +1855,42 @@ class DILocalVariable : public DIVariable { unsigned Arg; unsigned Flags; - DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Tag, - unsigned Line, unsigned Arg, unsigned Flags, - ArrayRef<Metadata *> Ops) - : DIVariable(C, DILocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg), + DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line, + unsigned Arg, unsigned Flags, ArrayRef<Metadata *> Ops) + : DIVariable(C, DILocalVariableKind, Storage, Line, Ops), Arg(Arg), Flags(Flags) {} ~DILocalVariable() = default; - static DILocalVariable *getImpl(LLVMContext &Context, unsigned Tag, - DIScope *Scope, StringRef Name, DIFile *File, - unsigned Line, DITypeRef Type, unsigned Arg, - unsigned Flags, StorageType Storage, + static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope, + StringRef Name, DIFile *File, unsigned Line, + DITypeRef Type, unsigned Arg, unsigned Flags, + StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name), - File, Line, Type, Arg, Flags, Storage, ShouldCreate); + return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File, + Line, Type, Arg, Flags, Storage, ShouldCreate); } - static DILocalVariable * - getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name, - Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, - unsigned Flags, StorageType Storage, bool ShouldCreate = true); + static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope, + MDString *Name, Metadata *File, unsigned Line, + Metadata *Type, unsigned Arg, unsigned Flags, + StorageType Storage, + bool ShouldCreate = true); TempDILocalVariable cloneImpl() const { - return getTemporary(getContext(), getTag(), getScope(), getName(), - getFile(), getLine(), getType(), getArg(), getFlags()); + return getTemporary(getContext(), getScope(), getName(), getFile(), + getLine(), getType(), getArg(), getFlags()); } public: DEFINE_MDNODE_GET(DILocalVariable, - (unsigned Tag, DILocalScope *Scope, StringRef Name, - DIFile *File, unsigned Line, DITypeRef Type, unsigned Arg, + (DILocalScope * Scope, StringRef Name, DIFile *File, + unsigned Line, DITypeRef Type, unsigned Arg, unsigned Flags), - (Tag, Scope, Name, File, Line, Type, Arg, Flags)) + (Scope, Name, File, Line, Type, Arg, Flags)) DEFINE_MDNODE_GET(DILocalVariable, - (unsigned Tag, Metadata *Scope, MDString *Name, - Metadata *File, unsigned Line, Metadata *Type, - unsigned Arg, unsigned Flags), - (Tag, Scope, Name, File, Line, Type, Arg, Flags)) + (Metadata * Scope, MDString *Name, Metadata *File, + unsigned Line, Metadata *Type, unsigned Arg, + unsigned Flags), + (Scope, Name, File, Line, Type, Arg, Flags)) TempDILocalVariable clone() const { return cloneImpl(); } @@ -1979,6 +1901,7 @@ public: return cast<DILocalScope>(DIVariable::getScope()); } + bool isParameter() const { return Arg; } unsigned getArg() const { return Arg; } unsigned getFlags() const { return Flags; } @@ -1988,7 +1911,7 @@ public: /// \brief Check that a location is valid for this variable. /// /// Check that \c DL exists, is in the same subprogram, and has the same - /// inlined-at location as \c this. (Otherwise, it's not a valid attachemnt + /// inlined-at location as \c this. (Otherwise, it's not a valid attachment /// to a \a DbgInfoIntrinsic.) bool isValidLocationForIntrinsic(const DILocation *DL) const { return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram(); @@ -2284,6 +2207,165 @@ public: } }; +/// \brief Macro Info DWARF-like metadata node. +/// +/// A metadata node with a DWARF macro info (i.e., a constant named +/// \c DW_MACINFO_*, defined in llvm/Support/Dwarf.h). Called \a DIMacroNode +/// because it's potentially used for non-DWARF output. +class DIMacroNode : public MDNode { + friend class LLVMContextImpl; + friend class MDNode; + +protected: + DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType, + ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None) + : MDNode(C, ID, Storage, Ops1, Ops2) { + assert(MIType < 1u << 16); + SubclassData16 = MIType; + } + ~DIMacroNode() = default; + + template <class Ty> Ty *getOperandAs(unsigned I) const { + return cast_or_null<Ty>(getOperand(I)); + } + + StringRef getStringOperand(unsigned I) const { + if (auto *S = getOperandAs<MDString>(I)) + return S->getString(); + return StringRef(); + } + + static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) { + if (S.empty()) + return nullptr; + return MDString::get(Context, S); + } + +public: + unsigned getMacinfoType() const { return SubclassData16; } + + static bool classof(const Metadata *MD) { + switch (MD->getMetadataID()) { + default: + return false; + case DIMacroKind: + case DIMacroFileKind: + return true; + } + } +}; + +class DIMacro : public DIMacroNode { + friend class LLVMContextImpl; + friend class MDNode; + + unsigned Line; + + DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line, + ArrayRef<Metadata *> Ops) + : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {} + ~DIMacro() = default; + + static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, + StringRef Name, StringRef Value, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name), + getCanonicalMDString(Context, Value), Storage, ShouldCreate); + } + static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, + MDString *Name, MDString *Value, StorageType Storage, + bool ShouldCreate = true); + + TempDIMacro cloneImpl() const { + return getTemporary(getContext(), getMacinfoType(), getLine(), getName(), + getValue()); + } + +public: + DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name, + StringRef Value = ""), + (MIType, Line, Name, Value)) + DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name, + MDString *Value), + (MIType, Line, Name, Value)) + + TempDIMacro clone() const { return cloneImpl(); } + + unsigned getLine() const { return Line; } + + StringRef getName() const { return getStringOperand(0); } + StringRef getValue() const { return getStringOperand(1); } + + MDString *getRawName() const { return getOperandAs<MDString>(0); } + MDString *getRawValue() const { return getOperandAs<MDString>(1); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DIMacroKind; + } +}; + +class DIMacroFile : public DIMacroNode { + friend class LLVMContextImpl; + friend class MDNode; + + unsigned Line; + + DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType, + unsigned Line, ArrayRef<Metadata *> Ops) + : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {} + ~DIMacroFile() = default; + + static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType, + unsigned Line, DIFile *File, + DIMacroNodeArray Elements, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, MIType, Line, static_cast<Metadata *>(File), + Elements.get(), Storage, ShouldCreate); + } + + static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType, + unsigned Line, Metadata *File, Metadata *Elements, + StorageType Storage, bool ShouldCreate = true); + + TempDIMacroFile cloneImpl() const { + return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(), + getElements()); + } + +public: + DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File, + DIMacroNodeArray Elements), + (MIType, Line, File, Elements)) + DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, + Metadata *File, Metadata *Elements), + (MIType, Line, File, Elements)) + + TempDIMacroFile clone() const { return cloneImpl(); } + + void replaceElements(DIMacroNodeArray Elements) { +#ifndef NDEBUG + for (DIMacroNode *Op : getElements()) + assert(std::find(Elements->op_begin(), Elements->op_end(), Op) && + "Lost a macro node during macro node list replacement"); +#endif + replaceOperandWith(1, Elements.get()); + } + + unsigned getLine() const { return Line; } + DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } + + DIMacroNodeArray getElements() const { + return cast_or_null<MDTuple>(getRawElements()); + } + + Metadata *getRawFile() const { return getOperand(0); } + Metadata *getRawElements() const { return getOperand(1); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DIMacroFileKind; + } +}; + } // end namespace llvm #undef DEFINE_MDNODE_GET_UNPACK_IMPL diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 4a94499b4cf5..071e69b1e808 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -36,11 +36,12 @@ class StringRef; /// @brief Integer representation type class IntegerType : public Type { friend class LLVMContextImpl; - + protected: explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){ setSubclassData(NumBits); } + public: /// This enum is just used to hold constants we need for IntegerType. enum { @@ -90,6 +91,9 @@ public: } }; +unsigned Type::getIntegerBitWidth() const { + return cast<IntegerType>(this)->getBitWidth(); +} /// FunctionType - Class to represent function types /// @@ -108,7 +112,7 @@ public: /// FunctionType::get - Create a FunctionType taking no parameters. /// static FunctionType *get(Type *Result, bool isVarArg); - + /// isValidReturnType - Return true if the specified type is valid as a return /// type. static bool isValidReturnType(Type *RetTy); @@ -143,18 +147,30 @@ public: static_assert(AlignOf<FunctionType>::Alignment >= AlignOf<Type *>::Alignment, "Alignment sufficient for objects appended to FunctionType"); +bool Type::isFunctionVarArg() const { + return cast<FunctionType>(this)->isVarArg(); +} + +Type *Type::getFunctionParamType(unsigned i) const { + return cast<FunctionType>(this)->getParamType(i); +} + +unsigned Type::getFunctionNumParams() const { + return cast<FunctionType>(this)->getNumParams(); +} + /// CompositeType - Common super class of ArrayType, StructType, PointerType /// and VectorType. class CompositeType : public Type { protected: - explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { } -public: + explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {} +public: /// getTypeAtIndex - Given an index value into the type, return the type of /// the element. /// - Type *getTypeAtIndex(const Value *V); - Type *getTypeAtIndex(unsigned Idx); + Type *getTypeAtIndex(const Value *V) const; + Type *getTypeAtIndex(unsigned Idx) const; bool indexValid(const Value *V) const; bool indexValid(unsigned Idx) const; @@ -167,14 +183,13 @@ public: } }; - /// StructType - Class to represent struct types. There are two different kinds /// of struct types: Literal structs and Identified structs. /// /// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must /// always have a body when created. You can get one of these by using one of /// the StructType::get() forms. -/// +/// /// Identified structs (e.g. %foo or %42) may optionally have a name and are not /// uniqued. The names for identified structs are managed at the LLVMContext /// level, so there can only be a single identified struct with a given name in @@ -205,23 +220,20 @@ class StructType : public CompositeType { /// pointer to the symbol table entry (maintained by LLVMContext) for the /// struct. This is null if the type is an literal struct or if it is /// a identified type that has an empty name. - /// + /// void *SymbolTableEntry; -public: +public: /// StructType::create - This creates an identified struct. static StructType *create(LLVMContext &Context, StringRef Name); static StructType *create(LLVMContext &Context); - - static StructType *create(ArrayRef<Type*> Elements, - StringRef Name, - bool isPacked = false); - static StructType *create(ArrayRef<Type*> Elements); - static StructType *create(LLVMContext &Context, - ArrayRef<Type*> Elements, - StringRef Name, + + static StructType *create(ArrayRef<Type *> Elements, StringRef Name, bool isPacked = false); - static StructType *create(LLVMContext &Context, ArrayRef<Type*> Elements); + static StructType *create(ArrayRef<Type *> Elements); + static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements, + StringRef Name, bool isPacked = false); + static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements); static StructType *create(StringRef Name, Type *elt1, ...) LLVM_END_WITH_NULL; /// StructType::get - This static method is the primary way to create a @@ -232,7 +244,7 @@ public: /// StructType::get - Create an empty structure type. /// static StructType *get(LLVMContext &Context, bool isPacked = false); - + /// StructType::get - This static method is a convenience method for creating /// structure types by specifying the elements as arguments. Note that this /// method always returns a non-packed struct, and requires at least one @@ -240,26 +252,26 @@ public: static StructType *get(Type *elt1, ...) LLVM_END_WITH_NULL; bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } - + /// isLiteral - Return true if this type is uniqued by structural /// equivalence, false if it is a struct definition. bool isLiteral() const { return (getSubclassData() & SCDB_IsLiteral) != 0; } - + /// isOpaque - Return true if this is a type with an identity that has no body /// specified yet. These prints as 'opaque' in .ll files. bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; } /// isSized - Return true if this is a sized type. - bool isSized(SmallPtrSetImpl<const Type*> *Visited = nullptr) const; - + bool isSized(SmallPtrSetImpl<Type *> *Visited = nullptr) const; + /// hasName - Return true if this is a named struct that has a non-empty name. bool hasName() const { return SymbolTableEntry != nullptr; } - + /// getName - Return the name for this struct type if it has an identity. /// This may return an empty string for an unnamed struct type. Do not call /// this on an literal type. StringRef getName() const; - + /// setName - Change the name of this type to the specified name, or to a name /// with a suffix if there is a collision. Do not call this on an literal /// type. @@ -268,11 +280,10 @@ public: /// setBody - Specify a body for an opaque identified type. void setBody(ArrayRef<Type*> Elements, bool isPacked = false); void setBody(Type *elt1, ...) LLVM_END_WITH_NULL; - + /// isValidElementType - Return true if the specified type is valid as a /// element type. static bool isValidElementType(Type *ElemTy); - // Iterator access to the elements. typedef Type::subtype_iterator element_iterator; @@ -284,8 +295,8 @@ public: /// isLayoutIdentical - Return true if this is layout identical to the /// specified struct. - bool isLayoutIdentical(StructType *Other) const; - + bool isLayoutIdentical(StructType *Other) const; + /// Random access to the elements unsigned getNumElements() const { return NumContainedTys; } Type *getElementType(unsigned N) const { @@ -299,6 +310,18 @@ public: } }; +StringRef Type::getStructName() const { + return cast<StructType>(this)->getName(); +} + +unsigned Type::getStructNumElements() const { + return cast<StructType>(this)->getNumElements(); +} + +Type *Type::getStructElementType(unsigned N) const { + return cast<StructType>(this)->getElementType(N); +} + /// SequentialType - This is the superclass of the array, pointer and vector /// type classes. All of these represent "arrays" in memory. The array type /// represents a specifically sized array, pointer types are unsized/unknown @@ -330,6 +353,9 @@ public: } }; +Type *Type::getSequentialElementType() const { + return cast<SequentialType>(this)->getElementType(); +} /// ArrayType - Class to represent array types. /// @@ -339,6 +365,7 @@ class ArrayType : public SequentialType { ArrayType(const ArrayType &) = delete; const ArrayType &operator=(const ArrayType &) = delete; ArrayType(Type *ElType, uint64_t NumEl); + public: /// ArrayType::get - This static method is the primary way to construct an /// ArrayType @@ -357,6 +384,10 @@ public: } }; +uint64_t Type::getArrayNumElements() const { + return cast<ArrayType>(this)->getNumElements(); +} + /// VectorType - Class to represent vector types. /// class VectorType : public SequentialType { @@ -365,6 +396,7 @@ class VectorType : public SequentialType { VectorType(const VectorType &) = delete; const VectorType &operator=(const VectorType &) = delete; VectorType(Type *ElType, unsigned NumEl); + public: /// VectorType::get - This static method is the primary way to construct an /// VectorType. @@ -443,6 +475,9 @@ public: } }; +unsigned Type::getVectorNumElements() const { + return cast<VectorType>(this)->getNumElements(); +} /// PointerType - Class to represent pointers. /// @@ -450,6 +485,7 @@ class PointerType : public SequentialType { PointerType(const PointerType &) = delete; const PointerType &operator=(const PointerType &) = delete; explicit PointerType(Type *ElType, unsigned AddrSpace); + public: /// PointerType::get - This constructs a pointer to an object of the specified /// type in a numbered address space. @@ -477,6 +513,10 @@ public: } }; +unsigned Type::getPointerAddressSpace() const { + return cast<PointerType>(getScalarType())->getAddressSpace(); +} + } // End llvm namespace #endif diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index f38313f82ea7..f69955e5ed48 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -15,7 +15,6 @@ #ifndef LLVM_IR_DIAGNOSTICINFO_H #define LLVM_IR_DIAGNOSTICINFO_H -#include "llvm-c/Core.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Module.h" @@ -56,8 +55,11 @@ enum DiagnosticKind { DK_OptimizationRemark, DK_OptimizationRemarkMissed, DK_OptimizationRemarkAnalysis, + DK_OptimizationRemarkAnalysisFPCommute, + DK_OptimizationRemarkAnalysisAliasing, DK_OptimizationFailure, DK_MIRParser, + DK_PGOProfile, DK_FirstPluginKind }; @@ -99,6 +101,8 @@ public: /// The printed message must not end with '.' nor start with a severity /// keyword. virtual void print(DiagnosticPrinter &DP) const = 0; + + static const char *AlwaysPrint; }; typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction; @@ -210,19 +214,18 @@ public: /// Diagnostic information for the sample profiler. class DiagnosticInfoSampleProfile : public DiagnosticInfo { public: - DiagnosticInfoSampleProfile(const char *FileName, unsigned LineNum, + DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum, const Twine &Msg, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), LineNum(LineNum), Msg(Msg) {} - DiagnosticInfoSampleProfile(const char *FileName, const Twine &Msg, + DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), LineNum(0), Msg(Msg) {} DiagnosticInfoSampleProfile(const Twine &Msg, DiagnosticSeverity Severity = DS_Error) - : DiagnosticInfo(DK_SampleProfile, Severity), FileName(nullptr), - LineNum(0), Msg(Msg) {} + : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {} /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; @@ -231,13 +234,13 @@ public: return DI->getKind() == DK_SampleProfile; } - const char *getFileName() const { return FileName; } + StringRef getFileName() const { return FileName; } unsigned getLineNum() const { return LineNum; } const Twine &getMsg() const { return Msg; } private: /// Name of the input file associated with this diagnostic. - const char *FileName; + StringRef FileName; /// Line number where the diagnostic occurred. If 0, no line number will /// be emitted in the message. @@ -247,6 +250,31 @@ private: const Twine &Msg; }; +/// Diagnostic information for the PGO profiler. +class DiagnosticInfoPGOProfile : public DiagnosticInfo { +public: + DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg, + DiagnosticSeverity Severity = DS_Error) + : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {} + + /// \see DiagnosticInfo::print. + void print(DiagnosticPrinter &DP) const override; + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_PGOProfile; + } + + const char *getFileName() const { return FileName; } + const Twine &getMsg() const { return Msg; } + +private: + /// Name of the input file associated with this diagnostic. + const char *FileName; + + /// Message to report. + const Twine &Msg; +}; + /// Common features for diagnostics dealing with optimization remarks. class DiagnosticInfoOptimizationBase : public DiagnosticInfo { public: @@ -267,10 +295,6 @@ public: /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; - static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() == DK_OptimizationRemark; - } - /// Return true if this optimization remark is enabled by one of /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed, /// or -pass-remarks-analysis). Note that this only handles the LLVM @@ -386,6 +410,69 @@ public: /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override; + +protected: + DiagnosticInfoOptimizationRemarkAnalysis(enum DiagnosticKind Kind, + const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg) + : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, + Msg) {} +}; + +/// Diagnostic information for optimization analysis remarks related to +/// floating-point non-commutativity. +class DiagnosticInfoOptimizationRemarkAnalysisFPCommute + : public DiagnosticInfoOptimizationRemarkAnalysis { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If + /// this name matches the regular expression given in -Rpass-analysis=, then + /// the diagnostic will be emitted. \p Fn is the function where the diagnostic + /// is being emitted. \p DLoc is the location information to use in the + /// diagnostic. If line table information is available, the diagnostic will + /// include the source code location. \p Msg is the message to show. The + /// front-end will append its own message related to options that address + /// floating-point non-commutativity. Note that this class does not copy this + /// message, so this reference must be valid for the whole life time of the + /// diagnostic. + DiagnosticInfoOptimizationRemarkAnalysisFPCommute(const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg) + : DiagnosticInfoOptimizationRemarkAnalysis( + DK_OptimizationRemarkAnalysisFPCommute, PassName, Fn, DLoc, Msg) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute; + } +}; + +/// Diagnostic information for optimization analysis remarks related to +/// pointer aliasing. +class DiagnosticInfoOptimizationRemarkAnalysisAliasing + : public DiagnosticInfoOptimizationRemarkAnalysis { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If + /// this name matches the regular expression given in -Rpass-analysis=, then + /// the diagnostic will be emitted. \p Fn is the function where the diagnostic + /// is being emitted. \p DLoc is the location information to use in the + /// diagnostic. If line table information is available, the diagnostic will + /// include the source code location. \p Msg is the message to show. The + /// front-end will append its own message related to options that address + /// pointer aliasing legality. Note that this class does not copy this + /// message, so this reference must be valid for the whole life time of the + /// diagnostic. + DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg) + : DiagnosticInfoOptimizationRemarkAnalysis( + DK_OptimizationRemarkAnalysisAliasing, PassName, Fn, DLoc, Msg) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing; + } }; /// Diagnostic information for machine IR parser. @@ -438,6 +525,30 @@ void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg); +/// Emit an optimization analysis remark related to messages about +/// floating-point non-commutativity. \p PassName is the name of the pass +/// emitting the message. If -Rpass-analysis= is given and \p PassName matches +/// the regular expression in -Rpass, then the remark will be emitted. \p Fn is +/// the function triggering the remark, \p DLoc is the debug location where the +/// diagnostic is generated. \p Msg is the message string to use. +void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx, + const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg); + +/// Emit an optimization analysis remark related to messages about +/// pointer aliasing. \p PassName is the name of the pass emitting the message. +/// If -Rpass-analysis= is given and \p PassName matches the regular expression +/// in -Rpass, then the remark will be emitted. \p Fn is the function triggering +/// the remark, \p DLoc is the debug location where the diagnostic is generated. +/// \p Msg is the message string to use. +void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx, + const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg); + /// Diagnostic information for optimization failures. class DiagnosticInfoOptimizationFailure : public DiagnosticInfoOptimizationBase { diff --git a/include/llvm/IR/DiagnosticPrinter.h b/include/llvm/IR/DiagnosticPrinter.h index 735e3ad7a8b0..1bcd73738b66 100644 --- a/include/llvm/IR/DiagnosticPrinter.h +++ b/include/llvm/IR/DiagnosticPrinter.h @@ -63,7 +63,7 @@ protected: raw_ostream &Stream; public: - DiagnosticPrinterRawOStream(raw_ostream &Stream) : Stream(Stream) {}; + DiagnosticPrinterRawOStream(raw_ostream &Stream) : Stream(Stream) {} // Simple types. DiagnosticPrinter &operator<<(char C) override; diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index 27d989b0344c..37447c353b19 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -64,11 +64,30 @@ public: /// \brief Concrete subclass of DominatorTreeBase that is used to compute a /// normal dominator tree. +/// +/// Definition: A block is said to be forward statically reachable if there is +/// a path from the entry of the function to the block. A statically reachable +/// block may become statically unreachable during optimization. +/// +/// A forward unreachable block may appear in the dominator tree, or it may +/// not. If it does, dominance queries will return results as if all reachable +/// blocks dominate it. When asking for a Node corresponding to a potentially +/// unreachable block, calling code must handle the case where the block was +/// unreachable and the result of getNode() is nullptr. +/// +/// Generally, a block known to be unreachable when the dominator tree is +/// constructed will not be in the tree. One which becomes unreachable after +/// the dominator tree is initially constructed may still exist in the tree, +/// even if the tree is properly updated. Calling code should not rely on the +/// preceding statements; this is stated only to assist human understanding. class DominatorTree : public DominatorTreeBase<BasicBlock> { public: typedef DominatorTreeBase<BasicBlock> Base; DominatorTree() : DominatorTreeBase<BasicBlock>(false) {} + explicit DominatorTree(Function &F) : DominatorTreeBase<BasicBlock>(false) { + recalculate(F); + } DominatorTree(DominatorTree &&Arg) : Base(std::move(static_cast<Base &>(Arg))) {} @@ -122,31 +141,35 @@ public: // DominatorTree GraphTraits specializations so the DominatorTree can be // iterable by generic graph iterators. -template <> struct GraphTraits<DomTreeNode*> { - typedef DomTreeNode NodeType; - typedef NodeType::iterator ChildIteratorType; +template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase { + typedef Node NodeType; + typedef ChildIterator ChildIteratorType; + typedef df_iterator<Node *, SmallPtrSet<NodeType *, 8>> nodes_iterator; - static NodeType *getEntryNode(NodeType *N) { - return N; - } + static NodeType *getEntryNode(NodeType *N) { return N; } static inline ChildIteratorType child_begin(NodeType *N) { return N->begin(); } - static inline ChildIteratorType child_end(NodeType *N) { - return N->end(); - } + static inline ChildIteratorType child_end(NodeType *N) { return N->end(); } - typedef df_iterator<DomTreeNode*> nodes_iterator; - - static nodes_iterator nodes_begin(DomTreeNode *N) { + static nodes_iterator nodes_begin(NodeType *N) { return df_begin(getEntryNode(N)); } - static nodes_iterator nodes_end(DomTreeNode *N) { + static nodes_iterator nodes_end(NodeType *N) { return df_end(getEntryNode(N)); } }; +template <> +struct GraphTraits<DomTreeNode *> + : public DomTreeGraphTraitsBase<DomTreeNode, DomTreeNode::iterator> {}; + +template <> +struct GraphTraits<const DomTreeNode *> + : public DomTreeGraphTraitsBase<const DomTreeNode, + DomTreeNode::const_iterator> {}; + template <> struct GraphTraits<DominatorTree*> : public GraphTraits<DomTreeNode*> { static NodeType *getEntryNode(DominatorTree *DT) { diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index ec9f4cad094a..2a983930bf4d 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -32,28 +32,16 @@ namespace llvm { class FunctionType; class LLVMContext; +class DISubprogram; -template<> struct ilist_traits<Argument> - : public SymbolTableListTraits<Argument, Function> { - - Argument *createSentinel() const { - return static_cast<Argument*>(&Sentinel); - } - static void destroySentinel(Argument*) {} - - Argument *provideInitialHead() const { return createSentinel(); } - Argument *ensureHead(Argument*) const { return createSentinel(); } - static void noteHead(Argument*, Argument*) {} - - static ValueSymbolTable *getSymTab(Function *ItemParent); -private: - mutable ilist_half_node<Argument> Sentinel; -}; +template <> +struct SymbolTableListSentinelTraits<Argument> + : public ilist_half_embedded_sentinel_traits<Argument> {}; class Function : public GlobalObject, public ilist_node<Function> { public: - typedef iplist<Argument> ArgumentListType; - typedef iplist<BasicBlock> BasicBlockListType; + typedef SymbolTableList<Argument> ArgumentListType; + typedef SymbolTableList<BasicBlock> BasicBlockListType; // BasicBlock iterators... typedef BasicBlockListType::iterator iterator; @@ -73,10 +61,12 @@ private: /* * Value::SubclassData * - * bit 0 : HasLazyArguments - * bit 1 : HasPrefixData - * bit 2 : HasPrologueData - * bit 3-6: CallingConvention + * bit 0 : HasLazyArguments + * bit 1 : HasPrefixData + * bit 2 : HasPrologueData + * bit 3 : HasPersonalityFn + * bits 4-13 : CallingConvention + * bits 14-15 : [reserved] */ /// Bits from GlobalObject::GlobalObjectSubclassData. @@ -90,7 +80,7 @@ private: (Value ? Mask : 0u)); } - friend class SymbolTableListTraits<Function, Module>; + friend class SymbolTableListTraits<Function>; void setParent(Module *parent); @@ -120,7 +110,7 @@ private: public: static Function *Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N = "", Module *M = nullptr) { - return new(1) Function(Ty, Linkage, N, M); + return new Function(Ty, Linkage, N, M); } ~Function() override; @@ -128,14 +118,6 @@ public: /// \brief Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// \brief Get the personality function associated with this function. - bool hasPersonalityFn() const { return getNumOperands() != 0; } - Constant *getPersonalityFn() const { - assert(hasPersonalityFn()); - return cast<Constant>(Op<0>()); - } - void setPersonalityFn(Constant *C); - Type *getReturnType() const; // Return the type of the ret val FunctionType *getFunctionType() const; // Return the FunctionType for me @@ -170,11 +152,13 @@ public: /// calling convention of this function. The enum values for the known /// calling conventions are defined in CallingConv.h. CallingConv::ID getCallingConv() const { - return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 3); + return static_cast<CallingConv::ID>((getSubclassDataFromValue() >> 4) & + CallingConv::MaxID); } void setCallingConv(CallingConv::ID CC) { - setValueSubclassData((getSubclassDataFromValue() & 7) | - (static_cast<unsigned>(CC) << 3)); + auto ID = static_cast<unsigned>(CC); + assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention"); + setValueSubclassData((getSubclassDataFromValue() & 0xc00f) | (ID << 4)); } /// @brief Return the attribute list for this Function. @@ -267,13 +251,13 @@ public: uint64_t getDereferenceableBytes(unsigned i) const { return AttributeSets.getDereferenceableBytes(i); } - + /// @brief Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). uint64_t getDereferenceableOrNullBytes(unsigned i) const { return AttributeSets.getDereferenceableOrNullBytes(i); } - + /// @brief Determine if the function does not access memory. bool doesNotAccessMemory() const { return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, @@ -299,10 +283,28 @@ public: return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly); } - void setOnlyAccessesArgMemory() { - addFnAttr(Attribute::ArgMemOnly); + void setOnlyAccessesArgMemory() { addFnAttr(Attribute::ArgMemOnly); } + + /// @brief Determine if the function may only access memory that is + /// inaccessible from the IR. + bool onlyAccessesInaccessibleMemory() const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::InaccessibleMemOnly); + } + void setOnlyAccessesInaccessibleMemory() { + addFnAttr(Attribute::InaccessibleMemOnly); } - + + /// @brief Determine if the function may only access memory that is + // either inaccessible from the IR or pointed to by its arguments. + bool onlyAccessesInaccessibleMemOrArgMem() const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::InaccessibleMemOrArgMemOnly); + } + void setOnlyAccessesInaccessibleMemOrArgMem() { + addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); + } + /// @brief Determine if the function cannot return. bool doesNotReturn() const { return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, @@ -339,6 +341,15 @@ public: addFnAttr(Attribute::Convergent); } + /// Determine if the function is known not to recurse, directly or + /// indirectly. + bool doesNotRecurse() const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::NoRecurse); + } + void setDoesNotRecurse() { + addFnAttr(Attribute::NoRecurse); + } /// @brief True if the ABI mandates (or the user requested) that this /// function be in a unwind table. @@ -362,7 +373,8 @@ public: AttributeSets.hasAttribute(2, Attribute::StructRet); } - /// @brief Determine if the parameter does not alias other parameters. + /// @brief Determine if the parameter or return value is marked with NoAlias + /// attribute. /// @param n The parameter to check. 1 is the first parameter, 0 is the return bool doesNotAlias(unsigned n) const { return AttributeSets.hasAttribute(n, Attribute::NoAlias); @@ -395,6 +407,14 @@ public: addAttribute(n, Attribute::ReadOnly); } + /// Optimize this function for minimum size (-Oz). + bool optForMinSize() const { return hasFnAttribute(Attribute::MinSize); }; + + /// Optimize this function for size (-Os) or minimum size (-Oz). + bool optForSize() const { + return hasFnAttribute(Attribute::OptimizeForSize) || optForMinSize(); + } + /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a Function) from the Function Src to this one. void copyAttributesFrom(const GlobalValue *Src) override; @@ -417,7 +437,6 @@ public: /// void eraseFromParent() override; - /// Get the underlying elements of the Function... the basic block list is /// empty for external functions. /// @@ -429,13 +448,13 @@ public: CheckLazyArguments(); return ArgumentList; } - static iplist<Argument> Function::*getSublistAccess(Argument*) { + static ArgumentListType Function::*getSublistAccess(Argument*) { return &Function::ArgumentList; } const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; } BasicBlockListType &getBasicBlockList() { return BasicBlocks; } - static iplist<BasicBlock> Function::*getSublistAccess(BasicBlock*) { + static BasicBlockListType Function::*getSublistAccess(BasicBlock*) { return &Function::BasicBlocks; } @@ -450,7 +469,6 @@ public: inline ValueSymbolTable &getValueSymbolTable() { return *SymTab; } inline const ValueSymbolTable &getValueSymbolTable() const { return *SymTab; } - //===--------------------------------------------------------------------===// // BasicBlock iterator forwarding functions // @@ -487,11 +505,11 @@ public: } iterator_range<arg_iterator> args() { - return iterator_range<arg_iterator>(arg_begin(), arg_end()); + return make_range(arg_begin(), arg_end()); } iterator_range<const_arg_iterator> args() const { - return iterator_range<const_arg_iterator>(arg_begin(), arg_end()); + return make_range(arg_begin(), arg_end()); } /// @} @@ -499,24 +517,33 @@ public: size_t arg_size() const; bool arg_empty() const; + /// \brief Check whether this function has a personality function. + bool hasPersonalityFn() const { + return getSubclassDataFromValue() & (1<<3); + } + + /// \brief Get the personality function associated with this function. + Constant *getPersonalityFn() const; + void setPersonalityFn(Constant *Fn); + + /// \brief Check whether this function has prefix data. bool hasPrefixData() const { return getSubclassDataFromValue() & (1<<1); } + /// \brief Get the prefix data associated with this function. Constant *getPrefixData() const; void setPrefixData(Constant *PrefixData); + /// \brief Check whether this function has prologue data. bool hasPrologueData() const { return getSubclassDataFromValue() & (1<<2); } + /// \brief Get the prologue data associated with this function. Constant *getPrologueData() const; void setPrologueData(Constant *PrologueData); - /// Print the function to an output stream with an optional - /// AssemblyAnnotationWriter. - void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW = nullptr) const; - /// viewCFG - This function is meant for use from the debugger. You can just /// say 'call F->viewCFG()' and a ghostview window should pop up from the /// program, displaying the CFG of the current function with the code for each @@ -596,12 +623,27 @@ public: /// Drop all metadata from \c this not included in \c KnownIDs. void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs); + /// \brief Set the attached subprogram. + /// + /// Calls \a setMetadata() with \a LLVMContext::MD_dbg. + void setSubprogram(DISubprogram *SP); + + /// \brief Get the attached subprogram. + /// + /// Calls \a getMetadata() with \a LLVMContext::MD_dbg and casts the result + /// to \a DISubprogram. + DISubprogram *getSubprogram() const; + private: + void allocHungoffUselist(); + template<int Idx> void setHungoffOperand(Constant *C); + // Shadow Value::setValueSubclassData with a private forwarding method so that // subclasses cannot accidentally use it. void setValueSubclassData(unsigned short D) { Value::setValueSubclassData(D); } + void setValueSubclassDataBit(unsigned Bit, bool On); bool hasMetadataHashEntry() const { return getGlobalObjectSubClassData() & HasMetadataHashEntryBit; @@ -613,18 +655,8 @@ private: void clearMetadata(); }; -inline ValueSymbolTable * -ilist_traits<BasicBlock>::getSymTab(Function *F) { - return F ? &F->getValueSymbolTable() : nullptr; -} - -inline ValueSymbolTable * -ilist_traits<Argument>::getSymTab(Function *F) { - return F ? &F->getValueSymbolTable() : nullptr; -} - template <> -struct OperandTraits<Function> : public OptionalOperandTraits<Function> {}; +struct OperandTraits<Function> : public HungoffOperandTraits<3> {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(Function, Value) diff --git a/include/llvm/IR/FunctionInfo.h b/include/llvm/IR/FunctionInfo.h new file mode 100644 index 000000000000..eba088a61bc0 --- /dev/null +++ b/include/llvm/IR/FunctionInfo.h @@ -0,0 +1,241 @@ +//===-- llvm/FunctionInfo.h - Function Info Index ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// @file +/// FunctionInfo.h This file contains the declarations the classes that hold +/// the function info index and summary. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_FUNCTIONINFO_H +#define LLVM_IR_FUNCTIONINFO_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +/// \brief Function summary information to aid decisions and implementation of +/// importing. +/// +/// This is a separate class from FunctionInfo to enable lazy reading of this +/// function summary information from the combined index file during imporing. +class FunctionSummary { +private: + /// \brief Path of module containing function IR, used to locate module when + /// importing this function. + /// + /// This is only used during parsing of the combined function index, or when + /// parsing the per-module index for creation of the combined function index, + /// not during writing of the per-module index which doesn't contain a + /// module path string table. + StringRef ModulePath; + + /// \brief Used to flag functions that have local linkage types and need to + /// have module identifier appended before placing into the combined + /// index, to disambiguate from other functions with the same name. + /// + /// This is only used in the per-module function index, as it is consumed + /// while creating the combined index. + bool IsLocalFunction; + + // The rest of the information is used to help decide whether importing + // is likely to be profitable. + // Other information will be added as the importing is tuned, such + // as hotness (when profile available), and other function characteristics. + + /// Number of instructions (ignoring debug instructions, e.g.) computed + /// during the initial compile step when the function index is first built. + unsigned InstCount; + +public: + /// Construct a summary object from summary data expected for all + /// summary records. + FunctionSummary(unsigned NumInsts) : InstCount(NumInsts) {} + + /// Set the path to the module containing this function, for use in + /// the combined index. + void setModulePath(StringRef ModPath) { ModulePath = ModPath; } + + /// Get the path to the module containing this function. + StringRef modulePath() const { return ModulePath; } + + /// Record whether this is a local function in the per-module index. + void setLocalFunction(bool IsLocal) { IsLocalFunction = IsLocal; } + + /// Check whether this was a local function, for use in creating + /// the combined index. + bool isLocalFunction() const { return IsLocalFunction; } + + /// Get the instruction count recorded for this function. + unsigned instCount() const { return InstCount; } +}; + +/// \brief Class to hold pointer to function summary and information required +/// for parsing it. +/// +/// For the per-module index, this holds the bitcode offset +/// of the corresponding function block. For the combined index, +/// after parsing of the \a ValueSymbolTable, this initially +/// holds the offset of the corresponding function summary bitcode +/// record. After parsing the associated summary information from the summary +/// block the \a FunctionSummary is populated and stored here. +class FunctionInfo { +private: + /// Function summary information used to help make ThinLTO importing + /// decisions. + std::unique_ptr<FunctionSummary> Summary; + + /// \brief The bitcode offset corresponding to either the associated + /// function's function body record, or its function summary record, + /// depending on whether this is a per-module or combined index. + /// + /// This bitcode offset is written to or read from the associated + /// \a ValueSymbolTable entry for the function. + /// For the per-module index this holds the bitcode offset of the + /// function's body record within bitcode module block in its module, + /// which is used during lazy function parsing or ThinLTO importing. + /// For the combined index this holds the offset of the corresponding + /// function summary record, to enable associating the combined index + /// VST records with the summary records. + uint64_t BitcodeIndex; + +public: + /// Constructor used during parsing of VST entries. + FunctionInfo(uint64_t FuncOffset) + : Summary(nullptr), BitcodeIndex(FuncOffset) {} + + /// Constructor used for per-module index bitcode writing. + FunctionInfo(uint64_t FuncOffset, + std::unique_ptr<FunctionSummary> FuncSummary) + : Summary(std::move(FuncSummary)), BitcodeIndex(FuncOffset) {} + + /// Record the function summary information parsed out of the function + /// summary block during parsing or combined index creation. + void setFunctionSummary(std::unique_ptr<FunctionSummary> FuncSummary) { + Summary = std::move(FuncSummary); + } + + /// Get the function summary recorded for this function. + FunctionSummary *functionSummary() const { return Summary.get(); } + + /// Get the bitcode index recorded for this function, depending on + /// the index type. + uint64_t bitcodeIndex() const { return BitcodeIndex; } + + /// Record the bitcode index for this function, depending on + /// the index type. + void setBitcodeIndex(uint64_t FuncOffset) { BitcodeIndex = FuncOffset; } +}; + +/// List of function info structures for a particular function name held +/// in the FunctionMap. Requires a vector in the case of multiple +/// COMDAT functions of the same name. +typedef std::vector<std::unique_ptr<FunctionInfo>> FunctionInfoList; + +/// Map from function name to corresponding function info structures. +typedef StringMap<FunctionInfoList> FunctionInfoMapTy; + +/// Type used for iterating through the function info map. +typedef FunctionInfoMapTy::const_iterator const_funcinfo_iterator; +typedef FunctionInfoMapTy::iterator funcinfo_iterator; + +/// String table to hold/own module path strings, which additionally holds the +/// module ID assigned to each module during the plugin step. The StringMap +/// makes a copy of and owns inserted strings. +typedef StringMap<uint64_t> ModulePathStringTableTy; + +/// Class to hold module path string table and function map, +/// and encapsulate methods for operating on them. +class FunctionInfoIndex { +private: + /// Map from function name to list of function information instances + /// for functions of that name (may be duplicates in the COMDAT case, e.g.). + FunctionInfoMapTy FunctionMap; + + /// Holds strings for combined index, mapping to the corresponding module ID. + ModulePathStringTableTy ModulePathStringTable; + +public: + FunctionInfoIndex() = default; + + // Disable the copy constructor and assignment operators, so + // no unexpected copying/moving occurs. + FunctionInfoIndex(const FunctionInfoIndex &) = delete; + void operator=(const FunctionInfoIndex &) = delete; + + funcinfo_iterator begin() { return FunctionMap.begin(); } + const_funcinfo_iterator begin() const { return FunctionMap.begin(); } + funcinfo_iterator end() { return FunctionMap.end(); } + const_funcinfo_iterator end() const { return FunctionMap.end(); } + + /// Get the list of function info objects for a given function. + const FunctionInfoList &getFunctionInfoList(StringRef FuncName) { + return FunctionMap[FuncName]; + } + + /// Get the list of function info objects for a given function. + const const_funcinfo_iterator findFunctionInfoList(StringRef FuncName) const { + return FunctionMap.find(FuncName); + } + + /// Add a function info for a function of the given name. + void addFunctionInfo(StringRef FuncName, std::unique_ptr<FunctionInfo> Info) { + FunctionMap[FuncName].push_back(std::move(Info)); + } + + /// Iterator to allow writer to walk through table during emission. + iterator_range<StringMap<uint64_t>::const_iterator> + modPathStringEntries() const { + return llvm::make_range(ModulePathStringTable.begin(), + ModulePathStringTable.end()); + } + + /// Get the module ID recorded for the given module path. + uint64_t getModuleId(const StringRef ModPath) const { + return ModulePathStringTable.lookup(ModPath); + } + + /// Add the given per-module index into this function index/summary, + /// assigning it the given module ID. Each module merged in should have + /// a unique ID, necessary for consistent renaming of promoted + /// static (local) variables. + void mergeFrom(std::unique_ptr<FunctionInfoIndex> Other, + uint64_t NextModuleId); + + /// Convenience method for creating a promoted global name + /// for the given value name of a local, and its original module's ID. + static std::string getGlobalNameForLocal(StringRef Name, uint64_t ModId) { + SmallString<256> NewName(Name); + NewName += ".llvm."; + raw_svector_ostream(NewName) << ModId; + return NewName.str(); + } + + /// Add a new module path, mapped to the given module Id, and return StringRef + /// owned by string table map. + StringRef addModulePath(StringRef ModPath, uint64_t ModId) { + return ModulePathStringTable.insert(std::make_pair(ModPath, ModId)) + .first->first(); + } + + /// Check if the given Module has any functions available for exporting + /// in the index. We consider any module present in the ModulePathStringTable + /// to have exported functions. + bool hasExportedFunctions(const Module &M) const { + return ModulePathStringTable.count(M.getModuleIdentifier()); + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h index 1d6c9157f0b8..6cb593c7a3da 100644 --- a/include/llvm/IR/GVMaterializer.h +++ b/include/llvm/IR/GVMaterializer.h @@ -18,12 +18,14 @@ #ifndef LLVM_IR_GVMATERIALIZER_H #define LLVM_IR_GVMATERIALIZER_H +#include "llvm/ADT/DenseMap.h" #include <system_error> #include <vector> namespace llvm { class Function; class GlobalValue; +class Metadata; class Module; class StructType; @@ -34,28 +36,25 @@ protected: public: virtual ~GVMaterializer(); - /// True if GV has been materialized and can be dematerialized back to - /// whatever backing store this GVMaterializer uses. - virtual bool isDematerializable(const GlobalValue *GV) const = 0; - /// Make sure the given GlobalValue is fully read. /// virtual std::error_code materialize(GlobalValue *GV) = 0; - /// If the given GlobalValue is read in, and if the GVMaterializer supports - /// it, release the memory for the GV, and set it up to be materialized - /// lazily. If the Materializer doesn't support this capability, this method - /// is a noop. - /// - virtual void dematerialize(GlobalValue *) {} - /// Make sure the entire Module has been completely read. /// - virtual std::error_code materializeModule(Module *M) = 0; + virtual std::error_code materializeModule() = 0; virtual std::error_code materializeMetadata() = 0; virtual void setStripDebugInfo() = 0; + /// Client should define this interface if the mapping between metadata + /// values and value ids needs to be preserved, e.g. across materializer + /// instantiations. If OnlyTempMD is true, only those that have remained + /// temporary metadata are recorded in the map. + virtual void + saveMetadataList(DenseMap<const Metadata *, unsigned> &MetadataToIDs, + bool OnlyTempMD) {} + virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0; }; diff --git a/include/llvm/IR/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h index 6bba0ae29e98..7cb13fa33aa6 100644 --- a/include/llvm/IR/GetElementPtrTypeIterator.h +++ b/include/llvm/IR/GetElementPtrTypeIterator.h @@ -78,7 +78,7 @@ namespace llvm { // current type directly. Type *operator->() const { return operator*(); } - Value *getOperand() const { return *OpIt; } + Value *getOperand() const { return const_cast<Value *>(&**OpIt); } generic_gep_type_iterator& operator++() { // Preincrement if (CurTy.getInt()) { diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index ce73b7af8ca1..b0772143309f 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -23,18 +23,17 @@ namespace llvm { class Module; -template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; +template <typename ValueSubClass> class SymbolTableListTraits; class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> { - friend class SymbolTableListTraits<GlobalAlias, Module>; + friend class SymbolTableListTraits<GlobalAlias>; void operator=(const GlobalAlias &) = delete; GlobalAlias(const GlobalAlias &) = delete; void setParent(Module *parent); - GlobalAlias(PointerType *Ty, LinkageTypes Linkage, const Twine &Name, - Constant *Aliasee, Module *Parent); + GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, + const Twine &Name, Constant *Aliasee, Module *Parent); public: // allocate space for exactly one operand @@ -44,17 +43,19 @@ public: /// If a parent module is specified, the alias is automatically inserted into /// the end of the specified module's alias list. - static GlobalAlias *create(PointerType *Ty, LinkageTypes Linkage, - const Twine &Name, Constant *Aliasee, - Module *Parent); + static GlobalAlias *create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + Constant *Aliasee, Module *Parent); // Without the Aliasee. - static GlobalAlias *create(PointerType *Ty, LinkageTypes Linkage, - const Twine &Name, Module *Parent); + static GlobalAlias *create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + Module *Parent); // The module is taken from the Aliasee. - static GlobalAlias *create(PointerType *Ty, LinkageTypes Linkage, - const Twine &Name, GlobalValue *Aliasee); + static GlobalAlias *create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + GlobalValue *Aliasee); // Type, Parent and AddressSpace taken from the Aliasee. static GlobalAlias *create(LinkageTypes Linkage, const Twine &Name, diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index f0552410b61d..ee111a046d73 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -27,9 +27,11 @@ class GlobalObject : public GlobalValue { GlobalObject(const GlobalObject &) = delete; protected: - GlobalObject(PointerType *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, - LinkageTypes Linkage, const Twine &Name) - : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name), ObjComdat(nullptr) { + GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, + LinkageTypes Linkage, const Twine &Name, + unsigned AddressSpace = 0) + : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace), + ObjComdat(nullptr) { setGlobalValueSubClassData(0); } diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 2961369a7327..4fa4e7daeab0 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -65,15 +65,16 @@ public: }; protected: - GlobalValue(PointerType *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, - LinkageTypes Linkage, const Twine &Name) - : Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage), - Visibility(DefaultVisibility), UnnamedAddr(0), - DllStorageClass(DefaultStorageClass), + GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, + LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace) + : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps), + ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility), + UnnamedAddr(0), DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal), IntID((Intrinsic::ID)0U), Parent(nullptr) { setName(Name); } + Type *ValueType; // Note: VC++ treats enums as signed, so an extra bit is required to prevent // Linkage and Visibility from turning into negative values. LinkageTypes Linkage : 5; // The linkage of this global @@ -184,7 +185,7 @@ public: /// Global values are always pointers. PointerType *getType() const { return cast<PointerType>(User::getType()); } - Type *getValueType() const { return getType()->getElementType(); } + Type *getValueType() const { return ValueType; } static LinkageTypes getLinkOnceLinkage(bool ODR) { return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; @@ -236,7 +237,8 @@ public: /// Whether the definition of this global may be discarded if it is not used /// in its compilation unit. static bool isDiscardableIfUnused(LinkageTypes Linkage) { - return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage); + return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage) || + isAvailableExternallyLinkage(Linkage); } /// Whether the definition of this global may be replaced by something @@ -320,21 +322,11 @@ public: /// function has been read in yet or not. bool isMaterializable() const; - /// Returns true if this function was loaded from a GVMaterializer that's - /// still attached to its Module and that knows how to dematerialize the - /// function. - bool isDematerializable() const; - /// Make sure this GlobalValue is fully read. If the module is corrupt, this /// returns true and fills in the optional string with information about the /// problem. If successful, this returns false. std::error_code materialize(); - /// If this GlobalValue is read in, and if the GVMaterializer supports it, - /// release the memory for the function, and set it up to be materialized - /// lazily. If !isDematerializable(), this method is a noop. - void dematerialize(); - /// @} /// Return true if the primary definition of this global value is outside of diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index a0159830ba3b..342bdc01bfbd 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -29,11 +29,10 @@ namespace llvm { class Module; class Constant; -template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; +template <typename ValueSubClass> class SymbolTableListTraits; class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> { - friend class SymbolTableListTraits<GlobalVariable, Module>; + friend class SymbolTableListTraits<GlobalVariable>; void *operator new(size_t, unsigned) = delete; void operator=(const GlobalVariable &) = delete; GlobalVariable(const GlobalVariable &) = delete; @@ -106,18 +105,13 @@ public: /// hasUniqueInitializer - Whether the global variable has an initializer, and /// any changes made to the initializer will turn up in the final executable. inline bool hasUniqueInitializer() const { - return hasInitializer() && - // It's not safe to modify initializers of global variables with weak - // linkage, because the linker might choose to discard the initializer and - // use the initializer from another instance of the global variable - // instead. It is wrong to modify the initializer of a global variable - // with *_odr linkage because then different instances of the global may - // have different initializers, breaking the One Definition Rule. - !isWeakForLinker() && - // It is not safe to modify initializers of global variables with the - // external_initializer marker since the value may be changed at runtime - // before C++ initializers are evaluated. - !isExternallyInitialized(); + return + // We need to be sure this is the definition that will actually be used + isStrongDefinitionForLinker() && + // It is not safe to modify initializers of global variables with the + // external_initializer marker since the value may be changed at runtime + // before C++ initializers are evaluated. + !isExternallyInitialized(); } /// getInitializer - Return the initializer for this global variable. It is diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index 6c67c79b6c0e..7fe04f2a091a 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -24,6 +24,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Operator.h" #include "llvm/IR/ValueHandle.h" @@ -51,6 +52,7 @@ protected: /// \brief Common base class shared among various IRBuilders. class IRBuilderBase { DebugLoc CurDbgLocation; + protected: BasicBlock *BB; BasicBlock::iterator InsertPt; @@ -58,8 +60,8 @@ protected: MDNode *DefaultFPMathTag; FastMathFlags FMF; -public: +public: IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr) : Context(context), DefaultFPMathTag(FPMathTag), FMF() { ClearInsertionPoint(); @@ -73,7 +75,7 @@ public: /// inserted into a block. void ClearInsertionPoint() { BB = nullptr; - InsertPt = nullptr; + InsertPt.reset(nullptr); } BasicBlock *GetInsertBlock() const { return BB; } @@ -91,8 +93,8 @@ public: /// the specified instruction. void SetInsertPoint(Instruction *I) { BB = I->getParent(); - InsertPt = I; - assert(I != BB->end() && "Can't read debug loc from end()"); + InsertPt = I->getIterator(); + assert(InsertPt != BB->end() && "Can't read debug loc from end()"); SetCurrentDebugLocation(I->getDebugLoc()); } @@ -313,10 +315,8 @@ public: } /// \brief Fetch the type representing a 128-bit integer. - IntegerType *getInt128Ty() { - return Type::getInt128Ty(Context); - } - + IntegerType *getInt128Ty() { return Type::getInt128Ty(Context); } + /// \brief Fetch the type representing an N-bit integer. IntegerType *getIntNTy(unsigned N) { return Type::getIntNTy(Context, N); @@ -426,7 +426,7 @@ public: /// \brief Create a call to Masked Load intrinsic CallInst *CreateMaskedLoad(Value *Ptr, unsigned Align, Value *Mask, - Value *PassThru = 0, const Twine &Name = ""); + Value *PassThru = nullptr, const Twine &Name = ""); /// \brief Create a call to Masked Store intrinsic CallInst *CreateMaskedStore(Value *Val, Value *Ptr, unsigned Align, @@ -445,6 +445,16 @@ public: ArrayRef<Value *> GCArgs, const Twine &Name = ""); + /// \brief Create a call to the experimental.gc.statepoint intrinsic to + /// start a new statepoint sequence. + CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, + Value *ActualCallee, uint32_t Flags, + ArrayRef<Use> CallArgs, + ArrayRef<Use> TransitionArgs, + ArrayRef<Use> DeoptArgs, + ArrayRef<Value *> GCArgs, + const Twine &Name = ""); + // \brief Conveninence function for the common case when CallArgs are filled // in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be // .get()'ed to get the Value pointer. @@ -463,6 +473,15 @@ public: ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name = ""); + /// brief Create an invoke to the experimental.gc.statepoint intrinsic to + /// start a new statepoint sequence. + InvokeInst *CreateGCStatepointInvoke( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, + BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, + ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs, + ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, + const Twine &Name = ""); + // Conveninence function for the common case when CallArgs are filled in using // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to // get the Value *. @@ -516,11 +535,11 @@ template<bool preserveNames = true, typename T = ConstantFolder, typename Inserter = IRBuilderDefaultInserter<preserveNames> > class IRBuilder : public IRBuilderBase, public Inserter { T Folder; + public: - IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), + IRBuilder(LLVMContext &C, const T &F, Inserter I = Inserter(), MDNode *FPMathTag = nullptr) - : IRBuilderBase(C, FPMathTag), Inserter(I), Folder(F) { - } + : IRBuilderBase(C, FPMathTag), Inserter(std::move(I)), Folder(F) {} explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr) : IRBuilderBase(C, FPMathTag), Folder() { @@ -578,12 +597,15 @@ public: //===--------------------------------------------------------------------===// private: - /// \brief Helper to add branch weight metadata onto an instruction. + /// \brief Helper to add branch weight and unpredictable metadata onto an + /// instruction. /// \returns The annotated instruction. template <typename InstTy> - InstTy *addBranchWeights(InstTy *I, MDNode *Weights) { + InstTy *addBranchMetadata(InstTy *I, MDNode *Weights, MDNode *Unpredictable) { if (Weights) I->setMetadata(LLVMContext::MD_prof, Weights); + if (Unpredictable) + I->setMetadata(LLVMContext::MD_unpredictable, Unpredictable); return I; } @@ -620,18 +642,20 @@ public: /// \brief Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, - MDNode *BranchWeights = nullptr) { - return Insert(addBranchWeights(BranchInst::Create(True, False, Cond), - BranchWeights)); + MDNode *BranchWeights = nullptr, + MDNode *Unpredictable = nullptr) { + return Insert(addBranchMetadata(BranchInst::Create(True, False, Cond), + BranchWeights, Unpredictable)); } /// \brief Create a switch instruction with the specified value, default dest, /// and with a hint for the number of cases that will be added (for efficient /// allocation). SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, - MDNode *BranchWeights = nullptr) { - return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases), - BranchWeights)); + MDNode *BranchWeights = nullptr, + MDNode *Unpredictable = nullptr) { + return Insert(addBranchMetadata(SwitchInst::Create(V, Dest, NumCases), + BranchWeights, Unpredictable)); } /// \brief Create an indirect branch instruction with the specified address @@ -667,11 +691,45 @@ public: return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), Name); } + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> OpBundles, + const Twine &Name = "") { + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + OpBundles), Name); + } ResumeInst *CreateResume(Value *Exn) { return Insert(ResumeInst::Create(Exn)); } + CleanupReturnInst *CreateCleanupRet(CleanupPadInst *CleanupPad, + BasicBlock *UnwindBB = nullptr) { + return Insert(CleanupReturnInst::Create(CleanupPad, UnwindBB)); + } + + CatchSwitchInst *CreateCatchSwitch(Value *ParentPad, BasicBlock *UnwindBB, + unsigned NumHandlers, + const Twine &Name = "") { + return Insert(CatchSwitchInst::Create(ParentPad, UnwindBB, NumHandlers), + Name); + } + + CatchPadInst *CreateCatchPad(Value *ParentPad, ArrayRef<Value *> Args, + const Twine &Name = "") { + return Insert(CatchPadInst::Create(ParentPad, Args), Name); + } + + CleanupPadInst *CreateCleanupPad(Value *ParentPad, + ArrayRef<Value *> Args = None, + const Twine &Name = "") { + return Insert(CleanupPadInst::Create(ParentPad, Args), Name); + } + + CatchReturnInst *CreateCatchRet(CatchPadInst *CatchPad, BasicBlock *BB) { + return Insert(CatchReturnInst::Create(CatchPad, BB)); + } + UnreachableInst *CreateUnreachable() { return Insert(new UnreachableInst(Context)); } @@ -700,6 +758,7 @@ private: I->setFastMathFlags(FMF); return I; } + public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -1326,18 +1385,22 @@ public: const Twine &Name = "") { if (V->getType() == DestTy) return V; - if (V->getType()->isPointerTy() && DestTy->isIntegerTy()) + if (V->getType()->getScalarType()->isPointerTy() && + DestTy->getScalarType()->isIntegerTy()) return CreatePtrToInt(V, DestTy, Name); - if (V->getType()->isIntegerTy() && DestTy->isPointerTy()) + if (V->getType()->getScalarType()->isIntegerTy() && + DestTy->getScalarType()->isPointerTy()) return CreateIntToPtr(V, DestTy, Name); return CreateBitCast(V, DestTy, Name); } + private: // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a // compile time error, instead of converting the string to bool for the // isSigned parameter. Value *CreateIntCast(Value *, Type *, const char *) = delete; + public: Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) @@ -1465,18 +1528,30 @@ public: } CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None, + ArrayRef<OperandBundleDef> OpBundles = None, const Twine &Name = "") { - return Insert(CallInst::Create(Callee, Args), Name); + return Insert(CallInst::Create(Callee, Args, OpBundles), Name); + } + + CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args, + const Twine &Name, MDNode *FPMathTag = nullptr) { + PointerType *PTy = cast<PointerType>(Callee->getType()); + FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); + return CreateCall(FTy, Callee, Args, Name, FPMathTag); } CallInst *CreateCall(llvm::FunctionType *FTy, Value *Callee, - ArrayRef<Value *> Args, const Twine &Name = "") { - return Insert(CallInst::Create(FTy, Callee, Args), Name); + ArrayRef<Value *> Args, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + CallInst *CI = CallInst::Create(FTy, Callee, Args); + if (isa<FPMathOperator>(CI)) + CI = cast<CallInst>(AddFPMathAttributes(CI, FPMathTag, FMF)); + return Insert(CI, Name); } CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args, - const Twine &Name = "") { - return CreateCall(Callee->getFunctionType(), Callee, Args, Name); + const Twine &Name = "", MDNode *FPMathTag = nullptr) { + return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag); } Value *CreateSelect(Value *C, Value *True, Value *False, @@ -1594,6 +1669,32 @@ public: Name); } + /// \brief Create an invariant.group.barrier intrinsic call, that stops + /// optimizer to propagate equality using invariant.group metadata. + /// If Ptr type is different from i8*, it's casted to i8* before call + /// and casted back to Ptr type after call. + Value *CreateInvariantGroupBarrier(Value *Ptr) { + Module *M = BB->getParent()->getParent(); + Function *FnInvariantGroupBarrier = Intrinsic::getDeclaration(M, + Intrinsic::invariant_group_barrier); + + Type *ArgumentAndReturnType = FnInvariantGroupBarrier->getReturnType(); + assert(ArgumentAndReturnType == + FnInvariantGroupBarrier->getFunctionType()->getParamType(0) && + "InvariantGroupBarrier should take and return the same type"); + Type *PtrType = Ptr->getType(); + + bool PtrTypeConversionNeeded = PtrType != ArgumentAndReturnType; + if (PtrTypeConversionNeeded) + Ptr = CreateBitCast(Ptr, ArgumentAndReturnType); + + CallInst *Fn = CreateCall(FnInvariantGroupBarrier, {Ptr}); + + if (PtrTypeConversionNeeded) + return CreateBitCast(Fn, PtrType); + return Fn; + } + /// \brief Return a vector value that contains \arg V broadcasted to \p /// NumElts elements. Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") { @@ -1676,6 +1777,6 @@ public: // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef) -} +} // end namespace llvm -#endif +#endif // LLVM_IR_IRBUILDER_H diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h index 5f1d56f7e831..88b18e826daf 100644 --- a/include/llvm/IR/IRPrintingPasses.h +++ b/include/llvm/IR/IRPrintingPasses.h @@ -47,6 +47,12 @@ FunctionPass *createPrintFunctionPass(raw_ostream &OS, BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS, const std::string &Banner = ""); +/// Print out a name of an LLVM value without any prefixes. +/// +/// The name is surrounded with ""'s and escaped if it has any special or +/// non-printable characters in it. +void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name); + /// \brief Pass for printing a Module as LLVM's text IR assembly. /// /// Note: This pass is for use with the new pass manager. Use the create...Pass diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 08b51021116c..d2e9e48539ce 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -44,11 +44,12 @@ private: void operator=(const InlineAsm&) = delete; std::string AsmString, Constraints; + FunctionType *FTy; bool HasSideEffects; bool IsAlignStack; AsmDialect Dialect; - InlineAsm(PointerType *Ty, const std::string &AsmString, + InlineAsm(FunctionType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects, bool isAlignStack, AsmDialect asmDialect); ~InlineAsm() override; @@ -56,15 +57,15 @@ private: /// When the ConstantUniqueMap merges two types and makes two InlineAsms /// identical, it destroys one of them with this method. void destroyConstant(); -public: +public: /// InlineAsm::get - Return the specified uniqued inline asm string. /// static InlineAsm *get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack = false, AsmDialect asmDialect = AD_ATT); - + bool hasSideEffects() const { return HasSideEffects; } bool isAlignStack() const { return IsAlignStack; } AsmDialect getDialect() const { return Dialect; } @@ -74,11 +75,11 @@ public: PointerType *getType() const { return reinterpret_cast<PointerType*>(Value::getType()); } - + /// getFunctionType - InlineAsm's are always pointers to functions. /// FunctionType *getFunctionType() const; - + const std::string &getAsmString() const { return AsmString; } const std::string &getConstraintString() const { return Constraints; } @@ -88,15 +89,15 @@ public: /// static bool Verify(FunctionType *Ty, StringRef Constraints); - // Constraint String Parsing + // Constraint String Parsing enum ConstraintPrefix { isInput, // 'x' isOutput, // '=x' isClobber // '~x' }; - + typedef std::vector<std::string> ConstraintCodeVector; - + struct SubConstraintInfo { /// MatchingInput - If this is not -1, this is an output constraint where an /// input constraint is required to match it (e.g. "0"). The value is the @@ -113,80 +114,79 @@ public: typedef std::vector<SubConstraintInfo> SubConstraintInfoVector; struct ConstraintInfo; typedef std::vector<ConstraintInfo> ConstraintInfoVector; - + struct ConstraintInfo { /// Type - The basic type of the constraint: input/output/clobber /// ConstraintPrefix Type; - + /// isEarlyClobber - "&": output operand writes result before inputs are all /// read. This is only ever set for an output operand. - bool isEarlyClobber; - + bool isEarlyClobber; + /// MatchingInput - If this is not -1, this is an output constraint where an /// input constraint is required to match it (e.g. "0"). The value is the /// constraint number that matches this one (for example, if this is /// constraint #0 and constraint #4 has the value "0", this will be 4). signed char MatchingInput; - + /// hasMatchingInput - Return true if this is an output constraint that has /// a matching input constraint. bool hasMatchingInput() const { return MatchingInput != -1; } - + /// isCommutative - This is set to true for a constraint that is commutative /// with the next operand. bool isCommutative; - + /// isIndirect - True if this operand is an indirect operand. This means /// that the address of the source or destination is present in the call /// instruction, instead of it being returned or passed in explicitly. This /// is represented with a '*' in the asm string. bool isIndirect; - + /// Code - The constraint code, either the register name (in braces) or the /// constraint letter/number. ConstraintCodeVector Codes; - + /// isMultipleAlternative - '|': has multiple-alternative constraints. bool isMultipleAlternative; - + /// multipleAlternatives - If there are multiple alternative constraints, /// this array will contain them. Otherwise it will be empty. SubConstraintInfoVector multipleAlternatives; - + /// The currently selected alternative constraint index. unsigned currentAlternativeIndex; - - ///Default constructor. + + /// Default constructor. ConstraintInfo(); - + /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar); - + /// selectAlternative - Point this constraint to the alternative constraint /// indicated by the index. void selectAlternative(unsigned index); }; - + /// ParseConstraints - Split up the constraint string into the specific /// constraints and their prefixes. If this returns an empty vector, and if /// the constraint string itself isn't empty, there was an error parsing. static ConstraintInfoVector ParseConstraints(StringRef ConstraintString); - - /// ParseConstraints - Parse the constraints of this inlineasm object, + + /// ParseConstraints - Parse the constraints of this inlineasm object, /// returning them the same way that ParseConstraints(str) does. ConstraintInfoVector ParseConstraints() const { return ParseConstraints(Constraints); } - + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::InlineAsmVal; } - // These are helper methods for dealing with flags in the INLINEASM SDNode // in the backend. // @@ -203,7 +203,7 @@ public: // code. // Else: // Bit 30-16 - The register class ID to use for the operand. - + enum : uint32_t { // Fixed operands on an INLINEASM SDNode. Op_InputChain = 0, @@ -264,15 +264,15 @@ public: Flag_MatchingOperand = 0x80000000 }; - + static unsigned getFlagWord(unsigned Kind, unsigned NumOps) { assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!"); assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind"); return Kind | (NumOps << 3); } - + /// getFlagWordForMatchingOp - Augment an existing flag word returned by - /// getFlagWord with information indicating that this input operand is tied + /// getFlagWord with information indicating that this input operand is tied /// to a previous output operand. static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo) { @@ -355,7 +355,6 @@ public: RC = High - 1; return true; } - }; } // End llvm namespace diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h index f3ce6490fb66..1baca21c73af 100644 --- a/include/llvm/IR/InstIterator.h +++ b/include/llvm/IR/InstIterator.h @@ -115,19 +115,18 @@ private: } }; - -typedef InstIterator<iplist<BasicBlock>, - Function::iterator, BasicBlock::iterator, - Instruction> inst_iterator; -typedef InstIterator<const iplist<BasicBlock>, - Function::const_iterator, - BasicBlock::const_iterator, +typedef InstIterator<SymbolTableList<BasicBlock>, Function::iterator, + BasicBlock::iterator, Instruction> inst_iterator; +typedef InstIterator<const SymbolTableList<BasicBlock>, + Function::const_iterator, BasicBlock::const_iterator, const Instruction> const_inst_iterator; +typedef iterator_range<inst_iterator> inst_range; +typedef iterator_range<const_inst_iterator> const_inst_range; inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); } inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); } -inline iterator_range<inst_iterator> inst_range(Function *F) { - return iterator_range<inst_iterator>(inst_begin(F), inst_end(F)); +inline inst_range instructions(Function *F) { + return inst_range(inst_begin(F), inst_end(F)); } inline const_inst_iterator inst_begin(const Function *F) { return const_inst_iterator(*F); @@ -135,13 +134,13 @@ inline const_inst_iterator inst_begin(const Function *F) { inline const_inst_iterator inst_end(const Function *F) { return const_inst_iterator(*F, true); } -inline iterator_range<const_inst_iterator> inst_range(const Function *F) { - return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F)); +inline const_inst_range instructions(const Function *F) { + return const_inst_range(inst_begin(F), inst_end(F)); } inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); } inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); } -inline iterator_range<inst_iterator> inst_range(Function &F) { - return iterator_range<inst_iterator>(inst_begin(F), inst_end(F)); +inline inst_range instructions(Function &F) { + return inst_range(inst_begin(F), inst_end(F)); } inline const_inst_iterator inst_begin(const Function &F) { return const_inst_iterator(F); @@ -149,8 +148,8 @@ inline const_inst_iterator inst_begin(const Function &F) { inline const_inst_iterator inst_end(const Function &F) { return const_inst_iterator(F, true); } -inline iterator_range<const_inst_iterator> inst_range(const Function &F) { - return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F)); +inline const_inst_range instructions(const Function &F) { + return const_inst_range(inst_begin(F), inst_end(F)); } } // End llvm namespace diff --git a/include/llvm/IR/InstVisitor.h b/include/llvm/IR/InstVisitor.h index 581e860b8382..088d3e0fbfa5 100644 --- a/include/llvm/IR/InstVisitor.h +++ b/include/llvm/IR/InstVisitor.h @@ -169,6 +169,9 @@ public: RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} + RetTy visitCleanupReturnInst(CleanupReturnInst &I) { DELEGATE(TerminatorInst);} + RetTy visitCatchReturnInst(CatchReturnInst &I) { DELEGATE(TerminatorInst); } + RetTy visitCatchSwitchInst(CatchSwitchInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);} @@ -200,6 +203,9 @@ public: RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } + RetTy visitFuncletPadInst(FuncletPadInst &I) { DELEGATE(Instruction); } + RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(FuncletPadInst); } + RetTy visitCatchPadInst(CatchPadInst &I) { DELEGATE(FuncletPadInst); } // Handle the special instrinsic instruction classes. RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);} diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index b791ded0e194..5091bb407833 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -16,9 +16,12 @@ #ifndef LLVM_IR_INSTRTYPES_H #define LLVM_IR_INSTRTYPES_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/Twine.h" +#include "llvm/IR/Attributes.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/OperandTraits.h" namespace llvm { @@ -51,8 +54,8 @@ protected: virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; -public: +public: /// Return the number of successors that this terminator has. unsigned getNumSuccessors() const { return getNumSuccessorsV(); @@ -75,8 +78,198 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } -}; + // \brief Returns true if this terminator relates to exception handling. + bool isExceptional() const { + switch (getOpcode()) { + case Instruction::CatchSwitch: + case Instruction::CatchRet: + case Instruction::CleanupRet: + case Instruction::Invoke: + case Instruction::Resume: + return true; + default: + return false; + } + } + + //===--------------------------------------------------------------------===// + // succ_iterator definition + //===--------------------------------------------------------------------===// + + template <class Term, class BB> // Successor Iterator + class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB, + int, BB *, BB *> { + typedef std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *> + super; + + public: + typedef typename super::pointer pointer; + typedef typename super::reference reference; + + private: + Term TermInst; + unsigned idx; + typedef SuccIterator<Term, BB> Self; + + inline bool index_is_valid(unsigned idx) { + return idx < TermInst->getNumSuccessors(); + } + + /// \brief Proxy object to allow write access in operator[] + class SuccessorProxy { + Self it; + + public: + explicit SuccessorProxy(const Self &it) : it(it) {} + + SuccessorProxy(const SuccessorProxy &) = default; + + SuccessorProxy &operator=(SuccessorProxy r) { + *this = reference(r); + return *this; + } + + SuccessorProxy &operator=(reference r) { + it.TermInst->setSuccessor(it.idx, r); + return *this; + } + + operator reference() const { return *it; } + }; + + public: + // begin iterator + explicit inline SuccIterator(Term T) : TermInst(T), idx(0) {} + // end iterator + inline SuccIterator(Term T, bool) : TermInst(T) { + if (TermInst) + idx = TermInst->getNumSuccessors(); + else + // Term == NULL happens, if a basic block is not fully constructed and + // consequently getTerminator() returns NULL. In this case we construct + // a SuccIterator which describes a basic block that has zero + // successors. + // Defining SuccIterator for incomplete and malformed CFGs is especially + // useful for debugging. + idx = 0; + } + + /// This is used to interface between code that wants to + /// operate on terminator instructions directly. + unsigned getSuccessorIndex() const { return idx; } + + inline bool operator==(const Self &x) const { return idx == x.idx; } + inline bool operator!=(const Self &x) const { return !operator==(x); } + + inline reference operator*() const { return TermInst->getSuccessor(idx); } + inline pointer operator->() const { return operator*(); } + + inline Self &operator++() { + ++idx; + return *this; + } // Preincrement + + inline Self operator++(int) { // Postincrement + Self tmp = *this; + ++*this; + return tmp; + } + + inline Self &operator--() { + --idx; + return *this; + } // Predecrement + inline Self operator--(int) { // Postdecrement + Self tmp = *this; + --*this; + return tmp; + } + + inline bool operator<(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx < x.idx; + } + + inline bool operator<=(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx <= x.idx; + } + inline bool operator>=(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx >= x.idx; + } + + inline bool operator>(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx > x.idx; + } + + inline Self &operator+=(int Right) { + unsigned new_idx = idx + Right; + assert(index_is_valid(new_idx) && "Iterator index out of bound"); + idx = new_idx; + return *this; + } + + inline Self operator+(int Right) const { + Self tmp = *this; + tmp += Right; + return tmp; + } + + inline Self &operator-=(int Right) { return operator+=(-Right); } + + inline Self operator-(int Right) const { return operator+(-Right); } + + inline int operator-(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot work on iterators of different blocks!"); + int distance = idx - x.idx; + return distance; + } + + inline SuccessorProxy operator[](int offset) { + Self tmp = *this; + tmp += offset; + return SuccessorProxy(tmp); + } + + /// Get the source BB of this iterator. + inline BB *getSource() { + assert(TermInst && "Source not available, if basic block was malformed"); + return TermInst->getParent(); + } + }; + + typedef SuccIterator<TerminatorInst *, BasicBlock> succ_iterator; + typedef SuccIterator<const TerminatorInst *, const BasicBlock> + succ_const_iterator; + typedef llvm::iterator_range<succ_iterator> succ_range; + typedef llvm::iterator_range<succ_const_iterator> succ_const_range; + +private: + inline succ_iterator succ_begin() { return succ_iterator(this); } + inline succ_const_iterator succ_begin() const { + return succ_const_iterator(this); + } + inline succ_iterator succ_end() { return succ_iterator(this, true); } + inline succ_const_iterator succ_end() const { + return succ_const_iterator(this, true); + } + +public: + inline succ_range successors() { + return succ_range(succ_begin(), succ_end()); + } + inline succ_const_range successors() const { + return succ_const_range(succ_begin(), succ_end()); + } +}; //===----------------------------------------------------------------------===// // UnaryInstruction Class @@ -95,6 +288,7 @@ protected: : Instruction(Ty, iType, &Op<0>(), 1, IAE) { Op<0>() = V; } + public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -133,6 +327,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) class BinaryOperator : public Instruction { void *operator new(size_t, unsigned) = delete; + protected: void init(BinaryOps iType); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, @@ -209,7 +404,7 @@ public: BO->setHasNoSignedWrap(true); return BO; } - + static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name = "") { BinaryOperator *BO = Create(Opc, V1, V2, Name); @@ -228,7 +423,7 @@ public: BO->setHasNoUnsignedWrap(true); return BO; } - + static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name = "") { BinaryOperator *BO = Create(Opc, V1, V2, Name); @@ -247,29 +442,29 @@ public: BO->setIsExact(true); return BO; } - -#define DEFINE_HELPERS(OPC, NUWNSWEXACT) \ - static BinaryOperator *Create ## NUWNSWEXACT ## OPC \ - (Value *V1, Value *V2, const Twine &Name = "") { \ - return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name); \ - } \ - static BinaryOperator *Create ## NUWNSWEXACT ## OPC \ - (Value *V1, Value *V2, const Twine &Name, BasicBlock *BB) { \ - return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, BB); \ - } \ - static BinaryOperator *Create ## NUWNSWEXACT ## OPC \ - (Value *V1, Value *V2, const Twine &Name, Instruction *I) { \ - return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I); \ + +#define DEFINE_HELPERS(OPC, NUWNSWEXACT) \ + static BinaryOperator *Create##NUWNSWEXACT##OPC(Value *V1, Value *V2, \ + const Twine &Name = "") { \ + return Create##NUWNSWEXACT(Instruction::OPC, V1, V2, Name); \ + } \ + static BinaryOperator *Create##NUWNSWEXACT##OPC( \ + Value *V1, Value *V2, const Twine &Name, BasicBlock *BB) { \ + return Create##NUWNSWEXACT(Instruction::OPC, V1, V2, Name, BB); \ + } \ + static BinaryOperator *Create##NUWNSWEXACT##OPC( \ + Value *V1, Value *V2, const Twine &Name, Instruction *I) { \ + return Create##NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I); \ } - - DEFINE_HELPERS(Add, NSW) // CreateNSWAdd - DEFINE_HELPERS(Add, NUW) // CreateNUWAdd - DEFINE_HELPERS(Sub, NSW) // CreateNSWSub - DEFINE_HELPERS(Sub, NUW) // CreateNUWSub - DEFINE_HELPERS(Mul, NSW) // CreateNSWMul - DEFINE_HELPERS(Mul, NUW) // CreateNUWMul - DEFINE_HELPERS(Shl, NSW) // CreateNSWShl - DEFINE_HELPERS(Shl, NUW) // CreateNUWShl + + DEFINE_HELPERS(Add, NSW) // CreateNSWAdd + DEFINE_HELPERS(Add, NUW) // CreateNUWAdd + DEFINE_HELPERS(Sub, NSW) // CreateNSWSub + DEFINE_HELPERS(Sub, NUW) // CreateNUWSub + DEFINE_HELPERS(Mul, NSW) // CreateNSWMul + DEFINE_HELPERS(Mul, NUW) // CreateNUWMul + DEFINE_HELPERS(Shl, NSW) // CreateNSWShl + DEFINE_HELPERS(Shl, NUW) // CreateNUWShl DEFINE_HELPERS(SDiv, Exact) // CreateExactSDiv DEFINE_HELPERS(UDiv, Exact) // CreateExactUDiv @@ -277,7 +472,7 @@ public: DEFINE_HELPERS(LShr, Exact) // CreateExactLShr #undef DEFINE_HELPERS - + /// Helper functions to construct and inspect unary operations (NEG and NOT) /// via binary operators SUB and XOR: /// @@ -355,7 +550,7 @@ public: /// Convenience method to copy supported wrapping, exact, and fast-math flags /// from V to this instruction. void copyIRFlags(const Value *V); - + /// Logical 'and' of any supported wrapping, exact, and fast-math flags of /// V and this instruction. void andIRFlags(const Value *V); @@ -388,6 +583,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) /// @brief Base class of casting instructions. class CastInst : public UnaryInstruction { void anchor() override; + protected: /// @brief Constructor with insert-before-instruction semantics for subclasses CastInst(Type *Ty, unsigned iType, Value *S, @@ -401,6 +597,7 @@ protected: : UnaryInstruction(Ty, iType, S, InsertAtEnd) { setName(NameStr); } + public: /// Provides a way to construct any of the CastInst subclasses using an /// opcode instead of the subclass's constructor. The opcode must be in the @@ -490,7 +687,7 @@ public: Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction - Instruction *InsertBefore = 0 ///< Place to insert the instruction + Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); /// @brief Create a BitCast, a PtrToInt, or an IntToPTr cast instruction. @@ -503,7 +700,7 @@ public: Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction - Instruction *InsertBefore = 0 ///< Place to insert the instruction + Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. @@ -677,18 +874,6 @@ public: /// This class is the base class for the comparison instructions. /// @brief Abstract base class of comparison instructions. class CmpInst : public Instruction { - void *operator new(size_t, unsigned) = delete; - CmpInst() = delete; -protected: - CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred, - Value *LHS, Value *RHS, const Twine &Name = "", - Instruction *InsertBefore = nullptr); - - CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred, - Value *LHS, Value *RHS, const Twine &Name, - BasicBlock *InsertAtEnd); - - void anchor() override; // Out of line virtual method. public: /// This enumeration lists the possible predicates for CmpInst subclasses. /// Values in the range 0-31 are reserved for FCmpInst, while values in the @@ -730,6 +915,22 @@ public: BAD_ICMP_PREDICATE = ICMP_SLE + 1 }; +private: + void *operator new(size_t, unsigned) = delete; + CmpInst() = delete; + +protected: + CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred, + Value *LHS, Value *RHS, const Twine &Name = "", + Instruction *InsertBefore = nullptr); + + CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred, + Value *LHS, Value *RHS, const Twine &Name, + BasicBlock *InsertAtEnd); + + void anchor() override; // Out of line virtual method. + +public: // allocate space for exactly two operands void *operator new(size_t s) { return User::operator new(s, 2); @@ -740,7 +941,7 @@ public: /// The specified Instruction is allowed to be a dereferenced end iterator. /// @brief Create a CmpInst static CmpInst *Create(OtherOps Op, - unsigned short predicate, Value *S1, + Predicate predicate, Value *S1, Value *S2, const Twine &Name = "", Instruction *InsertBefore = nullptr); @@ -748,7 +949,7 @@ public: /// two operands. Also automatically insert this instruction to the end of /// the BasicBlock specified. /// @brief Create a CmpInst - static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1, + static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name, BasicBlock *InsertAtEnd); /// @brief Get the opcode casted to the right type @@ -775,7 +976,6 @@ public: bool isFPPredicate() const { return isFPPredicate(getPredicate()); } bool isIntPredicate() const { return isIntPredicate(getPredicate()); } - /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc. /// @returns the inverse predicate for the instruction's current predicate. @@ -833,6 +1033,19 @@ public: return isUnsigned(getPredicate()); } + /// For example, ULT->SLT, ULE->SLE, UGT->SGT, UGE->SGE, SLT->Failed assert + /// @returns the signed version of the unsigned predicate pred. + /// @brief return the signed version of a predicate + static Predicate getSignedPredicate(Predicate pred); + + /// For example, ULT->SLT, ULE->SLE, UGT->SGT, UGE->SGE, SLT->Failed assert + /// @returns the signed version of the predicate for this instruction (which + /// has to be an unsigned predicate). + /// @brief return the signed version of a predicate + Predicate getSignedPredicate() { + return getSignedPredicate(getPredicate()); + } + /// This is just a convenience. /// @brief Determine if this is true when both operands are the same. bool isTrueWhenEqual() const { @@ -847,23 +1060,23 @@ public: /// @returns true if the predicate is unsigned, false otherwise. /// @brief Determine if the predicate is an unsigned operation. - static bool isUnsigned(unsigned short predicate); + static bool isUnsigned(Predicate predicate); /// @returns true if the predicate is signed, false otherwise. /// @brief Determine if the predicate is an signed operation. - static bool isSigned(unsigned short predicate); + static bool isSigned(Predicate predicate); /// @brief Determine if the predicate is an ordered operation. - static bool isOrdered(unsigned short predicate); + static bool isOrdered(Predicate predicate); /// @brief Determine if the predicate is an unordered operation. - static bool isUnordered(unsigned short predicate); + static bool isUnordered(Predicate predicate); /// Determine if the predicate is true when comparing a value with itself. - static bool isTrueWhenEqual(unsigned short predicate); + static bool isTrueWhenEqual(Predicate predicate); /// Determine if the predicate is false when comparing a value with itself. - static bool isFalseWhenEqual(unsigned short predicate); + static bool isFalseWhenEqual(Predicate predicate); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { @@ -882,6 +1095,7 @@ public: } return Type::getInt1Ty(opnd_type->getContext()); } + private: // Shadow Value::setValueSubclassData with a private forwarding method so that // subclasses cannot accidentally use it. @@ -890,7 +1104,6 @@ private: } }; - // FIXME: these are redundant if CmpInst < BinaryOperator template <> struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> { @@ -898,6 +1111,523 @@ struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) -} // End llvm namespace +//===----------------------------------------------------------------------===// +// FuncletPadInst Class +//===----------------------------------------------------------------------===// +class FuncletPadInst : public Instruction { +private: + void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr); + + FuncletPadInst(const FuncletPadInst &CPI); + + explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore); + explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, BasicBlock *InsertAtEnd); + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + friend class CatchPadInst; + friend class CleanupPadInst; + FuncletPadInst *cloneImpl() const; + +public: + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// getNumArgOperands - Return the number of funcletpad arguments. + /// + unsigned getNumArgOperands() const { return getNumOperands() - 1; } + + /// Convenience accessors + + /// \brief Return the outer EH-pad this funclet is nested within. + /// + /// Note: This returns the associated CatchSwitchInst if this FuncletPadInst + /// is a CatchPadInst. + Value *getParentPad() const { return Op<-1>(); } + void setParentPad(Value *ParentPad) { + assert(ParentPad); + Op<-1>() = ParentPad; + } + + /// getArgOperand/setArgOperand - Return/set the i-th funcletpad argument. + /// + Value *getArgOperand(unsigned i) const { return getOperand(i); } + void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + + /// arg_operands - iteration adapter for range-for loops. + op_range arg_operands() { return op_range(op_begin(), op_end() - 1); } + + /// arg_operands - iteration adapter for range-for loops. + const_op_range arg_operands() const { + return const_op_range(op_begin(), op_end() - 1); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { return I->isFuncletPad(); } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +template <> +struct OperandTraits<FuncletPadInst> + : public VariadicOperandTraits<FuncletPadInst, /*MINARITY=*/1> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(FuncletPadInst, Value) + +/// \brief A lightweight accessor for an operand bundle meant to be passed +/// around by value. +struct OperandBundleUse { + ArrayRef<Use> Inputs; + + OperandBundleUse() {} + explicit OperandBundleUse(StringMapEntry<uint32_t> *Tag, ArrayRef<Use> Inputs) + : Inputs(Inputs), Tag(Tag) {} + + /// \brief Return true if the operand at index \p Idx in this operand bundle + /// has the attribute A. + bool operandHasAttr(unsigned Idx, Attribute::AttrKind A) const { + if (isDeoptOperandBundle()) + if (A == Attribute::ReadOnly || A == Attribute::NoCapture) + return Inputs[Idx]->getType()->isPointerTy(); + + // Conservative answer: no operands have any attributes. + return false; + }; + + /// \brief Return the tag of this operand bundle as a string. + StringRef getTagName() const { + return Tag->getKey(); + } + + /// \brief Return the tag of this operand bundle as an integer. + /// + /// Operand bundle tags are interned by LLVMContextImpl::getOrInsertBundleTag, + /// and this function returns the unique integer getOrInsertBundleTag + /// associated the tag of this operand bundle to. + uint32_t getTagID() const { + return Tag->getValue(); + } + + /// \brief Return true if this is a "deopt" operand bundle. + bool isDeoptOperandBundle() const { + return getTagID() == LLVMContext::OB_deopt; + } + + /// \brief Return true if this is a "funclet" operand bundle. + bool isFuncletOperandBundle() const { + return getTagID() == LLVMContext::OB_funclet; + } + +private: + /// \brief Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag. + StringMapEntry<uint32_t> *Tag; +}; + +/// \brief A container for an operand bundle being viewed as a set of values +/// rather than a set of uses. +/// +/// Unlike OperandBundleUse, OperandBundleDefT owns the memory it carries, and +/// so it is possible to create and pass around "self-contained" instances of +/// OperandBundleDef and ConstOperandBundleDef. +template <typename InputTy> class OperandBundleDefT { + std::string Tag; + std::vector<InputTy> Inputs; + +public: + explicit OperandBundleDefT(std::string Tag, std::vector<InputTy> Inputs) + : Tag(std::move(Tag)), Inputs(std::move(Inputs)) {} + explicit OperandBundleDefT(std::string Tag, ArrayRef<InputTy> Inputs) + : Tag(std::move(Tag)), Inputs(Inputs) {} + + explicit OperandBundleDefT(const OperandBundleUse &OBU) { + Tag = OBU.getTagName(); + Inputs.insert(Inputs.end(), OBU.Inputs.begin(), OBU.Inputs.end()); + } + + ArrayRef<InputTy> inputs() const { return Inputs; } + + typedef typename std::vector<InputTy>::const_iterator input_iterator; + size_t input_size() const { return Inputs.size(); } + input_iterator input_begin() const { return Inputs.begin(); } + input_iterator input_end() const { return Inputs.end(); } + + StringRef getTag() const { return Tag; } +}; + +typedef OperandBundleDefT<Value *> OperandBundleDef; +typedef OperandBundleDefT<const Value *> ConstOperandBundleDef; + +/// \brief A mixin to add operand bundle functionality to llvm instruction +/// classes. +/// +/// OperandBundleUser uses the descriptor area co-allocated with the host User +/// to store some meta information about which operands are "normal" operands, +/// and which ones belong to some operand bundle. +/// +/// The layout of an operand bundle user is +/// +/// +-----------uint32_t End-------------------------------------+ +/// | | +/// | +--------uint32_t Begin--------------------+ | +/// | | | | +/// ^ ^ v v +/// |------|------|----|----|----|----|----|---------|----|---------|----|----- +/// | BOI0 | BOI1 | .. | DU | U0 | U1 | .. | BOI0_U0 | .. | BOI1_U0 | .. | Un +/// |------|------|----|----|----|----|----|---------|----|---------|----|----- +/// v v ^ ^ +/// | | | | +/// | +--------uint32_t Begin------------+ | +/// | | +/// +-----------uint32_t End-----------------------------+ +/// +/// +/// BOI0, BOI1 ... are descriptions of operand bundles in this User's use list. +/// These descriptions are installed and managed by this class, and they're all +/// instances of OperandBundleUser<T>::BundleOpInfo. +/// +/// DU is an additional descriptor installed by User's 'operator new' to keep +/// track of the 'BOI0 ... BOIN' co-allocation. OperandBundleUser does not +/// access or modify DU in any way, it's an implementation detail private to +/// User. +/// +/// The regular Use& vector for the User starts at U0. The operand bundle uses +/// are part of the Use& vector, just like normal uses. In the diagram above, +/// the operand bundle uses start at BOI0_U0. Each instance of BundleOpInfo has +/// information about a contiguous set of uses constituting an operand bundle, +/// and the total set of operand bundle uses themselves form a contiguous set of +/// uses (i.e. there are no gaps between uses corresponding to individual +/// operand bundles). +/// +/// This class does not know the location of the set of operand bundle uses +/// within the use list -- that is decided by the User using this class via the +/// BeginIdx argument in populateBundleOperandInfos. +/// +/// Currently operand bundle users with hung-off operands are not supported. +template <typename InstrTy, typename OpIteratorTy> class OperandBundleUser { +public: + /// \brief Return the number of operand bundles associated with this User. + unsigned getNumOperandBundles() const { + return std::distance(bundle_op_info_begin(), bundle_op_info_end()); + } + + /// \brief Return true if this User has any operand bundles. + bool hasOperandBundles() const { return getNumOperandBundles() != 0; } + + /// \brief Return the index of the first bundle operand in the Use array. + unsigned getBundleOperandsStartIndex() const { + assert(hasOperandBundles() && "Don't call otherwise!"); + return bundle_op_info_begin()->Begin; + } + + /// \brief Return the index of the last bundle operand in the Use array. + unsigned getBundleOperandsEndIndex() const { + assert(hasOperandBundles() && "Don't call otherwise!"); + return bundle_op_info_end()[-1].End; + } + + /// \brief Return the total number operands (not operand bundles) used by + /// every operand bundle in this OperandBundleUser. + unsigned getNumTotalBundleOperands() const { + if (!hasOperandBundles()) + return 0; + + unsigned Begin = getBundleOperandsStartIndex(); + unsigned End = getBundleOperandsEndIndex(); + + assert(Begin <= End && "Should be!"); + return End - Begin; + } + + /// \brief Return the operand bundle at a specific index. + OperandBundleUse getOperandBundleAt(unsigned Index) const { + assert(Index < getNumOperandBundles() && "Index out of bounds!"); + return operandBundleFromBundleOpInfo(*(bundle_op_info_begin() + Index)); + } + + /// \brief Return the number of operand bundles with the tag Name attached to + /// this instruction. + unsigned countOperandBundlesOfType(StringRef Name) const { + unsigned Count = 0; + for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) + if (getOperandBundleAt(i).getTagName() == Name) + Count++; + + return Count; + } + + /// \brief Return the number of operand bundles with the tag ID attached to + /// this instruction. + unsigned countOperandBundlesOfType(uint32_t ID) const { + unsigned Count = 0; + for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) + if (getOperandBundleAt(i).getTagID() == ID) + Count++; + + return Count; + } + + /// \brief Return an operand bundle by name, if present. + /// + /// It is an error to call this for operand bundle types that may have + /// multiple instances of them on the same instruction. + Optional<OperandBundleUse> getOperandBundle(StringRef Name) const { + assert(countOperandBundlesOfType(Name) < 2 && "Precondition violated!"); + + for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) { + OperandBundleUse U = getOperandBundleAt(i); + if (U.getTagName() == Name) + return U; + } + + return None; + } + + /// \brief Return an operand bundle by tag ID, if present. + /// + /// It is an error to call this for operand bundle types that may have + /// multiple instances of them on the same instruction. + Optional<OperandBundleUse> getOperandBundle(uint32_t ID) const { + assert(countOperandBundlesOfType(ID) < 2 && "Precondition violated!"); + + for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) { + OperandBundleUse U = getOperandBundleAt(i); + if (U.getTagID() == ID) + return U; + } + + return None; + } + + /// \brief Return the list of operand bundles attached to this instruction as + /// a vector of OperandBundleDefs. + /// + /// This function copies the OperandBundeUse instances associated with this + /// OperandBundleUser to a vector of OperandBundleDefs. Note: + /// OperandBundeUses and OperandBundleDefs are non-trivially *different* + /// representations of operand bundles (see documentation above). + void getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> &Defs) const { + for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) + Defs.emplace_back(getOperandBundleAt(i)); + } + + /// \brief Return the operand bundle for the operand at index OpIdx. + /// + /// It is an error to call this with an OpIdx that does not correspond to an + /// bundle operand. + OperandBundleUse getOperandBundleForOperand(unsigned OpIdx) const { + return operandBundleFromBundleOpInfo(getBundleOpInfoForOperand(OpIdx)); + } + + /// \brief Return true if this operand bundle user has operand bundles that + /// may read from the heap. + bool hasReadingOperandBundles() const { + // Implementation note: this is a conservative implementation of operand + // bundle semantics, where *any* operand bundle forces a callsite to be at + // least readonly. + return hasOperandBundles(); + } + + /// \brief Return true if this operand bundle user has operand bundles that + /// may write to the heap. + bool hasClobberingOperandBundles() const { + for (auto &BOI : bundle_op_infos()) { + if (BOI.Tag->second == LLVMContext::OB_deopt || + BOI.Tag->second == LLVMContext::OB_funclet) + continue; + + // This instruction has an operand bundle that is not known to us. + // Assume the worst. + return true; + } + + return false; + } + + /// \brief Return true if the bundle operand at index \p OpIdx has the + /// attribute \p A. + bool bundleOperandHasAttr(unsigned OpIdx, Attribute::AttrKind A) const { + auto &BOI = getBundleOpInfoForOperand(OpIdx); + auto OBU = operandBundleFromBundleOpInfo(BOI); + return OBU.operandHasAttr(OpIdx - BOI.Begin, A); + } + + /// \brief Return true if \p Other has the same sequence of operand bundle + /// tags with the same number of operands on each one of them as this + /// OperandBundleUser. + bool hasIdenticalOperandBundleSchema( + const OperandBundleUser<InstrTy, OpIteratorTy> &Other) const { + if (getNumOperandBundles() != Other.getNumOperandBundles()) + return false; + + return std::equal(bundle_op_info_begin(), bundle_op_info_end(), + Other.bundle_op_info_begin()); + }; + +protected: + /// \brief Is the function attribute S disallowed by some operand bundle on + /// this operand bundle user? + bool isFnAttrDisallowedByOpBundle(StringRef S) const { + // Operand bundles only possibly disallow readnone, readonly and argmenonly + // attributes. All String attributes are fine. + return false; + } + + /// \brief Is the function attribute A disallowed by some operand bundle on + /// this operand bundle user? + bool isFnAttrDisallowedByOpBundle(Attribute::AttrKind A) const { + switch (A) { + default: + return false; + + case Attribute::ArgMemOnly: + return hasReadingOperandBundles(); + + case Attribute::ReadNone: + return hasReadingOperandBundles(); + + case Attribute::ReadOnly: + return hasClobberingOperandBundles(); + } + + llvm_unreachable("switch has a default case!"); + } + + /// \brief Used to keep track of an operand bundle. See the main comment on + /// OperandBundleUser above. + struct BundleOpInfo { + /// \brief The operand bundle tag, interned by + /// LLVMContextImpl::getOrInsertBundleTag. + StringMapEntry<uint32_t> *Tag; + + /// \brief The index in the Use& vector where operands for this operand + /// bundle starts. + uint32_t Begin; + + /// \brief The index in the Use& vector where operands for this operand + /// bundle ends. + uint32_t End; + + bool operator==(const BundleOpInfo &Other) const { + return Tag == Other.Tag && Begin == Other.Begin && End == Other.End; + } + }; + + /// \brief Simple helper function to map a BundleOpInfo to an + /// OperandBundleUse. + OperandBundleUse + operandBundleFromBundleOpInfo(const BundleOpInfo &BOI) const { + auto op_begin = static_cast<const InstrTy *>(this)->op_begin(); + ArrayRef<Use> Inputs(op_begin + BOI.Begin, op_begin + BOI.End); + return OperandBundleUse(BOI.Tag, Inputs); + } + + typedef BundleOpInfo *bundle_op_iterator; + typedef const BundleOpInfo *const_bundle_op_iterator; + + /// \brief Return the start of the list of BundleOpInfo instances associated + /// with this OperandBundleUser. + bundle_op_iterator bundle_op_info_begin() { + if (!static_cast<InstrTy *>(this)->hasDescriptor()) + return nullptr; + + uint8_t *BytesBegin = static_cast<InstrTy *>(this)->getDescriptor().begin(); + return reinterpret_cast<bundle_op_iterator>(BytesBegin); + } + + /// \brief Return the start of the list of BundleOpInfo instances associated + /// with this OperandBundleUser. + const_bundle_op_iterator bundle_op_info_begin() const { + auto *NonConstThis = + const_cast<OperandBundleUser<InstrTy, OpIteratorTy> *>(this); + return NonConstThis->bundle_op_info_begin(); + } + + /// \brief Return the end of the list of BundleOpInfo instances associated + /// with this OperandBundleUser. + bundle_op_iterator bundle_op_info_end() { + if (!static_cast<InstrTy *>(this)->hasDescriptor()) + return nullptr; + + uint8_t *BytesEnd = static_cast<InstrTy *>(this)->getDescriptor().end(); + return reinterpret_cast<bundle_op_iterator>(BytesEnd); + } + + /// \brief Return the end of the list of BundleOpInfo instances associated + /// with this OperandBundleUser. + const_bundle_op_iterator bundle_op_info_end() const { + auto *NonConstThis = + const_cast<OperandBundleUser<InstrTy, OpIteratorTy> *>(this); + return NonConstThis->bundle_op_info_end(); + } + + /// \brief Return the range [\p bundle_op_info_begin, \p bundle_op_info_end). + iterator_range<bundle_op_iterator> bundle_op_infos() { + return make_range(bundle_op_info_begin(), bundle_op_info_end()); + } + + /// \brief Return the range [\p bundle_op_info_begin, \p bundle_op_info_end). + iterator_range<const_bundle_op_iterator> bundle_op_infos() const { + return make_range(bundle_op_info_begin(), bundle_op_info_end()); + } + + /// \brief Populate the BundleOpInfo instances and the Use& vector from \p + /// Bundles. Return the op_iterator pointing to the Use& one past the last + /// last bundle operand use. + /// + /// Each \p OperandBundleDef instance is tracked by a OperandBundleInfo + /// instance allocated in this User's descriptor. + OpIteratorTy populateBundleOperandInfos(ArrayRef<OperandBundleDef> Bundles, + const unsigned BeginIndex) { + auto It = static_cast<InstrTy *>(this)->op_begin() + BeginIndex; + for (auto &B : Bundles) + It = std::copy(B.input_begin(), B.input_end(), It); + + auto *ContextImpl = static_cast<InstrTy *>(this)->getContext().pImpl; + auto BI = Bundles.begin(); + unsigned CurrentIndex = BeginIndex; + + for (auto &BOI : bundle_op_infos()) { + assert(BI != Bundles.end() && "Incorrect allocation?"); + + BOI.Tag = ContextImpl->getOrInsertBundleTag(BI->getTag()); + BOI.Begin = CurrentIndex; + BOI.End = CurrentIndex + BI->input_size(); + CurrentIndex = BOI.End; + BI++; + } + + assert(BI == Bundles.end() && "Incorrect allocation?"); + + return It; + } + + /// \brief Return the BundleOpInfo for the operand at index OpIdx. + /// + /// It is an error to call this with an OpIdx that does not correspond to an + /// bundle operand. + const BundleOpInfo &getBundleOpInfoForOperand(unsigned OpIdx) const { + for (auto &BOI : bundle_op_infos()) + if (BOI.Begin <= OpIdx && OpIdx < BOI.End) + return BOI; + + llvm_unreachable("Did not find operand bundle for operand!"); + } + + /// \brief Return the total number of values used in \p Bundles. + static unsigned CountBundleInputs(ArrayRef<OperandBundleDef> Bundles) { + unsigned Total = 0; + for (auto &B : Bundles) + Total += B.input_size(); + return Total; + } +}; + +} // end llvm namespace -#endif +#endif // LLVM_IR_INSTRTYPES_H diff --git a/include/llvm/IR/Instruction.def b/include/llvm/IR/Instruction.def index d46314cc761d..18711abb8060 100644 --- a/include/llvm/IR/Instruction.def +++ b/include/llvm/IR/Instruction.def @@ -1,21 +1,21 @@ //===-- llvm/Instruction.def - File that describes Instructions -*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file contains descriptions of the various LLVM instructions. This is -// used as a central place for enumerating the different instructions and +// used as a central place for enumerating the different instructions and // should eventually be the place to put comments about the instructions. // //===----------------------------------------------------------------------===// // NOTE: NO INCLUDE GUARD DESIRED! -// Provide definitions of macros so that users of this file do not have to +// Provide definitions of macros so that users of this file do not have to // define everything to use it... // #ifndef FIRST_TERM_INST @@ -74,6 +74,20 @@ #define LAST_CAST_INST(num) #endif +#ifndef FIRST_FUNCLETPAD_INST +#define FIRST_FUNCLETPAD_INST(num) +#endif +#ifndef HANDLE_FUNCLETPAD_INST +#ifndef HANDLE_INST +#define HANDLE_FUNCLETPAD_INST(num, opcode, Class) +#else +#define HANDLE_FUNCLETPAD_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class) +#endif +#endif +#ifndef LAST_FUNCLETPAD_INST +#define LAST_FUNCLETPAD_INST(num) +#endif + #ifndef FIRST_OTHER_INST #define FIRST_OTHER_INST(num) #endif @@ -88,92 +102,99 @@ #define LAST_OTHER_INST(num) #endif - // Terminator Instructions - These instructions are used to terminate a basic // block of the program. Every basic block must end with one of these // instructions for it to be a well formed basic block. // FIRST_TERM_INST ( 1) -HANDLE_TERM_INST ( 1, Ret , ReturnInst) -HANDLE_TERM_INST ( 2, Br , BranchInst) -HANDLE_TERM_INST ( 3, Switch , SwitchInst) -HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst) -HANDLE_TERM_INST ( 5, Invoke , InvokeInst) -HANDLE_TERM_INST ( 6, Resume , ResumeInst) -HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst) - LAST_TERM_INST ( 7) +HANDLE_TERM_INST ( 1, Ret , ReturnInst) +HANDLE_TERM_INST ( 2, Br , BranchInst) +HANDLE_TERM_INST ( 3, Switch , SwitchInst) +HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst) +HANDLE_TERM_INST ( 5, Invoke , InvokeInst) +HANDLE_TERM_INST ( 6, Resume , ResumeInst) +HANDLE_TERM_INST ( 7, Unreachable , UnreachableInst) +HANDLE_TERM_INST ( 8, CleanupRet , CleanupReturnInst) +HANDLE_TERM_INST ( 9, CatchRet , CatchReturnInst) +HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst) + LAST_TERM_INST (10) // Standard binary operators... - FIRST_BINARY_INST( 8) -HANDLE_BINARY_INST( 8, Add , BinaryOperator) -HANDLE_BINARY_INST( 9, FAdd , BinaryOperator) -HANDLE_BINARY_INST(10, Sub , BinaryOperator) -HANDLE_BINARY_INST(11, FSub , BinaryOperator) -HANDLE_BINARY_INST(12, Mul , BinaryOperator) -HANDLE_BINARY_INST(13, FMul , BinaryOperator) -HANDLE_BINARY_INST(14, UDiv , BinaryOperator) -HANDLE_BINARY_INST(15, SDiv , BinaryOperator) -HANDLE_BINARY_INST(16, FDiv , BinaryOperator) -HANDLE_BINARY_INST(17, URem , BinaryOperator) -HANDLE_BINARY_INST(18, SRem , BinaryOperator) -HANDLE_BINARY_INST(19, FRem , BinaryOperator) + FIRST_BINARY_INST(11) +HANDLE_BINARY_INST(11, Add , BinaryOperator) +HANDLE_BINARY_INST(12, FAdd , BinaryOperator) +HANDLE_BINARY_INST(13, Sub , BinaryOperator) +HANDLE_BINARY_INST(14, FSub , BinaryOperator) +HANDLE_BINARY_INST(15, Mul , BinaryOperator) +HANDLE_BINARY_INST(16, FMul , BinaryOperator) +HANDLE_BINARY_INST(17, UDiv , BinaryOperator) +HANDLE_BINARY_INST(18, SDiv , BinaryOperator) +HANDLE_BINARY_INST(19, FDiv , BinaryOperator) +HANDLE_BINARY_INST(20, URem , BinaryOperator) +HANDLE_BINARY_INST(21, SRem , BinaryOperator) +HANDLE_BINARY_INST(22, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(23, And , BinaryOperator) -HANDLE_BINARY_INST(24, Or , BinaryOperator) -HANDLE_BINARY_INST(25, Xor , BinaryOperator) - LAST_BINARY_INST(25) +HANDLE_BINARY_INST(23, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(24, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(25, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(26, And , BinaryOperator) +HANDLE_BINARY_INST(27, Or , BinaryOperator) +HANDLE_BINARY_INST(28, Xor , BinaryOperator) + LAST_BINARY_INST(28) // Memory operators... - FIRST_MEMORY_INST(26) -HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(28, Store , StoreInst ) -HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) -HANDLE_MEMORY_INST(30, Fence , FenceInst ) -HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst ) -HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst ) - LAST_MEMORY_INST(32) + FIRST_MEMORY_INST(29) +HANDLE_MEMORY_INST(29, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(30, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(31, Store , StoreInst ) +HANDLE_MEMORY_INST(32, GetElementPtr, GetElementPtrInst) +HANDLE_MEMORY_INST(33, Fence , FenceInst ) +HANDLE_MEMORY_INST(34, AtomicCmpXchg , AtomicCmpXchgInst ) +HANDLE_MEMORY_INST(35, AtomicRMW , AtomicRMWInst ) + LAST_MEMORY_INST(35) // Cast operators ... -// NOTE: The order matters here because CastInst::isEliminableCastPair +// NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(33) -HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast -HANDLE_CAST_INST(45, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast - LAST_CAST_INST(45) + FIRST_CAST_INST(36) +HANDLE_CAST_INST(36, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(37, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(38, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(39, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(40, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(41, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(42, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(43, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(44, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(45, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(46, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(47, BitCast , BitCastInst ) // Type cast +HANDLE_CAST_INST(48, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast + LAST_CAST_INST(48) + + FIRST_FUNCLETPAD_INST(49) +HANDLE_FUNCLETPAD_INST(49, CleanupPad, CleanupPadInst) +HANDLE_FUNCLETPAD_INST(50, CatchPad , CatchPadInst) + LAST_FUNCLETPAD_INST(50) // Other operators... - FIRST_OTHER_INST(46) -HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate -HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction. - LAST_OTHER_INST(59) + FIRST_OTHER_INST(51) +HANDLE_OTHER_INST(51, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(56, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(57, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(61, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(62, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(63, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction. + LAST_OTHER_INST(64) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST @@ -191,6 +212,10 @@ HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction. #undef HANDLE_CAST_INST #undef LAST_CAST_INST +#undef FIRST_FUNCLETPAD_INST +#undef HANDLE_FUNCLETPAD_INST +#undef LAST_FUNCLETPAD_INST + #undef FIRST_OTHER_INST #undef HANDLE_OTHER_INST #undef LAST_OTHER_INST diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 31f363f70a5b..03c45497fa95 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -30,25 +30,11 @@ class BasicBlock; struct AAMDNodes; template <> -struct ilist_traits<Instruction> - : public SymbolTableListTraits<Instruction, BasicBlock> { +struct SymbolTableListSentinelTraits<Instruction> + : public ilist_half_embedded_sentinel_traits<Instruction> {}; - /// \brief Return a node that marks the end of a list. - /// - /// The sentinel is relative to this instance, so we use a non-static - /// method. - Instruction *createSentinel() const; - static void destroySentinel(Instruction *) {} - - Instruction *provideInitialHead() const { return createSentinel(); } - Instruction *ensureHead(Instruction *) const { return createSentinel(); } - static void noteHead(Instruction *, Instruction *) {} - -private: - mutable ilist_half_node<Instruction> Sentinel; -}; - -class Instruction : public User, public ilist_node<Instruction> { +class Instruction : public User, + public ilist_node_with_parent<Instruction, BasicBlock> { void operator=(const Instruction &) = delete; Instruction(const Instruction &) = delete; @@ -80,6 +66,13 @@ public: const Module *getModule() const; Module *getModule(); + /// \brief Return the function this instruction belongs to. + /// + /// Note: it is undefined behavior to call this on an instruction not + /// currently inserted into a function. + const Function *getFunction() const; + Function *getFunction(); + /// removeFromParent - This method unlinks 'this' from the containing basic /// block, but does not delete it. /// @@ -89,7 +82,7 @@ public: /// block and deletes it. /// /// \returns an iterator pointing to the element after the erased one - iplist<Instruction>::iterator eraseFromParent(); + SymbolTableList<Instruction>::iterator eraseFromParent(); /// Insert an unlinked instruction into a basic block immediately before /// the specified instruction. @@ -116,6 +109,7 @@ public: bool isBinaryOp() const { return isBinaryOp(getOpcode()); } bool isShift() { return isShift(getOpcode()); } bool isCast() const { return isCast(getOpcode()); } + bool isFuncletPad() const { return isFuncletPad(getOpcode()); } static const char* getOpcodeName(unsigned OpCode); @@ -148,6 +142,11 @@ public: return OpCode >= CastOpsBegin && OpCode < CastOpsEnd; } + /// @brief Determine if the OpCode is one of the FuncletPadInst instructions. + static inline bool isFuncletPad(unsigned OpCode) { + return OpCode >= FuncletPadOpsBegin && OpCode < FuncletPadOpsEnd; + } + //===--------------------------------------------------------------------===// // Metadata manipulation. //===--------------------------------------------------------------------===// @@ -204,20 +203,22 @@ public: void setMetadata(unsigned KindID, MDNode *Node); void setMetadata(StringRef Kind, MDNode *Node); - /// \brief Drop unknown metadata. + /// Drop all unknown metadata except for debug locations. + /// @{ /// Passes are required to drop metadata they don't understand. This is a /// convenience method for passes to do so. - void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs); - void dropUnknownMetadata() { - return dropUnknownMetadata(None); + void dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs); + void dropUnknownNonDebugMetadata() { + return dropUnknownNonDebugMetadata(None); } - void dropUnknownMetadata(unsigned ID1) { - return dropUnknownMetadata(makeArrayRef(ID1)); + void dropUnknownNonDebugMetadata(unsigned ID1) { + return dropUnknownNonDebugMetadata(makeArrayRef(ID1)); } - void dropUnknownMetadata(unsigned ID1, unsigned ID2) { + void dropUnknownNonDebugMetadata(unsigned ID1, unsigned ID2) { unsigned IDs[] = {ID1, ID2}; - return dropUnknownMetadata(IDs); + return dropUnknownNonDebugMetadata(IDs); } + /// @} /// setAAMetadata - Sets the metadata on this instruction from the /// AAMDNodes structure. @@ -388,6 +389,19 @@ public: return mayWriteToMemory() || mayThrow() || !mayReturn(); } + /// \brief Return true if the instruction is a variety of EH-block. + bool isEHPad() const { + switch (getOpcode()) { + case Instruction::CatchSwitch: + case Instruction::CatchPad: + case Instruction::CleanupPad: + case Instruction::LandingPad: + return true; + default: + return false; + } + } + /// clone() - Create a copy of 'this' instruction that is identical in all /// ways except the following: /// * The instruction has no parent @@ -468,6 +482,13 @@ public: #include "llvm/IR/Instruction.def" }; + enum FuncletPadOps { +#define FIRST_FUNCLETPAD_INST(N) FuncletPadOpsBegin = N, +#define HANDLE_FUNCLETPAD_INST(N, OPC, CLASS) OPC = N, +#define LAST_FUNCLETPAD_INST(N) FuncletPadOpsEnd = N+1 +#include "llvm/IR/Instruction.def" + }; + enum OtherOps { #define FIRST_OTHER_INST(N) OtherOpsBegin = N, #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, @@ -489,7 +510,7 @@ private: (V ? HasMetadataBit : 0)); } - friend class SymbolTableListTraits<Instruction, BasicBlock>; + friend class SymbolTableListTraits<Instruction>; void setParent(BasicBlock *P); protected: // Instruction subclasses can stick up to 15 bits of stuff into the @@ -515,17 +536,6 @@ private: Instruction *cloneImpl() const; }; -inline Instruction *ilist_traits<Instruction>::createSentinel() const { - // Since i(p)lists always publicly derive from their corresponding traits, - // placing a data member in this class will augment the i(p)list. But since - // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>, - // there is a legal viable downcast from it to NodeTy. We use this trick to - // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the - // sentinel. Dereferencing the sentinel is forbidden (save the - // ilist_node<NodeTy>), so no one will ever notice the superposition. - return static_cast<Instruction *>(&Sentinel); -} - // Instruction* is only 4-byte aligned. template<> class PointerLikeTypeTraits<Instruction*> { diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 07d5f111b9e1..d781c7af36d7 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/CallingConv.h" @@ -158,6 +159,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -166,7 +168,6 @@ private: } }; - //===----------------------------------------------------------------------===// // LoadInst Class //===----------------------------------------------------------------------===// @@ -176,6 +177,7 @@ private: /// class LoadInst : public UnaryInstruction { void AssertOK(); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -290,7 +292,6 @@ public: return getPointerOperand()->getType()->getPointerAddressSpace(); } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; @@ -298,6 +299,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -306,7 +308,6 @@ private: } }; - //===----------------------------------------------------------------------===// // StoreInst Class //===----------------------------------------------------------------------===// @@ -316,6 +317,7 @@ private: class StoreInst : public Instruction { void *operator new(size_t, unsigned) = delete; void AssertOK(); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -344,7 +346,6 @@ public: SynchronizationScope SynchScope, BasicBlock *InsertAtEnd); - /// isVolatile - Return true if this is a store to a volatile memory /// location. /// @@ -422,6 +423,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -445,6 +447,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) class FenceInst : public Instruction { void *operator new(size_t, unsigned) = delete; void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -496,6 +499,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -517,6 +521,7 @@ class AtomicCmpXchgInst : public Instruction { void Init(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SynchronizationScope SynchScope); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -648,6 +653,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -673,6 +679,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value) /// class AtomicRMWInst : public Instruction { void *operator new(size_t, unsigned) = delete; + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -795,6 +802,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: void Init(BinOp Operation, Value *Ptr, Value *Val, AtomicOrdering Ordering, SynchronizationScope SynchScope); @@ -831,6 +839,8 @@ class GetElementPtrInst : public Instruction { Type *SourceElementType; Type *ResultElementType; + void anchor() override; + GetElementPtrInst(const GetElementPtrInst &GEPI); void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr); @@ -1078,10 +1088,8 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, init(Ptr, IdxList, NameStr); } - DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) - //===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// @@ -1091,6 +1099,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// must be identical types. /// \brief Represent an integer comparison operator. class ICmpInst: public CmpInst { + void anchor() override; + void AssertOK() { assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE && getPredicate() <= CmpInst::LAST_ICMP_PREDICATE && @@ -1226,7 +1236,6 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } - }; //===----------------------------------------------------------------------===// @@ -1350,62 +1359,102 @@ public: /// field to indicate whether or not this is a tail call. The rest of the bits /// hold the calling convention of the call. /// -class CallInst : public Instruction { +class CallInst : public Instruction, + public OperandBundleUser<CallInst, User::op_iterator> { AttributeSet AttributeList; ///< parameter attributes for call FunctionType *FTy; CallInst(const CallInst &CI); - void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) { + void init(Value *Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) { init(cast<FunctionType>( cast<PointerType>(Func->getType())->getElementType()), - Func, Args, NameStr); + Func, Args, Bundles, NameStr); } void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args, - const Twine &NameStr); + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr); void init(Value *Func, const Twine &NameStr); /// Construct a CallInst given a range of arguments. /// \brief Construct a CallInst from a range of arguments inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, - const Twine &NameStr, Instruction *InsertBefore); - inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, + Instruction *InsertBefore); + inline CallInst(Value *Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, Instruction *InsertBefore) : CallInst(cast<FunctionType>( cast<PointerType>(Func->getType())->getElementType()), - Func, Args, NameStr, InsertBefore) {} + Func, Args, Bundles, NameStr, InsertBefore) {} + + inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, + Instruction *InsertBefore) + : CallInst(Func, Args, None, NameStr, InsertBefore) {} /// Construct a CallInst given a range of arguments. /// \brief Construct a CallInst from a range of arguments inline CallInst(Value *Func, ArrayRef<Value *> Args, - const Twine &NameStr, BasicBlock *InsertAtEnd); + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, + BasicBlock *InsertAtEnd); explicit CallInst(Value *F, const Twine &NameStr, Instruction *InsertBefore); CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); + + friend class OperandBundleUser<CallInst, User::op_iterator>; + bool hasDescriptor() const { return HasDescriptor; } + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; CallInst *cloneImpl() const; public: - static CallInst *Create(Value *Func, - ArrayRef<Value *> Args, + static CallInst *Create(Value *Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(cast<FunctionType>( cast<PointerType>(Func->getType())->getElementType()), - Func, Args, NameStr, InsertBefore); + Func, Args, Bundles, NameStr, InsertBefore); + } + static CallInst *Create(Value *Func, ArrayRef<Value *> Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(cast<FunctionType>( + cast<PointerType>(Func->getType())->getElementType()), + Func, Args, None, NameStr, InsertBefore); } static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, - const Twine &NameStr = "", + const Twine &NameStr, Instruction *InsertBefore = nullptr) { return new (unsigned(Args.size() + 1)) - CallInst(Ty, Func, Args, NameStr, InsertBefore); + CallInst(Ty, Func, Args, None, NameStr, InsertBefore); } - static CallInst *Create(Value *Func, - ArrayRef<Value *> Args, + static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + const unsigned TotalOps = + unsigned(Args.size()) + CountBundleInputs(Bundles) + 1; + const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (TotalOps, DescriptorBytes) + CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore); + } + static CallInst *Create(Value *Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new(unsigned(Args.size() + 1)) - CallInst(Func, Args, NameStr, InsertAtEnd); + const unsigned TotalOps = + unsigned(Args.size()) + CountBundleInputs(Bundles) + 1; + const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (TotalOps, DescriptorBytes) + CallInst(Func, Args, Bundles, NameStr, InsertAtEnd); + } + static CallInst *Create(Value *Func, ArrayRef<Value *> Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return new (unsigned(Args.size() + 1)) + CallInst(Func, Args, None, NameStr, InsertAtEnd); } static CallInst *Create(Value *F, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { @@ -1415,6 +1464,16 @@ public: BasicBlock *InsertAtEnd) { return new(1) CallInst(F, NameStr, InsertAtEnd); } + + /// \brief Create a clone of \p CI with a different set of operand bundles and + /// insert it before \p InsertPt. + /// + /// The returned call instruction is identical \p CI in every way except that + /// the operand bundles for the new instruction are set to the operand bundles + /// in \p Bundles. + static CallInst *Create(CallInst *CI, ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertPt = nullptr); + /// CreateMalloc - Generate the IR for a call to malloc: /// 1. Compute the malloc call's argument as the specified type's size, /// possibly multiplied by the array size if the array size is not @@ -1445,16 +1504,21 @@ public: } // Note that 'musttail' implies 'tail'. - enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2 }; + enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2, + TCK_NoTail = 3 }; TailCallKind getTailCallKind() const { return TailCallKind(getSubclassDataFromInstruction() & 3); } bool isTailCall() const { - return (getSubclassDataFromInstruction() & 3) != TCK_None; + unsigned Kind = getSubclassDataFromInstruction() & 3; + return Kind == TCK_Tail || Kind == TCK_MustTail; } bool isMustTailCall() const { return (getSubclassDataFromInstruction() & 3) == TCK_MustTail; } + bool isNoTailCall() const { + return (getSubclassDataFromInstruction() & 3) == TCK_NoTail; + } void setTailCall(bool isTC = true) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | unsigned(isTC ? TCK_Tail : TCK_None)); @@ -1469,28 +1533,58 @@ public: /// getNumArgOperands - Return the number of call arguments. /// - unsigned getNumArgOperands() const { return getNumOperands() - 1; } + unsigned getNumArgOperands() const { + return getNumOperands() - getNumTotalBundleOperands() - 1; + } /// getArgOperand/setArgOperand - Return/set the i-th call argument. /// - Value *getArgOperand(unsigned i) const { return getOperand(i); } - void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + Value *getArgOperand(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperand(i); + } + void setArgOperand(unsigned i, Value *v) { + assert(i < getNumArgOperands() && "Out of bounds!"); + setOperand(i, v); + } + + /// \brief Return the iterator pointing to the beginning of the argument list. + op_iterator arg_begin() { return op_begin(); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the end of the argument list. + op_iterator arg_end() { + // [ call args ], [ operand bundles ], callee + return op_end() - getNumTotalBundleOperands() - 1; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range<op_iterator> arg_operands() { - // The last operand in the op list is the callee - it's not one of the args - // so we don't want to iterate over it. - return iterator_range<op_iterator>(op_begin(), op_end() - 1); + return make_range(arg_begin(), arg_end()); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + const_op_iterator arg_begin() const { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + const_op_iterator arg_end() const { + // [ call args ], [ operand bundles ], callee + return op_end() - getNumTotalBundleOperands() - 1; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range<const_op_iterator> arg_operands() const { - return iterator_range<const_op_iterator>(op_begin(), op_end() - 1); + return make_range(arg_begin(), arg_end()); } /// \brief Wrappers for getting the \c Use of a call argument. - const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } - Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } + const Use &getArgOperandUse(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } + Use &getArgOperandUse(unsigned i) { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. @@ -1498,8 +1592,10 @@ public: return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 2); } void setCallingConv(CallingConv::ID CC) { + auto ID = static_cast<unsigned>(CC); + assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention"); setInstructionSubclassData((getSubclassDataFromInstruction() & 3) | - (static_cast<unsigned>(CC) << 2)); + (ID << 2)); } /// getAttributes - Return the parameter attributes for this call. @@ -1541,6 +1637,21 @@ public: /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Return true if the data operand at index \p i has the attribute \p + /// A. + /// + /// Data operands include call arguments and values used in operand bundles, + /// but does not include the callee operand. This routine dispatches to the + /// underlying AttributeList or the OperandBundleUser as appropriate. + /// + /// The index \p i is interpreted as + /// + /// \p i == Attribute::ReturnIndex -> the return value + /// \p i in [1, arg_size + 1) -> argument number (\p i - 1) + /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index + /// (\p i - 1) in the operand list. + bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { return AttributeList.getParamAlignment(i); @@ -1557,7 +1668,14 @@ public: uint64_t getDereferenceableOrNullBytes(unsigned i) const { return AttributeList.getDereferenceableOrNullBytes(i); } - + + /// @brief Determine if the parameter or return value is marked with NoAlias + /// attribute. + /// @param n The parameter to check. 1 is the first parameter, 0 is the return + bool doesNotAlias(unsigned n) const { + return AttributeList.hasAttribute(n, Attribute::NoAlias); + } + /// \brief Return true if the call should not be treated as a call to a /// builtin. bool isNoBuiltin() const { @@ -1622,9 +1740,18 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate); } + /// \brief Determine if the call is convergent + bool isConvergent() const { return hasFnAttr(Attribute::Convergent); } + void setConvergent() { + addAttribute(AttributeSet::FunctionIndex, Attribute::Convergent); + } + /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { + if (getNumArgOperands() == 0) + return false; + // Be friendly and also check the callee. return paramHasAttr(1, Attribute::StructRet); } @@ -1671,12 +1798,17 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } -private: - template<typename AttrKind> - bool hasFnAttrImpl(AttrKind A) const { +private: + template <typename AttrKind> bool hasFnAttrImpl(AttrKind A) const { if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) return true; + + // Operand bundles override attributes on the called function, but don't + // override attributes directly present on the call instruction. + if (isFnAttrDisallowedByOpBundle(A)) + return false; + if (const Function *F = getCalledFunction()) return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A); return false; @@ -1694,24 +1826,28 @@ struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> { }; CallInst::CallInst(Value *Func, ArrayRef<Value *> Args, - const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, - OperandTraits<CallInst>::op_end(this) - (Args.size() + 1), - unsigned(Args.size() + 1), InsertAtEnd) { - init(Func, Args, NameStr); + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : Instruction( + cast<FunctionType>(cast<PointerType>(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, OperandTraits<CallInst>::op_end(this) - + (Args.size() + CountBundleInputs(Bundles) + 1), + unsigned(Args.size() + CountBundleInputs(Bundles) + 1), InsertAtEnd) { + init(Func, Args, Bundles, NameStr); } CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args, - const Twine &NameStr, Instruction *InsertBefore) + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, + Instruction *InsertBefore) : Instruction(Ty->getReturnType(), Instruction::Call, - OperandTraits<CallInst>::op_end(this) - (Args.size() + 1), - unsigned(Args.size() + 1), InsertBefore) { - init(Ty, Func, Args, NameStr); + OperandTraits<CallInst>::op_end(this) - + (Args.size() + CountBundleInputs(Bundles) + 1), + unsigned(Args.size() + CountBundleInputs(Bundles) + 1), + InsertBefore) { + init(Ty, Func, Args, Bundles, NameStr); } - // Note: if you get compile errors about private methods then // please update your code to use the high-level operand // interfaces. See line 943 above. @@ -1745,6 +1881,7 @@ class SelectInst : public Instruction { init(C, S1, S2); setName(NameStr); } + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -1845,6 +1982,7 @@ class ExtractElementInst : public Instruction { Instruction *InsertBefore = nullptr); ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -1875,7 +2013,6 @@ public: return cast<VectorType>(getVectorOperand()->getType()); } - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1906,8 +2043,9 @@ class InsertElementInst : public Instruction { InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); - InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, - const Twine &NameStr, BasicBlock *InsertAtEnd); + InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, + BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2020,7 +2158,6 @@ public: return Mask; } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; @@ -2063,9 +2200,8 @@ class ExtractValueInst : public UnaryInstruction { const Twine &NameStr, BasicBlock *InsertAtEnd); // allocate space for exactly one operand - void *operator new(size_t s) { - return User::operator new(s, 1); - } + void *operator new(size_t s) { return User::operator new(s, 1); } + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2096,7 +2232,7 @@ public: inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range<idx_iterator> indices() const { - return iterator_range<idx_iterator>(idx_begin(), idx_end()); + return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { @@ -2147,7 +2283,6 @@ ExtractValueInst::ExtractValueInst(Value *Agg, init(Idxs, NameStr); } - //===----------------------------------------------------------------------===// // InsertValueInst Class //===----------------------------------------------------------------------===// @@ -2177,11 +2312,12 @@ class InsertValueInst : public Instruction { /// Constructors - These two constructors are convenience methods because one /// and two index insertvalue instructions are so common. - InsertValueInst(Value *Agg, Value *Val, - unsigned Idx, const Twine &NameStr = "", - Instruction *InsertBefore = nullptr); InsertValueInst(Value *Agg, Value *Val, unsigned Idx, - const Twine &NameStr, BasicBlock *InsertAtEnd); + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr); + InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr, + BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2213,7 +2349,7 @@ public: inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range<idx_iterator> indices() const { - return iterator_range<idx_iterator>(idx_begin(), idx_end()); + return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { @@ -2294,6 +2430,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) // scientist's overactive imagination. // class PHINode : public Instruction { + void anchor() override; + void *operator new(size_t, unsigned) = delete; /// ReservedSpace - The number of operands actually allocated. NumOperands is /// the number actually in use. @@ -2319,6 +2457,7 @@ class PHINode : public Instruction { setName(NameStr); allocHungoffUses(ReservedSpace); } + protected: // allocHungoffUses - this is more complicated than the generic // User::allocHungoffUses, because we have to allocate Uses for the incoming @@ -2387,6 +2526,9 @@ public: return getOperand(i); } void setIncomingValue(unsigned i, Value *V) { + assert(V && "PHI node got a null value!"); + assert(getType() == V->getType() && + "All operands to PHI node must be the same type as the PHI node!"); setOperand(i, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { @@ -2418,16 +2560,13 @@ public: } void setIncomingBlock(unsigned i, BasicBlock *BB) { + assert(BB && "PHI node got a null basic block!"); block_begin()[i] = BB; } /// addIncoming - Add an incoming value to the end of the PHI list /// void addIncoming(Value *V, BasicBlock *BB) { - assert(V && "PHI node got a null value!"); - assert(BB && "PHI node got a null basic block!"); - assert(getType() == V->getType() && - "All operands to PHI node must be the same type as the PHI node!"); if (getNumOperands() == ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. @@ -2479,7 +2618,8 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } - private: + +private: void growOperands(); }; @@ -2506,8 +2646,10 @@ class LandingPadInst : public Instruction { /// the number actually in use. unsigned ReservedSpace; LandingPadInst(const LandingPadInst &LP); + public: enum ClauseType { Catch, Filter }; + private: void *operator new(size_t, unsigned) = delete; // Allocate space for exactly zero operands. @@ -2618,6 +2760,7 @@ private: Instruction *InsertBefore = nullptr); ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2654,7 +2797,8 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } - private: + +private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; void setSuccessorV(unsigned idx, BasicBlock *B) override; @@ -2693,6 +2837,7 @@ class BranchInst : public TerminatorInst { BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2740,7 +2885,7 @@ public: void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for Branch!"); - *(&Op<-1>() - idx) = (Value*)NewSucc; + *(&Op<-1>() - idx) = NewSucc; } /// \brief Swap the successors of this branch instruction. @@ -2757,6 +2902,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -2803,25 +2949,23 @@ class SwitchInst : public TerminatorInst { /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; SwitchInst *cloneImpl() const; public: - // -2 static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1); template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy> class CaseIteratorT { protected: - SwitchInstTy *SI; unsigned Index; public: - typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self; /// Initializes case iterator for given SwitchInst and for given @@ -2912,8 +3056,7 @@ public: typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy; public: - - CaseIt(const ParentTy& Src) : ParentTy(Src) {} + CaseIt(const ParentTy &Src) : ParentTy(Src) {} CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {} /// Sets the new value for current case. @@ -2983,12 +3126,12 @@ public: /// cases - iteration adapter for range-for loops. iterator_range<CaseIt> cases() { - return iterator_range<CaseIt>(case_begin(), case_end()); + return make_range(case_begin(), case_end()); } /// cases - iteration adapter for range-for loops. iterator_range<ConstCaseIt> cases() const { - return iterator_range<ConstCaseIt>(case_begin(), case_end()); + return make_range(case_begin(), case_end()); } /// Returns an iterator that points to the default case. @@ -3056,7 +3199,7 @@ public: } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); - setOperand(idx*2+1, (Value*)NewSucc); + setOperand(idx * 2 + 1, NewSucc); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -3066,6 +3209,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -3078,7 +3222,6 @@ struct OperandTraits<SwitchInst> : public HungoffOperandTraits<2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value) - //===----------------------------------------------------------------------===// // IndirectBrInst Class //===----------------------------------------------------------------------===// @@ -3111,6 +3254,7 @@ class IndirectBrInst : public TerminatorInst { /// here to make memory allocation more efficient. This constructor also /// autoinserts at the end of the specified BasicBlock. IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -3134,7 +3278,6 @@ public: const Value *getAddress() const { return getOperand(0); } void setAddress(Value *V) { setOperand(0, V); } - /// getNumDestinations - return the number of possible destinations in this /// indirectbr instruction. unsigned getNumDestinations() const { return getNumOperands()-1; } @@ -3156,7 +3299,7 @@ public: return cast<BasicBlock>(getOperand(i+1)); } void setSuccessor(unsigned i, BasicBlock *NewSucc) { - setOperand(i+1, (Value*)NewSucc); + setOperand(i + 1, NewSucc); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -3166,6 +3309,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -3178,7 +3322,6 @@ struct OperandTraits<IndirectBrInst> : public HungoffOperandTraits<1> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) - //===----------------------------------------------------------------------===// // InvokeInst Class //===----------------------------------------------------------------------===// @@ -3186,72 +3329,123 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) /// InvokeInst - Invoke instruction. The SubclassData field is used to hold the /// calling convention of the call. /// -class InvokeInst : public TerminatorInst { +class InvokeInst : public TerminatorInst, + public OperandBundleUser<InvokeInst, User::op_iterator> { AttributeSet AttributeList; FunctionType *FTy; InvokeInst(const InvokeInst &BI); void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, const Twine &NameStr) { + ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr) { init(cast<FunctionType>( cast<PointerType>(Func->getType())->getElementType()), - Func, IfNormal, IfException, Args, NameStr); + Func, IfNormal, IfException, Args, Bundles, NameStr); } void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, - const Twine &NameStr); + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr); /// Construct an InvokeInst given a range of arguments. /// /// \brief Construct an InvokeInst from a range of arguments inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, unsigned Values, - const Twine &NameStr, Instruction *InsertBefore) + ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) : InvokeInst(cast<FunctionType>( cast<PointerType>(Func->getType())->getElementType()), - Func, IfNormal, IfException, Args, Values, NameStr, + Func, IfNormal, IfException, Args, Bundles, Values, NameStr, InsertBefore) {} inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, - unsigned Values, const Twine &NameStr, - Instruction *InsertBefore); + ArrayRef<OperandBundleDef> Bundles, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore); /// Construct an InvokeInst given a range of arguments. /// /// \brief Construct an InvokeInst from a range of arguments inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, unsigned Values, - const Twine &NameStr, BasicBlock *InsertAtEnd); + ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd); + + friend class OperandBundleUser<InvokeInst, User::op_iterator>; + bool hasDescriptor() const { return HasDescriptor; } + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; InvokeInst *cloneImpl() const; public: - static InvokeInst *Create(Value *Func, - BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, const Twine &NameStr = "", + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef<Value *> Args, + const Twine &NameStr, Instruction *InsertBefore = nullptr) { return Create(cast<FunctionType>( cast<PointerType>(Func->getType())->getElementType()), - Func, IfNormal, IfException, Args, NameStr, InsertBefore); + Func, IfNormal, IfException, Args, None, NameStr, + InsertBefore); } - static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { + return Create(cast<FunctionType>( + cast<PointerType>(Func->getType())->getElementType()), + Func, IfNormal, IfException, Args, Bundles, NameStr, + InsertBefore); + } + static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef<Value *> Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { unsigned Values = unsigned(Args.size()) + 3; - return new (Values) InvokeInst(Ty, Func, IfNormal, IfException, Args, + return new (Values) InvokeInst(Ty, Func, IfNormal, IfException, Args, None, Values, NameStr, InsertBefore); } + static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = unsigned(Args.size()) + CountBundleInputs(Bundles) + 3; + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (Values, DescriptorBytes) + InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, Values, + NameStr, InsertBefore); + } static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = unsigned(Args.size()) + 3; - return new(Values) InvokeInst(Func, IfNormal, IfException, Args, - Values, NameStr, InsertAtEnd); + return new (Values) InvokeInst(Func, IfNormal, IfException, Args, None, + Values, NameStr, InsertAtEnd); + } + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = unsigned(Args.size()) + CountBundleInputs(Bundles) + 3; + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (Values, DescriptorBytes) + InvokeInst(Func, IfNormal, IfException, Args, Bundles, Values, NameStr, + InsertAtEnd); } + /// \brief Create a clone of \p II with a different set of operand bundles and + /// insert it before \p InsertPt. + /// + /// The returned invoke instruction is identical to \p II in every way except + /// that the operand bundles for the new instruction are set to the operand + /// bundles in \p Bundles. + static InvokeInst *Create(InvokeInst *II, ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertPt = nullptr); + /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -3264,26 +3458,58 @@ public: /// getNumArgOperands - Return the number of invoke arguments. /// - unsigned getNumArgOperands() const { return getNumOperands() - 3; } + unsigned getNumArgOperands() const { + return getNumOperands() - getNumTotalBundleOperands() - 3; + } /// getArgOperand/setArgOperand - Return/set the i-th invoke argument. /// - Value *getArgOperand(unsigned i) const { return getOperand(i); } - void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + Value *getArgOperand(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperand(i); + } + void setArgOperand(unsigned i, Value *v) { + assert(i < getNumArgOperands() && "Out of bounds!"); + setOperand(i, v); + } + + /// \brief Return the iterator pointing to the beginning of the argument list. + op_iterator arg_begin() { return op_begin(); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the end of the argument list. + op_iterator arg_end() { + // [ invoke args ], [ operand bundles ], normal dest, unwind dest, callee + return op_end() - getNumTotalBundleOperands() - 3; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range<op_iterator> arg_operands() { - return iterator_range<op_iterator>(op_begin(), op_end() - 3); + return make_range(arg_begin(), arg_end()); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + const_op_iterator arg_begin() const { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + const_op_iterator arg_end() const { + // [ invoke args ], [ operand bundles ], normal dest, unwind dest, callee + return op_end() - getNumTotalBundleOperands() - 3; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range<const_op_iterator> arg_operands() const { - return iterator_range<const_op_iterator>(op_begin(), op_end() - 3); + return make_range(arg_begin(), arg_end()); } /// \brief Wrappers for getting the \c Use of a invoke argument. - const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } - Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } + const Use &getArgOperandUse(unsigned i) const { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } + Use &getArgOperandUse(unsigned i) { + assert(i < getNumArgOperands() && "Out of bounds!"); + return getOperandUse(i); + } /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. @@ -3291,7 +3517,9 @@ public: return static_cast<CallingConv::ID>(getSubclassDataFromInstruction()); } void setCallingConv(CallingConv::ID CC) { - setInstructionSubclassData(static_cast<unsigned>(CC)); + auto ID = static_cast<unsigned>(CC); + assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention"); + setInstructionSubclassData(ID); } /// getAttributes - Return the parameter attributes for this invoke. @@ -3325,6 +3553,22 @@ public: /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Return true if the data operand at index \p i has the attribute \p + /// A. + /// + /// Data operands include invoke arguments and values used in operand bundles, + /// but does not include the invokee operand, or the two successor blocks. + /// This routine dispatches to the underlying AttributeList or the + /// OperandBundleUser as appropriate. + /// + /// The index \p i is interpreted as + /// + /// \p i == Attribute::ReturnIndex -> the return value + /// \p i in [1, arg_size + 1) -> argument number (\p i - 1) + /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index + /// (\p i - 1) in the operand list. + bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const; + /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { return AttributeList.getParamAlignment(i); @@ -3335,13 +3579,20 @@ public: uint64_t getDereferenceableBytes(unsigned i) const { return AttributeList.getDereferenceableBytes(i); } - + /// \brief Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). uint64_t getDereferenceableOrNullBytes(unsigned i) const { return AttributeList.getDereferenceableOrNullBytes(i); } + /// @brief Determine if the parameter or return value is marked with NoAlias + /// attribute. + /// @param n The parameter to check. 1 is the first parameter, 0 is the return + bool doesNotAlias(unsigned n) const { + return AttributeList.hasAttribute(n, Attribute::NoAlias); + } + /// \brief Return true if the call should not be treated as a call to a /// builtin. bool isNoBuiltin() const { @@ -3403,6 +3654,9 @@ public: /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { + if (getNumArgOperands() == 0) + return false; + // Be friendly and also check the callee. return paramHasAttr(1, Attribute::StructRet); } @@ -3495,23 +3749,23 @@ struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> { InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, - unsigned Values, const Twine &NameStr, - Instruction *InsertBefore) + ArrayRef<OperandBundleDef> Bundles, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore) : TerminatorInst(Ty->getReturnType(), Instruction::Invoke, OperandTraits<InvokeInst>::op_end(this) - Values, Values, InsertBefore) { - init(Ty, Func, IfNormal, IfException, Args, NameStr); + init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr); } -InvokeInst::InvokeInst(Value *Func, - BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, unsigned Values, +InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, + BasicBlock *IfException, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Invoke, - OperandTraits<InvokeInst>::op_end(this) - Values, - Values, InsertAtEnd) { - init(Func, IfNormal, IfException, Args, NameStr); + : TerminatorInst( + cast<FunctionType>(cast<PointerType>(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Invoke, OperandTraits<InvokeInst>::op_end(this) - Values, + Values, InsertAtEnd) { + init(Func, IfNormal, IfException, Args, Bundles, NameStr); } DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) @@ -3528,6 +3782,7 @@ class ResumeInst : public TerminatorInst { explicit ResumeInst(Value *Exn, Instruction *InsertBefore=nullptr); ResumeInst(Value *Exn, BasicBlock *InsertAtEnd); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -3556,6 +3811,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; @@ -3570,6 +3826,430 @@ struct OperandTraits<ResumeInst> : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) //===----------------------------------------------------------------------===// +// CatchSwitchInst Class +//===----------------------------------------------------------------------===// +class CatchSwitchInst : public TerminatorInst { + void *operator new(size_t, unsigned) = delete; + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; + // Operand[0] = Outer scope + // Operand[1] = Unwind block destination + // Operand[n] = BasicBlock to go to on match + CatchSwitchInst(const CatchSwitchInst &CSI); + void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved); + void growOperands(unsigned Size); + // allocate space for exactly zero operands + void *operator new(size_t s) { return User::operator new(s); } + /// CatchSwitchInst ctor - Create a new switch instruction, specifying a + /// default destination. The number of additional handlers can be specified + /// here to make memory allocation more efficient. + /// This constructor can also autoinsert before another instruction. + CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, + Instruction *InsertBefore); + + /// CatchSwitchInst ctor - Create a new switch instruction, specifying a + /// default destination. The number of additional handlers can be specified + /// here to make memory allocation more efficient. + /// This constructor also autoinserts at the end of the specified BasicBlock. + CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, + BasicBlock *InsertAtEnd); + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + CatchSwitchInst *cloneImpl() const; + +public: + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertBefore); + } + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, + BasicBlock *InsertAtEnd) { + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertAtEnd); + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + // Accessor Methods for CatchSwitch stmt + Value *getParentPad() const { return getOperand(0); } + void setParentPad(Value *ParentPad) { setOperand(0, ParentPad); } + + // Accessor Methods for CatchSwitch stmt + bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } + bool unwindsToCaller() const { return !hasUnwindDest(); } + BasicBlock *getUnwindDest() const { + if (hasUnwindDest()) + return cast<BasicBlock>(getOperand(1)); + return nullptr; + } + void setUnwindDest(BasicBlock *UnwindDest) { + assert(UnwindDest); + assert(hasUnwindDest()); + setOperand(1, UnwindDest); + } + + /// getNumHandlers - return the number of 'handlers' in this catchswitch + /// instruction, except the default handler + unsigned getNumHandlers() const { + if (hasUnwindDest()) + return getNumOperands() - 2; + return getNumOperands() - 1; + } + +private: + static BasicBlock *handler_helper(Value *V) { return cast<BasicBlock>(V); } + static const BasicBlock *handler_helper(const Value *V) { + return cast<BasicBlock>(V); + } + +public: + typedef std::pointer_to_unary_function<Value *, BasicBlock *> DerefFnTy; + typedef mapped_iterator<op_iterator, DerefFnTy> handler_iterator; + typedef iterator_range<handler_iterator> handler_range; + + + typedef std::pointer_to_unary_function<const Value *, const BasicBlock *> + ConstDerefFnTy; + typedef mapped_iterator<const_op_iterator, ConstDerefFnTy> const_handler_iterator; + typedef iterator_range<const_handler_iterator> const_handler_range; + + /// Returns an iterator that points to the first handler in CatchSwitchInst. + handler_iterator handler_begin() { + op_iterator It = op_begin() + 1; + if (hasUnwindDest()) + ++It; + return handler_iterator(It, DerefFnTy(handler_helper)); + } + /// Returns an iterator that points to the first handler in the + /// CatchSwitchInst. + const_handler_iterator handler_begin() const { + const_op_iterator It = op_begin() + 1; + if (hasUnwindDest()) + ++It; + return const_handler_iterator(It, ConstDerefFnTy(handler_helper)); + } + + /// Returns a read-only iterator that points one past the last + /// handler in the CatchSwitchInst. + handler_iterator handler_end() { + return handler_iterator(op_end(), DerefFnTy(handler_helper)); + } + /// Returns an iterator that points one past the last handler in the + /// CatchSwitchInst. + const_handler_iterator handler_end() const { + return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper)); + } + + /// handlers - iteration adapter for range-for loops. + handler_range handlers() { + return make_range(handler_begin(), handler_end()); + } + + /// handlers - iteration adapter for range-for loops. + const_handler_range handlers() const { + return make_range(handler_begin(), handler_end()); + } + + /// addHandler - Add an entry to the switch instruction... + /// Note: + /// This action invalidates handler_end(). Old handler_end() iterator will + /// point to the added handler. + void addHandler(BasicBlock *Dest); + + unsigned getNumSuccessors() const { return getNumOperands() - 1; } + BasicBlock *getSuccessor(unsigned Idx) const { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + return cast<BasicBlock>(getOperand(Idx + 1)); + } + void setSuccessor(unsigned Idx, BasicBlock *NewSucc) { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + setOperand(Idx + 1, NewSucc); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::CatchSwitch; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } + +private: + BasicBlock *getSuccessorV(unsigned Idx) const override; + unsigned getNumSuccessorsV() const override; + void setSuccessorV(unsigned Idx, BasicBlock *B) override; +}; + +template <> +struct OperandTraits<CatchSwitchInst> : public HungoffOperandTraits<2> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value) + +//===----------------------------------------------------------------------===// +// CleanupPadInst Class +//===----------------------------------------------------------------------===// +class CleanupPadInst : public FuncletPadInst { +private: + explicit CleanupPadInst(Value *ParentPad, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertBefore) {} + explicit CleanupPadInst(Value *ParentPad, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertAtEnd) {} + +public: + static CleanupPadInst *Create(Value *ParentPad, ArrayRef<Value *> Args = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore); + } + static CleanupPadInst *Create(Value *ParentPad, ArrayRef<Value *> Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertAtEnd); + } + + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::CleanupPad; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// CatchPadInst Class +//===----------------------------------------------------------------------===// +class CatchPadInst : public FuncletPadInst { +private: + explicit CatchPadInst(Value *CatchSwitch, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertBefore) {} + explicit CatchPadInst(Value *CatchSwitch, ArrayRef<Value *> Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertAtEnd) {} + +public: + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = 1 + Args.size(); + return new (Values) + CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore); + } + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = 1 + Args.size(); + return new (Values) + CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertAtEnd); + } + + /// Convenience accessors + CatchSwitchInst *getCatchSwitch() const { + return cast<CatchSwitchInst>(Op<-1>()); + } + void setCatchSwitch(Value *CatchSwitch) { + assert(CatchSwitch); + Op<-1>() = CatchSwitch; + } + + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::CatchPad; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// CatchReturnInst Class +//===----------------------------------------------------------------------===// + +class CatchReturnInst : public TerminatorInst { + CatchReturnInst(const CatchReturnInst &RI); + + void init(Value *CatchPad, BasicBlock *BB); + CatchReturnInst(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore); + CatchReturnInst(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd); + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + CatchReturnInst *cloneImpl() const; + +public: + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, + Instruction *InsertBefore = nullptr) { + assert(CatchPad); + assert(BB); + return new (2) CatchReturnInst(CatchPad, BB, InsertBefore); + } + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, + BasicBlock *InsertAtEnd) { + assert(CatchPad); + assert(BB); + return new (2) CatchReturnInst(CatchPad, BB, InsertAtEnd); + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// Convenience accessors. + CatchPadInst *getCatchPad() const { return cast<CatchPadInst>(Op<0>()); } + void setCatchPad(CatchPadInst *CatchPad) { + assert(CatchPad); + Op<0>() = CatchPad; + } + + BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<1>()); } + void setSuccessor(BasicBlock *NewSucc) { + assert(NewSucc); + Op<1>() = NewSucc; + } + unsigned getNumSuccessors() const { return 1; } + + Value *getParentPad() const { + return getCatchPad()->getCatchSwitch()->getParentPad(); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return (I->getOpcode() == Instruction::CatchRet); + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } + +private: + BasicBlock *getSuccessorV(unsigned Idx) const override; + unsigned getNumSuccessorsV() const override; + void setSuccessorV(unsigned Idx, BasicBlock *B) override; +}; + +template <> +struct OperandTraits<CatchReturnInst> + : public FixedNumOperandTraits<CatchReturnInst, 2> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value) + +//===----------------------------------------------------------------------===// +// CleanupReturnInst Class +//===----------------------------------------------------------------------===// + +class CleanupReturnInst : public TerminatorInst { +private: + CleanupReturnInst(const CleanupReturnInst &RI); + + void init(Value *CleanupPad, BasicBlock *UnwindBB); + CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, + Instruction *InsertBefore = nullptr); + CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, + BasicBlock *InsertAtEnd); + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + CleanupReturnInst *cloneImpl() const; + +public: + static CleanupReturnInst *Create(Value *CleanupPad, + BasicBlock *UnwindBB = nullptr, + Instruction *InsertBefore = nullptr) { + assert(CleanupPad); + unsigned Values = 1; + if (UnwindBB) + ++Values; + return new (Values) + CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore); + } + static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB, + BasicBlock *InsertAtEnd) { + assert(CleanupPad); + unsigned Values = 1; + if (UnwindBB) + ++Values; + return new (Values) + CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertAtEnd); + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } + bool unwindsToCaller() const { return !hasUnwindDest(); } + + /// Convenience accessor. + CleanupPadInst *getCleanupPad() const { + return cast<CleanupPadInst>(Op<0>()); + } + void setCleanupPad(CleanupPadInst *CleanupPad) { + assert(CleanupPad); + Op<0>() = CleanupPad; + } + + unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } + + BasicBlock *getUnwindDest() const { + return hasUnwindDest() ? cast<BasicBlock>(Op<1>()) : nullptr; + } + void setUnwindDest(BasicBlock *NewDest) { + assert(NewDest); + assert(hasUnwindDest()); + Op<1>() = NewDest; + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Instruction *I) { + return (I->getOpcode() == Instruction::CleanupRet); + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } + +private: + BasicBlock *getSuccessorV(unsigned Idx) const override; + unsigned getNumSuccessorsV() const override; + void setSuccessorV(unsigned Idx, BasicBlock *B) override; + + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +template <> +struct OperandTraits<CleanupReturnInst> + : public VariadicOperandTraits<CleanupReturnInst, /*MINARITY=*/1> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value) + +//===----------------------------------------------------------------------===// // UnreachableInst Class //===----------------------------------------------------------------------===// @@ -3580,6 +4260,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) /// class UnreachableInst : public TerminatorInst { void *operator new(size_t, unsigned) = delete; + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -3602,6 +4283,7 @@ public: static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + private: BasicBlock *getSuccessorV(unsigned idx) const override; unsigned getNumSuccessorsV() const override; diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index 2c8b6eb6f39a..169bcc021984 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -372,6 +372,39 @@ namespace llvm { return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); } }; -} + + /// This represents the llvm.instrprof_value_profile intrinsic. + class InstrProfValueProfileInst : public IntrinsicInst { + public: + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; + } + static inline bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + + GlobalVariable *getName() const { + return cast<GlobalVariable>( + const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); + } + + ConstantInt *getHash() const { + return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); + } + + Value *getTargetValue() const { + return cast<Value>(const_cast<Value *>(getArgOperand(2))); + } + + ConstantInt *getValueKind() const { + return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); + } + + // Returns the value site index. + ConstantInt *getIndex() const { + return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); + } + }; +} // namespace llvm #endif diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h index 43b8325107fa..314e2aaecf4b 100644 --- a/include/llvm/IR/Intrinsics.h +++ b/include/llvm/IR/Intrinsics.h @@ -79,7 +79,7 @@ namespace Intrinsic { /// intrinsic. This is returned by getIntrinsicInfoTableEntries. struct IITDescriptor { enum IITDescriptorKind { - Void, VarArg, MMX, Metadata, Half, Float, Double, + Void, VarArg, MMX, Token, Metadata, Half, Float, Double, Integer, Vector, Pointer, Struct, Argument, ExtendArgument, TruncArgument, HalfVecArgument, SameVecWidthArgument, PtrToArgument, VecOfPtrsToElt diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index bbae720b4e12..5a95ddced538 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -73,8 +73,8 @@ def IntrNoReturn : IntrinsicProperty; // Parallels the noduplicate attribute on LLVM IR functions. def IntrNoDuplicate : IntrinsicProperty; -// IntrConvergent - Calls to this intrinsic are convergent and may only be -// moved to control equivalent blocks. +// IntrConvergent - Calls to this intrinsic are convergent and may not be made +// control-dependent on any additional values. // Parallels the convergent attribute on LLVM IR functions. def IntrConvergent : IntrinsicProperty; @@ -150,16 +150,20 @@ def llvm_anyptr_ty : LLVMAnyPointerType<llvm_i8_ty>; // (space)i8* def llvm_empty_ty : LLVMType<OtherVT>; // { } def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }* def llvm_metadata_ty : LLVMType<MetadataVT>; // !{...} +def llvm_token_ty : LLVMType<token>; // token def llvm_x86mmx_ty : LLVMType<x86mmx>; def llvm_ptrx86mmx_ty : LLVMPointerType<llvm_x86mmx_ty>; // <1 x i64>* -def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1 -def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1 -def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1 -def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1 -def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1 -def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1 +def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1 +def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1 +def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1 +def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1 +def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1 +def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1 +def llvm_v512i1_ty : LLVMType<v512i1>; // 512 x i1 +def llvm_v1024i1_ty : LLVMType<v1024i1>; //1024 x i1 + def llvm_v1i8_ty : LLVMType<v1i8>; // 1 x i8 def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8 def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8 @@ -167,6 +171,8 @@ def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8 def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8 def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8 def llvm_v64i8_ty : LLVMType<v64i8>; // 64 x i8 +def llvm_v128i8_ty : LLVMType<v128i8>; //128 x i8 +def llvm_v256i8_ty : LLVMType<v256i8>; //256 x i8 def llvm_v1i16_ty : LLVMType<v1i16>; // 1 x i16 def llvm_v2i16_ty : LLVMType<v2i16>; // 2 x i16 @@ -174,17 +180,23 @@ def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16 def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16 def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16 def llvm_v32i16_ty : LLVMType<v32i16>; // 32 x i16 +def llvm_v64i16_ty : LLVMType<v64i16>; // 64 x i16 +def llvm_v128i16_ty : LLVMType<v128i16>; //128 x i16 def llvm_v1i32_ty : LLVMType<v1i32>; // 1 x i32 def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32 def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32 def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32 def llvm_v16i32_ty : LLVMType<v16i32>; // 16 x i32 +def llvm_v32i32_ty : LLVMType<v32i32>; // 32 x i32 +def llvm_v64i32_ty : LLVMType<v64i32>; // 64 x i32 + def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64 def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64 def llvm_v4i64_ty : LLVMType<v4i64>; // 4 x i64 def llvm_v8i64_ty : LLVMType<v8i64>; // 8 x i64 def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64 +def llvm_v32i64_ty : LLVMType<v32i64>; // 32 x i64 def llvm_v1i128_ty : LLVMType<v1i128>; // 1 x i128 @@ -292,6 +304,8 @@ def int_stacksave : Intrinsic<[llvm_ptr_ty]>, def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>, GCCBuiltin<"__builtin_stack_restore">; +def int_get_dynamic_area_offset : Intrinsic<[llvm_anyint_ty]>; + // IntrReadWriteArgMem is more pessimistic than strictly necessary for prefetch, // however it does conveniently prevent the prefetch from being reordered // with respect to nearby accesses to the same memory. @@ -319,6 +333,14 @@ def int_instrprof_increment : Intrinsic<[], llvm_i32_ty, llvm_i32_ty], []>; +// A call to profile runtime for value profiling of target expressions +// through instrumentation based profiling. +def int_instrprof_value_profile : Intrinsic<[], + [llvm_ptr_ty, llvm_i64_ty, + llvm_i64_ty, llvm_i32_ty, + llvm_i32_ty], + []>; + //===------------------- Standard C Library Intrinsics --------------------===// // @@ -399,6 +421,7 @@ let Properties = [IntrNoMem] in { def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>; def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>; + def int_bitreverse : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; } //===------------------------ Debugger Intrinsics -------------------------===// @@ -428,17 +451,13 @@ def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>; def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>; -// eh.begincatch takes a pointer returned by a landingpad instruction and -// copies the exception object into the memory pointed to by the second -// parameter. If the second parameter is null, no copy occurs. -def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], - [NoCapture<0>, NoCapture<1>]>; -def int_eh_endcatch : Intrinsic<[], []>; +// eh.exceptionpointer returns the pointer to the exception caught by +// the given `catchpad`. +def int_eh_exceptionpointer : Intrinsic<[llvm_anyptr_ty], [llvm_token_ty], + [IntrNoMem]>; -// Represents the list of actions to take when an exception is thrown. -def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>; - -def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>; +// Gets the exception code from a catchpad token. Only used on some platforms. +def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrNoMem]>; // __builtin_unwind_init is an undocumented GCC intrinsic that causes all // callee-saved registers to be saved and restored (regardless of whether they @@ -455,6 +474,7 @@ let Properties = [IntrNoMem] in { def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>; +def int_eh_sjlj_setup_dispatch : Intrinsic<[], []>; //===---------------- Generic Variable Attribute Intrinsics----------------===// // @@ -523,6 +543,10 @@ def int_invariant_end : Intrinsic<[], llvm_ptr_ty], [IntrReadWriteArgMem, NoCapture<2>]>; +def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty], + [IntrNoMem]>; + //===------------------------ Stackmap Intrinsics -------------------------===// // def int_experimental_stackmap : Intrinsic<[], @@ -543,21 +567,17 @@ def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty], //===------------------------ Garbage Collection Intrinsics ---------------===// // These are documented in docs/Statepoint.rst -def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty], +def int_experimental_gc_statepoint : Intrinsic<[llvm_token_ty], [llvm_i64_ty, llvm_i32_ty, llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_vararg_ty], [Throws]>; -def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>; +def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_token_ty], + [IntrReadMem]>; def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty], - [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>; - -// Deprecated: will be removed in a couple of weeks -def int_experimental_gc_result_int : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty]>; -def int_experimental_gc_result_float : Intrinsic<[llvm_anyfloat_ty], - [llvm_i32_ty]>; -def int_experimental_gc_result_ptr : Intrinsic<[llvm_anyptr_ty], [llvm_i32_ty]>; + [llvm_token_ty, llvm_i32_ty, llvm_i32_ty], + [IntrReadMem]>; //===-------------------------- Other Intrinsics --------------------------===// // diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td index 7d69ed52171c..578f259aae14 100644 --- a/include/llvm/IR/IntrinsicsAArch64.td +++ b/include/llvm/IR/IntrinsicsAArch64.td @@ -13,6 +13,9 @@ let TargetPrefix = "aarch64" in { +def int_aarch64_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">, + Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; + def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>; def int_aarch64_ldaxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>; def int_aarch64_stxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty]>; diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index 510e5ad2d9b4..84582e8b9925 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -33,6 +33,14 @@ defm int_r600_read_tgid : R600ReadPreloadRegisterIntrinsic_xyz < "__builtin_r600_read_tgid">; defm int_r600_read_tidig : R600ReadPreloadRegisterIntrinsic_xyz < "__builtin_r600_read_tidig">; + +def int_r600_rat_store_typed : + // 1st parameter: Data + // 2nd parameter: Index + // 3rd parameter: Constant RAT ID + Intrinsic<[], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], []>, + GCCBuiltin<"__builtin_r600_rat_store_typed">; + } // End TargetPrefix = "r600" let TargetPrefix = "AMDGPU" in { @@ -83,3 +91,67 @@ def int_AMDGPU_read_workdim : AMDGPUReadPreloadRegisterIntrinsic < "__builtin_amdgpu_read_workdim">; } // End TargetPrefix = "AMDGPU" + +let TargetPrefix = "amdgcn" in { + +// SI only +def int_amdgcn_buffer_wbinvl1_sc : + GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1_sc">, + Intrinsic<[], [], []>; + +// On CI+ +def int_amdgcn_buffer_wbinvl1_vol : + GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1_vol">, + Intrinsic<[], [], []>; + +def int_amdgcn_buffer_wbinvl1 : + GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1">, + Intrinsic<[], [], []>; + +def int_amdgcn_s_dcache_inv : + GCCBuiltin<"__builtin_amdgcn_s_dcache_inv">, + Intrinsic<[], [], []>; + +// CI+ +def int_amdgcn_s_dcache_inv_vol : + GCCBuiltin<"__builtin_amdgcn_s_dcache_inv_vol">, + Intrinsic<[], [], []>; + +// VI +def int_amdgcn_s_dcache_wb : + GCCBuiltin<"__builtin_amdgcn_s_dcache_wb">, + Intrinsic<[], [], []>; + +// VI +def int_amdgcn_s_dcache_wb_vol : + GCCBuiltin<"__builtin_amdgcn_s_dcache_wb_vol">, + Intrinsic<[], [], []>; + +def int_amdgcn_dispatch_ptr : + GCCBuiltin<"__builtin_amdgcn_dispatch_ptr">, + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>; + +// __builtin_amdgcn_interp_p1 <i>, <attr_chan>, <attr>, <m0> +def int_amdgcn_interp_p1 : + GCCBuiltin<"__builtin_amdgcn_interp_p1">, + Intrinsic<[llvm_float_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; // This intrinsic reads from lds, but the memory + // values are constant, so it behaves like IntrNoMem. + +// __builtin_amdgcn_interp_p2 <p1>, <j>, <attr_chan>, <attr>, <m0> +def int_amdgcn_interp_p2 : + GCCBuiltin<"__builtin_amdgcn_interp_p2">, + Intrinsic<[llvm_float_ty], + [llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; // See int_amdgcn_v_interp_p1 for why this is + // IntrNoMem. + +def int_amdgcn_mbcnt_lo : + GCCBuiltin<"__builtin_amdgcn_mbcnt_lo">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + +def int_amdgcn_mbcnt_hi : + GCCBuiltin<"__builtin_amdgcn_mbcnt_hi">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +} diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index 1dff80878592..c1d911cefee2 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -405,36 +405,36 @@ def int_arm_neon_vrintp : Neon_1Arg_Intrinsic; // De-interleaving vector loads from N-element structures. // Source operands are the address and alignment. def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty], - [llvm_ptr_ty, llvm_i32_ty], + [llvm_anyptr_ty, llvm_i32_ty], [IntrReadArgMem]>; def int_arm_neon_vld2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], - [llvm_ptr_ty, llvm_i32_ty], + [llvm_anyptr_ty, llvm_i32_ty], [IntrReadArgMem]>; def int_arm_neon_vld3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>], - [llvm_ptr_ty, llvm_i32_ty], + [llvm_anyptr_ty, llvm_i32_ty], [IntrReadArgMem]>; def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], - [llvm_ptr_ty, llvm_i32_ty], + [llvm_anyptr_ty, llvm_i32_ty], [IntrReadArgMem]>; // Vector load N-element structure to one lane. // Source operands are: the address, the N input vectors (since only one // lane is assigned), the lane number, and the alignment. def int_arm_neon_vld2lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], - [llvm_ptr_ty, LLVMMatchType<0>, + [llvm_anyptr_ty, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrReadArgMem]>; def int_arm_neon_vld3lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>], - [llvm_ptr_ty, LLVMMatchType<0>, + [llvm_anyptr_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrReadArgMem]>; def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], - [llvm_ptr_ty, LLVMMatchType<0>, + [llvm_anyptr_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrReadArgMem]>; @@ -442,38 +442,38 @@ def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, // Interleaving vector stores from N-element structures. // Source operands are: the address, the N vectors, and the alignment. def int_arm_neon_vst1 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, + [llvm_anyptr_ty, llvm_anyvector_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; def int_arm_neon_vst2 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, llvm_i32_ty], + [llvm_anyptr_ty, llvm_anyvector_ty, + LLVMMatchType<1>, llvm_i32_ty], [IntrReadWriteArgMem]>; def int_arm_neon_vst3 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, + [llvm_anyptr_ty, llvm_anyvector_ty, + LLVMMatchType<1>, LLVMMatchType<1>, llvm_i32_ty], [IntrReadWriteArgMem]>; def int_arm_neon_vst4 : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>, llvm_i32_ty], + [llvm_anyptr_ty, llvm_anyvector_ty, + LLVMMatchType<1>, LLVMMatchType<1>, + LLVMMatchType<1>, llvm_i32_ty], [IntrReadWriteArgMem]>; // Vector store N-element structure from one lane. // Source operands are: the address, the N vectors, the lane number, and // the alignment. def int_arm_neon_vst2lane : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, llvm_i32_ty, + [llvm_anyptr_ty, llvm_anyvector_ty, + LLVMMatchType<1>, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; def int_arm_neon_vst3lane : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, + [llvm_anyptr_ty, llvm_anyvector_ty, + LLVMMatchType<1>, LLVMMatchType<1>, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; def int_arm_neon_vst4lane : Intrinsic<[], - [llvm_ptr_ty, llvm_anyvector_ty, - LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>, llvm_i32_ty, + [llvm_anyptr_ty, llvm_anyvector_ty, + LLVMMatchType<1>, LLVMMatchType<1>, + LLVMMatchType<1>, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; // Vector bitwise select. diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td index 78ee651d20f9..ca6fcbd44337 100644 --- a/include/llvm/IR/IntrinsicsHexagon.td +++ b/include/llvm/IR/IntrinsicsHexagon.td @@ -32,14 +32,16 @@ class Hexagon_qi_mem_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem]>; + // // DEF_FUNCTION_TYPE_1(void_ftype_SI,BT_VOID,BT_INT) -> // Hexagon_void_si_Intrinsic<string GCCIntSuffix> // class Hexagon_void_si_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, - [llvm_void_ty], [llvm_i32_ty], - [IntrNoMem]>; + [], [llvm_ptr_ty], + []>; + // // DEF_FUNCTION_TYPE_1(HI_ftype_SI,BT_I16,BT_INT) -> // Hexagon_hi_si_Intrinsic<string GCCIntSuffix> @@ -458,6 +460,11 @@ class Hexagon_mem_memdisisi_Intrinsic<string GCCIntSuffix> llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; +class Hexagon_v256_v256v256_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], + [IntrReadWriteArgMem]>; + // // Hexagon_sf_df_Intrinsic<string GCCIntSuffix> // @@ -756,6 +763,12 @@ def int_hexagon_circ_stb : Hexagon_mem_memsisisi_Intrinsic<"circ_stb">; +def int_hexagon_mm256i_vaddw : +Hexagon_v256_v256v256_Intrinsic<"_mm256i_vaddw">; + + +// This one above will not be auto-generated, +// so make sure, you don't overwrite this one. // // BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2) // @@ -4946,6 +4959,11 @@ Hexagon_di_di_Intrinsic<"HEXAGON_S2_interleave">; // def int_hexagon_S2_deinterleave : Hexagon_di_di_Intrinsic<"HEXAGON_S2_deinterleave">; +// +// BUILTIN_INFO(HEXAGON.dcfetch_A,v_ftype_DI*,1) +// +def int_hexagon_prefetch : +Hexagon_void_si_Intrinsic<"HEXAGON_prefetch">; def llvm_ptr32_ty : LLVMPointerType<llvm_i32_ty>; def llvm_ptr64_ty : LLVMPointerType<llvm_i64_ty>; @@ -4964,3 +4982,4392 @@ Hexagon_Intrinsic<"HEXAGON_S2_storew_locked", [llvm_i32_ty], def int_hexagon_S4_stored_locked : Hexagon_Intrinsic<"HEXAGON_S4_stored_locked", [llvm_i32_ty], [llvm_ptr64_ty, llvm_i64_ty], [IntrReadWriteArgMem, NoCapture<0>]>; + +// V60 + +class Hexagon_v2048v2048_Intrinsic_T<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty], + [IntrNoMem]>; + +// tag : V6_hi_W +// tag : V6_lo_W +class Hexagon_v512v1024_Intrinsic_T<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v32i32_ty], + [IntrNoMem]>; + +// tag : V6_hi_W_128B +// tag : V6_lo_W_128B +class Hexagon_v1024v2048_Intrinsic_T<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v64i32_ty], + [IntrNoMem]>; + +class Hexagon_v1024v1024_Intrinsic_T<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty], + [IntrNoMem]>; + +// BUILTIN_INFO(HEXAGON.V6_hi_W,VI_ftype_VI,1) +// tag : V6_hi +def int_hexagon_V6_hi : +Hexagon_v512v1024_Intrinsic_T<"HEXAGON_V6_hi">; + +// BUILTIN_INFO(HEXAGON.V6_lo_W,VI_ftype_VI,1) +// tag : V6_lo +def int_hexagon_V6_lo : +Hexagon_v512v1024_Intrinsic_T<"HEXAGON_V6_lo">; + +// BUILTIN_INFO(HEXAGON.V6_hi_W,VI_ftype_VI,1) +// tag : V6_hi_128B +def int_hexagon_V6_hi_128B : +Hexagon_v1024v2048_Intrinsic_T<"HEXAGON_V6_hi_128B">; + +// BUILTIN_INFO(HEXAGON.V6_lo_W,VI_ftype_VI,1) +// tag : V6_lo_128B +def int_hexagon_V6_lo_128B : +Hexagon_v1024v2048_Intrinsic_T<"HEXAGON_V6_lo_128B">; + +// BUILTIN_INFO(HEXAGON.V6_vassignp,VI_ftype_VI,1) +// tag : V6_vassignp +def int_hexagon_V6_vassignp : +Hexagon_v1024v1024_Intrinsic_T<"HEXAGON_V6_vassignp">; + +// BUILTIN_INFO(HEXAGON.V6_vassignp,VI_ftype_VI,1) +// tag : V6_vassignp_128B +def int_hexagon_V6_vassignp_128B : +Hexagon_v2048v2048_Intrinsic_T<"HEXAGON_V6_vassignp_128B">; + + + +// +// Hexagon_iii_Intrinsic<string GCCIntSuffix> +// tag : S6_rol_i_r +class Hexagon_iii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_LLiLLii_Intrinsic<string GCCIntSuffix> +// tag : S6_rol_i_p +class Hexagon_LLiLLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_iiii_Intrinsic<string GCCIntSuffix> +// tag : S6_rol_i_r_acc +class Hexagon_iiii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_LLiLLiLLii_Intrinsic<string GCCIntSuffix> +// tag : S6_rol_i_p_acc +class Hexagon_LLiLLiLLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_valignb +class Hexagon_v512v512v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_valignb_128B +class Hexagon_v1024v1024v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vror +class Hexagon_v512v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vror_128B +class Hexagon_v1024v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vunpackub +class Hexagon_v1024v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vunpackub_128B +class Hexagon_v2048v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vunpackob +class Hexagon_v1024v1024v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vunpackob_128B +class Hexagon_v2048v2048v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vpackeb +class Hexagon_v512v512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vpackeb_128B +class Hexagon_v1024v1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048i_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpybus_dv_128B +class Hexagon_v2048v2048i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v2048i_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpybus_dv_acc_128B +class Hexagon_v2048v2048v2048i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpyhvsat_acc +class Hexagon_v512v512v512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpyhvsat_acc_128B +class Hexagon_v1024v1024v1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpyhisat +class Hexagon_v512v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v2048i_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpyhisat_128B +class Hexagon_v1024v2048i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v64i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpyhisat_acc +class Hexagon_v512v512v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v2048i_Intrinsic<string GCCIntSuffix> +// tag : V6_vdmpyhisat_acc_128B +class Hexagon_v1024v1024v2048i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v64i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vrmpyubi +class Hexagon_v1024v1024ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vrmpyubi_128B +class Hexagon_v2048v2048ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v1024ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vrmpyubi_acc +class Hexagon_v1024v1024v1024ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v2048ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vrmpyubi_acc_128B +class Hexagon_v2048v2048v2048ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v2048_Intrinsic<string GCCIntSuffix> +// tag : V6_vaddb_dv_128B +class Hexagon_v2048v2048v2048_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vaddubh +class Hexagon_v1024v512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vaddubh_128B +class Hexagon_v2048v1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vd0 +class Hexagon_v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [], + [IntrNoMem]>; + +// +// Hexagon_v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vd0_128B +class Hexagon_v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [], + [IntrNoMem]>; + +// +// Hexagon_v512v64iv512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vaddbq +class Hexagon_v512v64iv512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v128iv1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vaddbq_128B +class Hexagon_v1024v128iv1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vabsh +class Hexagon_v512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vabsh_128B +class Hexagon_v1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vmpybv_acc +class Hexagon_v1024v1024v512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vmpybv_acc_128B +class Hexagon_v2048v2048v1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vmpyub +class Hexagon_v1024v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vmpyub_128B +class Hexagon_v2048v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vmpyub_acc +class Hexagon_v1024v1024v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vmpyub_acc_128B +class Hexagon_v2048v2048v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v64ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vandqrt +class Hexagon_v512v64ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v128ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vandqrt_128B +class Hexagon_v1024v128ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v64ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vandqrt_acc +class Hexagon_v512v512v64ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v512i1_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v128ii_Intrinsic<string GCCIntSuffix> +// tag : V6_vandqrt_acc_128B +class Hexagon_v1024v1024v128ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v1024i1_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v64iv512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vandvrt +class Hexagon_v64iv512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v128iv1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vandvrt_128B +class Hexagon_v128iv1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v64iv64iv512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vandvrt_acc +class Hexagon_v64iv64iv512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v128iv128iv1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vandvrt_acc_128B +class Hexagon_v128iv128iv1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v64iv512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vgtw +class Hexagon_v64iv512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v128iv1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vgtw_128B +class Hexagon_v128iv1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v64iv64iv512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vgtw_and +class Hexagon_v64iv64iv512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v128iv128iv1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vgtw_and_128B +class Hexagon_v128iv128iv1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v64iv64iv64i_Intrinsic<string GCCIntSuffix> +// tag : V6_pred_or +class Hexagon_v64iv64iv64i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v512i1_ty], + [IntrNoMem]>; + +// +// Hexagon_v128iv128iv128i_Intrinsic<string GCCIntSuffix> +// tag : V6_pred_or_128B +class Hexagon_v128iv128iv128i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v1024i1_ty], + [IntrNoMem]>; + +// +// Hexagon_v64iv64i_Intrinsic<string GCCIntSuffix> +// tag : V6_pred_not +class Hexagon_v64iv64i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_v512i1_ty], + [IntrNoMem]>; + +// +// Hexagon_v128iv128i_Intrinsic<string GCCIntSuffix> +// tag : V6_pred_not_128B +class Hexagon_v128iv128i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_v1024i1_ty], + [IntrNoMem]>; + +// +// Hexagon_v64ii_Intrinsic<string GCCIntSuffix> +// tag : V6_pred_scalar2 +class Hexagon_v64ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v512i1_ty], [llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v128ii_Intrinsic<string GCCIntSuffix> +// tag : V6_pred_scalar2_128B +class Hexagon_v128ii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v1024i1_ty], [llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v64iv512v512_Intrinsic<string GCCIntSuffix> +// tag : V6_vswap +class Hexagon_v1024v64iv512v512_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_v16i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v128iv1024v1024_Intrinsic<string GCCIntSuffix> +// tag : V6_vswap_128B +class Hexagon_v2048v128iv1024v1024_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_v32i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v512v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vshuffvdd +class Hexagon_v1024v512v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v1024v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vshuffvdd_128B +class Hexagon_v2048v1024v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + + +// +// Hexagon_iv512i_Intrinsic<string GCCIntSuffix> +// tag : V6_extractw +class Hexagon_iv512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i32_ty], [llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_iv1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_extractw_128B +class Hexagon_iv1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i32_ty], [llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_lvsplatw +class Hexagon_v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_lvsplatw_128B +class Hexagon_v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512LLii_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutb +class Hexagon_v512v512LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024LLii_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutb_128B +class Hexagon_v1024v1024LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v512LLii_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutb_acc +class Hexagon_v512v512v512LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v1024LLii_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutb_acc_128B +class Hexagon_v1024v1024v1024LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048LLii_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutb_dv_128B +class Hexagon_v2048v2048LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v2048LLii_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutb_dv_acc_128B +class Hexagon_v2048v2048v2048LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i64_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v512v512v512v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutvvb_oracc +class Hexagon_v512v512v512v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v1024v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutvvb_oracc_128B +class Hexagon_v1024v1024v1024v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v1024v1024v512v512i_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutvwh_oracc +class Hexagon_v1024v1024v512v512i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_v2048v2048v1024v1024i_Intrinsic<string GCCIntSuffix> +// tag : V6_vlutvwh_oracc_128B +class Hexagon_v2048v2048v1024v1024i_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], + [IntrNoMem]>; + +// +// Hexagon_LLiLLiLLi_Intrinsic<string GCCIntSuffix> +// tag : M6_vabsdiffb +class Hexagon_LLiLLiLLi_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty], + [IntrNoMem]>; + +// +// Hexagon_LLii_Intrinsic<string GCCIntSuffix> +// tag : S6_vsplatrbp +class Hexagon_LLii_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_i64_ty], [llvm_i32_ty], + [IntrNoMem]>; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_r,SI_ftype_SISI,2) +// tag : S6_rol_i_r +def int_hexagon_S6_rol_i_r : +Hexagon_iii_Intrinsic<"HEXAGON_S6_rol_i_r">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_p,DI_ftype_DISI,2) +// tag : S6_rol_i_p +def int_hexagon_S6_rol_i_p : +Hexagon_LLiLLii_Intrinsic<"HEXAGON_S6_rol_i_p">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_r_acc,SI_ftype_SISISI,3) +// tag : S6_rol_i_r_acc +def int_hexagon_S6_rol_i_r_acc : +Hexagon_iiii_Intrinsic<"HEXAGON_S6_rol_i_r_acc">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_p_acc,DI_ftype_DIDISI,3) +// tag : S6_rol_i_p_acc +def int_hexagon_S6_rol_i_p_acc : +Hexagon_LLiLLiLLii_Intrinsic<"HEXAGON_S6_rol_i_p_acc">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_r_nac,SI_ftype_SISISI,3) +// tag : S6_rol_i_r_nac +def int_hexagon_S6_rol_i_r_nac : +Hexagon_iiii_Intrinsic<"HEXAGON_S6_rol_i_r_nac">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_p_nac,DI_ftype_DIDISI,3) +// tag : S6_rol_i_p_nac +def int_hexagon_S6_rol_i_p_nac : +Hexagon_LLiLLiLLii_Intrinsic<"HEXAGON_S6_rol_i_p_nac">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_r_xacc,SI_ftype_SISISI,3) +// tag : S6_rol_i_r_xacc +def int_hexagon_S6_rol_i_r_xacc : +Hexagon_iiii_Intrinsic<"HEXAGON_S6_rol_i_r_xacc">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_p_xacc,DI_ftype_DIDISI,3) +// tag : S6_rol_i_p_xacc +def int_hexagon_S6_rol_i_p_xacc : +Hexagon_LLiLLiLLii_Intrinsic<"HEXAGON_S6_rol_i_p_xacc">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_r_and,SI_ftype_SISISI,3) +// tag : S6_rol_i_r_and +def int_hexagon_S6_rol_i_r_and : +Hexagon_iiii_Intrinsic<"HEXAGON_S6_rol_i_r_and">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_r_or,SI_ftype_SISISI,3) +// tag : S6_rol_i_r_or +def int_hexagon_S6_rol_i_r_or : +Hexagon_iiii_Intrinsic<"HEXAGON_S6_rol_i_r_or">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_p_and,DI_ftype_DIDISI,3) +// tag : S6_rol_i_p_and +def int_hexagon_S6_rol_i_p_and : +Hexagon_LLiLLiLLii_Intrinsic<"HEXAGON_S6_rol_i_p_and">; + +// +// BUILTIN_INFO(HEXAGON.S6_rol_i_p_or,DI_ftype_DIDISI,3) +// tag : S6_rol_i_p_or +def int_hexagon_S6_rol_i_p_or : +Hexagon_LLiLLiLLii_Intrinsic<"HEXAGON_S6_rol_i_p_or">; + +// +// BUILTIN_INFO(HEXAGON.S2_cabacencbin,DI_ftype_DIDIQI,3) +// tag : S2_cabacencbin +def int_hexagon_S2_cabacencbin : +Hexagon_LLiLLiLLii_Intrinsic<"HEXAGON_S2_cabacencbin">; + +// +// BUILTIN_INFO(HEXAGON.V6_valignb,VI_ftype_VIVISI,3) +// tag : V6_valignb +def int_hexagon_V6_valignb : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_valignb">; + +// +// BUILTIN_INFO(HEXAGON.V6_valignb_128B,VI_ftype_VIVISI,3) +// tag : V6_valignb_128B +def int_hexagon_V6_valignb_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_valignb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlalignb,VI_ftype_VIVISI,3) +// tag : V6_vlalignb +def int_hexagon_V6_vlalignb : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vlalignb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlalignb_128B,VI_ftype_VIVISI,3) +// tag : V6_vlalignb_128B +def int_hexagon_V6_vlalignb_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlalignb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_valignbi,VI_ftype_VIVISI,3) +// tag : V6_valignbi +def int_hexagon_V6_valignbi : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_valignbi">; + +// +// BUILTIN_INFO(HEXAGON.V6_valignbi_128B,VI_ftype_VIVISI,3) +// tag : V6_valignbi_128B +def int_hexagon_V6_valignbi_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_valignbi_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlalignbi,VI_ftype_VIVISI,3) +// tag : V6_vlalignbi +def int_hexagon_V6_vlalignbi : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vlalignbi">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlalignbi_128B,VI_ftype_VIVISI,3) +// tag : V6_vlalignbi_128B +def int_hexagon_V6_vlalignbi_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlalignbi_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vror,VI_ftype_VISI,2) +// tag : V6_vror +def int_hexagon_V6_vror : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vror">; + +// +// BUILTIN_INFO(HEXAGON.V6_vror_128B,VI_ftype_VISI,2) +// tag : V6_vror_128B +def int_hexagon_V6_vror_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vror_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackub,VD_ftype_VI,1) +// tag : V6_vunpackub +def int_hexagon_V6_vunpackub : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vunpackub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackub_128B,VD_ftype_VI,1) +// tag : V6_vunpackub_128B +def int_hexagon_V6_vunpackub_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vunpackub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackb,VD_ftype_VI,1) +// tag : V6_vunpackb +def int_hexagon_V6_vunpackb : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vunpackb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackb_128B,VD_ftype_VI,1) +// tag : V6_vunpackb_128B +def int_hexagon_V6_vunpackb_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vunpackb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackuh,VD_ftype_VI,1) +// tag : V6_vunpackuh +def int_hexagon_V6_vunpackuh : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vunpackuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackuh_128B,VD_ftype_VI,1) +// tag : V6_vunpackuh_128B +def int_hexagon_V6_vunpackuh_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vunpackuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackh,VD_ftype_VI,1) +// tag : V6_vunpackh +def int_hexagon_V6_vunpackh : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vunpackh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackh_128B,VD_ftype_VI,1) +// tag : V6_vunpackh_128B +def int_hexagon_V6_vunpackh_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vunpackh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackob,VD_ftype_VDVI,2) +// tag : V6_vunpackob +def int_hexagon_V6_vunpackob : +Hexagon_v1024v1024v512_Intrinsic<"HEXAGON_V6_vunpackob">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackob_128B,VD_ftype_VDVI,2) +// tag : V6_vunpackob_128B +def int_hexagon_V6_vunpackob_128B : +Hexagon_v2048v2048v1024_Intrinsic<"HEXAGON_V6_vunpackob_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackoh,VD_ftype_VDVI,2) +// tag : V6_vunpackoh +def int_hexagon_V6_vunpackoh : +Hexagon_v1024v1024v512_Intrinsic<"HEXAGON_V6_vunpackoh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vunpackoh_128B,VD_ftype_VDVI,2) +// tag : V6_vunpackoh_128B +def int_hexagon_V6_vunpackoh_128B : +Hexagon_v2048v2048v1024_Intrinsic<"HEXAGON_V6_vunpackoh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackeb,VI_ftype_VIVI,2) +// tag : V6_vpackeb +def int_hexagon_V6_vpackeb : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackeb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackeb_128B,VI_ftype_VIVI,2) +// tag : V6_vpackeb_128B +def int_hexagon_V6_vpackeb_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackeb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackeh,VI_ftype_VIVI,2) +// tag : V6_vpackeh +def int_hexagon_V6_vpackeh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackeh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackeh_128B,VI_ftype_VIVI,2) +// tag : V6_vpackeh_128B +def int_hexagon_V6_vpackeh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackeh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackob,VI_ftype_VIVI,2) +// tag : V6_vpackob +def int_hexagon_V6_vpackob : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackob">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackob_128B,VI_ftype_VIVI,2) +// tag : V6_vpackob_128B +def int_hexagon_V6_vpackob_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackob_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackoh,VI_ftype_VIVI,2) +// tag : V6_vpackoh +def int_hexagon_V6_vpackoh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackoh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackoh_128B,VI_ftype_VIVI,2) +// tag : V6_vpackoh_128B +def int_hexagon_V6_vpackoh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackoh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackhub_sat,VI_ftype_VIVI,2) +// tag : V6_vpackhub_sat +def int_hexagon_V6_vpackhub_sat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackhub_sat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackhub_sat_128B,VI_ftype_VIVI,2) +// tag : V6_vpackhub_sat_128B +def int_hexagon_V6_vpackhub_sat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackhub_sat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackhb_sat,VI_ftype_VIVI,2) +// tag : V6_vpackhb_sat +def int_hexagon_V6_vpackhb_sat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackhb_sat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackhb_sat_128B,VI_ftype_VIVI,2) +// tag : V6_vpackhb_sat_128B +def int_hexagon_V6_vpackhb_sat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackhb_sat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackwuh_sat,VI_ftype_VIVI,2) +// tag : V6_vpackwuh_sat +def int_hexagon_V6_vpackwuh_sat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackwuh_sat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackwuh_sat_128B,VI_ftype_VIVI,2) +// tag : V6_vpackwuh_sat_128B +def int_hexagon_V6_vpackwuh_sat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackwuh_sat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackwh_sat,VI_ftype_VIVI,2) +// tag : V6_vpackwh_sat +def int_hexagon_V6_vpackwh_sat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vpackwh_sat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpackwh_sat_128B,VI_ftype_VIVI,2) +// tag : V6_vpackwh_sat_128B +def int_hexagon_V6_vpackwh_sat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vpackwh_sat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vzb,VD_ftype_VI,1) +// tag : V6_vzb +def int_hexagon_V6_vzb : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vzb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vzb_128B,VD_ftype_VI,1) +// tag : V6_vzb_128B +def int_hexagon_V6_vzb_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vzb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsb,VD_ftype_VI,1) +// tag : V6_vsb +def int_hexagon_V6_vsb : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vsb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsb_128B,VD_ftype_VI,1) +// tag : V6_vsb_128B +def int_hexagon_V6_vsb_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vsb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vzh,VD_ftype_VI,1) +// tag : V6_vzh +def int_hexagon_V6_vzh : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vzh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vzh_128B,VD_ftype_VI,1) +// tag : V6_vzh_128B +def int_hexagon_V6_vzh_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vzh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsh,VD_ftype_VI,1) +// tag : V6_vsh +def int_hexagon_V6_vsh : +Hexagon_v1024v512_Intrinsic<"HEXAGON_V6_vsh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsh_128B,VD_ftype_VI,1) +// tag : V6_vsh_128B +def int_hexagon_V6_vsh_128B : +Hexagon_v2048v1024_Intrinsic<"HEXAGON_V6_vsh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus,VI_ftype_VISI,2) +// tag : V6_vdmpybus +def int_hexagon_V6_vdmpybus : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vdmpybus">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_128B,VI_ftype_VISI,2) +// tag : V6_vdmpybus_128B +def int_hexagon_V6_vdmpybus_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpybus_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_acc,VI_ftype_VIVISI,3) +// tag : V6_vdmpybus_acc +def int_hexagon_V6_vdmpybus_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vdmpybus_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vdmpybus_acc_128B +def int_hexagon_V6_vdmpybus_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpybus_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_dv,VD_ftype_VDSI,2) +// tag : V6_vdmpybus_dv +def int_hexagon_V6_vdmpybus_dv : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpybus_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_dv_128B,VD_ftype_VDSI,2) +// tag : V6_vdmpybus_dv_128B +def int_hexagon_V6_vdmpybus_dv_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vdmpybus_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_dv_acc,VD_ftype_VDVDSI,3) +// tag : V6_vdmpybus_dv_acc +def int_hexagon_V6_vdmpybus_dv_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpybus_dv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpybus_dv_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vdmpybus_dv_acc_128B +def int_hexagon_V6_vdmpybus_dv_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vdmpybus_dv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb,VI_ftype_VISI,2) +// tag : V6_vdmpyhb +def int_hexagon_V6_vdmpyhb : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vdmpyhb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_128B,VI_ftype_VISI,2) +// tag : V6_vdmpyhb_128B +def int_hexagon_V6_vdmpyhb_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_acc,VI_ftype_VIVISI,3) +// tag : V6_vdmpyhb_acc +def int_hexagon_V6_vdmpyhb_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vdmpyhb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vdmpyhb_acc_128B +def int_hexagon_V6_vdmpyhb_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_dv,VD_ftype_VDSI,2) +// tag : V6_vdmpyhb_dv +def int_hexagon_V6_vdmpyhb_dv : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhb_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_dv_128B,VD_ftype_VDSI,2) +// tag : V6_vdmpyhb_dv_128B +def int_hexagon_V6_vdmpyhb_dv_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_dv_acc,VD_ftype_VDVDSI,3) +// tag : V6_vdmpyhb_dv_acc +def int_hexagon_V6_vdmpyhb_dv_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhb_dv_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vdmpyhb_dv_acc_128B +def int_hexagon_V6_vdmpyhb_dv_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhvsat,VI_ftype_VIVI,2) +// tag : V6_vdmpyhvsat +def int_hexagon_V6_vdmpyhvsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vdmpyhvsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhvsat_128B,VI_ftype_VIVI,2) +// tag : V6_vdmpyhvsat_128B +def int_hexagon_V6_vdmpyhvsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vdmpyhvsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhvsat_acc,VI_ftype_VIVIVI,3) +// tag : V6_vdmpyhvsat_acc +def int_hexagon_V6_vdmpyhvsat_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vdmpyhvsat_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhvsat_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vdmpyhvsat_acc_128B +def int_hexagon_V6_vdmpyhvsat_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vdmpyhvsat_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsat,VI_ftype_VISI,2) +// tag : V6_vdmpyhsat +def int_hexagon_V6_vdmpyhsat : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vdmpyhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsat_128B,VI_ftype_VISI,2) +// tag : V6_vdmpyhsat_128B +def int_hexagon_V6_vdmpyhsat_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsat_acc,VI_ftype_VIVISI,3) +// tag : V6_vdmpyhsat_acc +def int_hexagon_V6_vdmpyhsat_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vdmpyhsat_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsat_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vdmpyhsat_acc_128B +def int_hexagon_V6_vdmpyhsat_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhsat_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhisat,VI_ftype_VDSI,2) +// tag : V6_vdmpyhisat +def int_hexagon_V6_vdmpyhisat : +Hexagon_v512v1024i_Intrinsic<"HEXAGON_V6_vdmpyhisat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhisat_128B,VI_ftype_VDSI,2) +// tag : V6_vdmpyhisat_128B +def int_hexagon_V6_vdmpyhisat_128B : +Hexagon_v1024v2048i_Intrinsic<"HEXAGON_V6_vdmpyhisat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhisat_acc,VI_ftype_VIVDSI,3) +// tag : V6_vdmpyhisat_acc +def int_hexagon_V6_vdmpyhisat_acc : +Hexagon_v512v512v1024i_Intrinsic<"HEXAGON_V6_vdmpyhisat_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhisat_acc_128B,VI_ftype_VIVDSI,3) +// tag : V6_vdmpyhisat_acc_128B +def int_hexagon_V6_vdmpyhisat_acc_128B : +Hexagon_v1024v1024v2048i_Intrinsic<"HEXAGON_V6_vdmpyhisat_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsusat,VI_ftype_VISI,2) +// tag : V6_vdmpyhsusat +def int_hexagon_V6_vdmpyhsusat : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vdmpyhsusat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsusat_128B,VI_ftype_VISI,2) +// tag : V6_vdmpyhsusat_128B +def int_hexagon_V6_vdmpyhsusat_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhsusat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsusat_acc,VI_ftype_VIVISI,3) +// tag : V6_vdmpyhsusat_acc +def int_hexagon_V6_vdmpyhsusat_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vdmpyhsusat_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsusat_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vdmpyhsusat_acc_128B +def int_hexagon_V6_vdmpyhsusat_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdmpyhsusat_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsuisat,VI_ftype_VDSI,2) +// tag : V6_vdmpyhsuisat +def int_hexagon_V6_vdmpyhsuisat : +Hexagon_v512v1024i_Intrinsic<"HEXAGON_V6_vdmpyhsuisat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsuisat_128B,VI_ftype_VDSI,2) +// tag : V6_vdmpyhsuisat_128B +def int_hexagon_V6_vdmpyhsuisat_128B : +Hexagon_v1024v2048i_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsuisat_acc,VI_ftype_VIVDSI,3) +// tag : V6_vdmpyhsuisat_acc +def int_hexagon_V6_vdmpyhsuisat_acc : +Hexagon_v512v512v1024i_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdmpyhsuisat_acc_128B,VI_ftype_VIVDSI,3) +// tag : V6_vdmpyhsuisat_acc_128B +def int_hexagon_V6_vdmpyhsuisat_acc_128B : +Hexagon_v1024v1024v2048i_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyb,VD_ftype_VDSI,2) +// tag : V6_vtmpyb +def int_hexagon_V6_vtmpyb : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vtmpyb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyb_128B,VD_ftype_VDSI,2) +// tag : V6_vtmpyb_128B +def int_hexagon_V6_vtmpyb_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vtmpyb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyb_acc,VD_ftype_VDVDSI,3) +// tag : V6_vtmpyb_acc +def int_hexagon_V6_vtmpyb_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vtmpyb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyb_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vtmpyb_acc_128B +def int_hexagon_V6_vtmpyb_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vtmpyb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpybus,VD_ftype_VDSI,2) +// tag : V6_vtmpybus +def int_hexagon_V6_vtmpybus : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vtmpybus">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpybus_128B,VD_ftype_VDSI,2) +// tag : V6_vtmpybus_128B +def int_hexagon_V6_vtmpybus_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vtmpybus_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpybus_acc,VD_ftype_VDVDSI,3) +// tag : V6_vtmpybus_acc +def int_hexagon_V6_vtmpybus_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vtmpybus_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpybus_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vtmpybus_acc_128B +def int_hexagon_V6_vtmpybus_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vtmpybus_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyhb,VD_ftype_VDSI,2) +// tag : V6_vtmpyhb +def int_hexagon_V6_vtmpyhb : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vtmpyhb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyhb_128B,VD_ftype_VDSI,2) +// tag : V6_vtmpyhb_128B +def int_hexagon_V6_vtmpyhb_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vtmpyhb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyhb_acc,VD_ftype_VDVDSI,3) +// tag : V6_vtmpyhb_acc +def int_hexagon_V6_vtmpyhb_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vtmpyhb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vtmpyhb_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vtmpyhb_acc_128B +def int_hexagon_V6_vtmpyhb_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vtmpyhb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyub,VI_ftype_VISI,2) +// tag : V6_vrmpyub +def int_hexagon_V6_vrmpyub : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vrmpyub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyub_128B,VI_ftype_VISI,2) +// tag : V6_vrmpyub_128B +def int_hexagon_V6_vrmpyub_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vrmpyub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyub_acc,VI_ftype_VIVISI,3) +// tag : V6_vrmpyub_acc +def int_hexagon_V6_vrmpyub_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vrmpyub_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyub_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vrmpyub_acc_128B +def int_hexagon_V6_vrmpyub_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vrmpyub_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubv,VI_ftype_VIVI,2) +// tag : V6_vrmpyubv +def int_hexagon_V6_vrmpyubv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vrmpyubv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubv_128B,VI_ftype_VIVI,2) +// tag : V6_vrmpyubv_128B +def int_hexagon_V6_vrmpyubv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrmpyubv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubv_acc,VI_ftype_VIVIVI,3) +// tag : V6_vrmpyubv_acc +def int_hexagon_V6_vrmpyubv_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vrmpyubv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubv_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vrmpyubv_acc_128B +def int_hexagon_V6_vrmpyubv_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrmpyubv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybv,VI_ftype_VIVI,2) +// tag : V6_vrmpybv +def int_hexagon_V6_vrmpybv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vrmpybv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybv_128B,VI_ftype_VIVI,2) +// tag : V6_vrmpybv_128B +def int_hexagon_V6_vrmpybv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrmpybv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybv_acc,VI_ftype_VIVIVI,3) +// tag : V6_vrmpybv_acc +def int_hexagon_V6_vrmpybv_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vrmpybv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybv_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vrmpybv_acc_128B +def int_hexagon_V6_vrmpybv_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrmpybv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubi,VD_ftype_VDSISI,3) +// tag : V6_vrmpyubi +def int_hexagon_V6_vrmpyubi : +Hexagon_v1024v1024ii_Intrinsic<"HEXAGON_V6_vrmpyubi">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubi_128B,VD_ftype_VDSISI,3) +// tag : V6_vrmpyubi_128B +def int_hexagon_V6_vrmpyubi_128B : +Hexagon_v2048v2048ii_Intrinsic<"HEXAGON_V6_vrmpyubi_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubi_acc,VD_ftype_VDVDSISI,4) +// tag : V6_vrmpyubi_acc +def int_hexagon_V6_vrmpyubi_acc : +Hexagon_v1024v1024v1024ii_Intrinsic<"HEXAGON_V6_vrmpyubi_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpyubi_acc_128B,VD_ftype_VDVDSISI,4) +// tag : V6_vrmpyubi_acc_128B +def int_hexagon_V6_vrmpyubi_acc_128B : +Hexagon_v2048v2048v2048ii_Intrinsic<"HEXAGON_V6_vrmpyubi_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybus,VI_ftype_VISI,2) +// tag : V6_vrmpybus +def int_hexagon_V6_vrmpybus : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vrmpybus">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybus_128B,VI_ftype_VISI,2) +// tag : V6_vrmpybus_128B +def int_hexagon_V6_vrmpybus_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vrmpybus_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybus_acc,VI_ftype_VIVISI,3) +// tag : V6_vrmpybus_acc +def int_hexagon_V6_vrmpybus_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vrmpybus_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybus_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vrmpybus_acc_128B +def int_hexagon_V6_vrmpybus_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vrmpybus_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusi,VD_ftype_VDSISI,3) +// tag : V6_vrmpybusi +def int_hexagon_V6_vrmpybusi : +Hexagon_v1024v1024ii_Intrinsic<"HEXAGON_V6_vrmpybusi">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusi_128B,VD_ftype_VDSISI,3) +// tag : V6_vrmpybusi_128B +def int_hexagon_V6_vrmpybusi_128B : +Hexagon_v2048v2048ii_Intrinsic<"HEXAGON_V6_vrmpybusi_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusi_acc,VD_ftype_VDVDSISI,4) +// tag : V6_vrmpybusi_acc +def int_hexagon_V6_vrmpybusi_acc : +Hexagon_v1024v1024v1024ii_Intrinsic<"HEXAGON_V6_vrmpybusi_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusi_acc_128B,VD_ftype_VDVDSISI,4) +// tag : V6_vrmpybusi_acc_128B +def int_hexagon_V6_vrmpybusi_acc_128B : +Hexagon_v2048v2048v2048ii_Intrinsic<"HEXAGON_V6_vrmpybusi_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusv,VI_ftype_VIVI,2) +// tag : V6_vrmpybusv +def int_hexagon_V6_vrmpybusv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vrmpybusv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusv_128B,VI_ftype_VIVI,2) +// tag : V6_vrmpybusv_128B +def int_hexagon_V6_vrmpybusv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrmpybusv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusv_acc,VI_ftype_VIVIVI,3) +// tag : V6_vrmpybusv_acc +def int_hexagon_V6_vrmpybusv_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vrmpybusv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrmpybusv_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vrmpybusv_acc_128B +def int_hexagon_V6_vrmpybusv_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrmpybusv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdsaduh,VD_ftype_VDSI,2) +// tag : V6_vdsaduh +def int_hexagon_V6_vdsaduh : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vdsaduh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdsaduh_128B,VD_ftype_VDSI,2) +// tag : V6_vdsaduh_128B +def int_hexagon_V6_vdsaduh_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vdsaduh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdsaduh_acc,VD_ftype_VDVDSI,3) +// tag : V6_vdsaduh_acc +def int_hexagon_V6_vdsaduh_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vdsaduh_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdsaduh_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vdsaduh_acc_128B +def int_hexagon_V6_vdsaduh_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vdsaduh_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrsadubi,VD_ftype_VDSISI,3) +// tag : V6_vrsadubi +def int_hexagon_V6_vrsadubi : +Hexagon_v1024v1024ii_Intrinsic<"HEXAGON_V6_vrsadubi">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrsadubi_128B,VD_ftype_VDSISI,3) +// tag : V6_vrsadubi_128B +def int_hexagon_V6_vrsadubi_128B : +Hexagon_v2048v2048ii_Intrinsic<"HEXAGON_V6_vrsadubi_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrsadubi_acc,VD_ftype_VDVDSISI,4) +// tag : V6_vrsadubi_acc +def int_hexagon_V6_vrsadubi_acc : +Hexagon_v1024v1024v1024ii_Intrinsic<"HEXAGON_V6_vrsadubi_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrsadubi_acc_128B,VD_ftype_VDVDSISI,4) +// tag : V6_vrsadubi_acc_128B +def int_hexagon_V6_vrsadubi_acc_128B : +Hexagon_v2048v2048v2048ii_Intrinsic<"HEXAGON_V6_vrsadubi_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrw,VI_ftype_VISI,2) +// tag : V6_vasrw +def int_hexagon_V6_vasrw : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vasrw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrw_128B,VI_ftype_VISI,2) +// tag : V6_vasrw_128B +def int_hexagon_V6_vasrw_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vasrw_128B">; + + +// +// BUILTIN_INFO(HEXAGON.V6_vaslw,VI_ftype_VISI,2) +// tag : V6_vaslw +def int_hexagon_V6_vaslw : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vaslw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslw_128B,VI_ftype_VISI,2) +// tag : V6_vaslw_128B +def int_hexagon_V6_vaslw_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vaslw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrw,VI_ftype_VISI,2) +// tag : V6_vlsrw +def int_hexagon_V6_vlsrw : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vlsrw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrw_128B,VI_ftype_VISI,2) +// tag : V6_vlsrw_128B +def int_hexagon_V6_vlsrw_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vlsrw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwv,VI_ftype_VIVI,2) +// tag : V6_vasrwv +def int_hexagon_V6_vasrwv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vasrwv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwv_128B,VI_ftype_VIVI,2) +// tag : V6_vasrwv_128B +def int_hexagon_V6_vasrwv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vasrwv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslwv,VI_ftype_VIVI,2) +// tag : V6_vaslwv +def int_hexagon_V6_vaslwv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaslwv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslwv_128B,VI_ftype_VIVI,2) +// tag : V6_vaslwv_128B +def int_hexagon_V6_vaslwv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaslwv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrwv,VI_ftype_VIVI,2) +// tag : V6_vlsrwv +def int_hexagon_V6_vlsrwv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vlsrwv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrwv_128B,VI_ftype_VIVI,2) +// tag : V6_vlsrwv_128B +def int_hexagon_V6_vlsrwv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vlsrwv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrh,VI_ftype_VISI,2) +// tag : V6_vasrh +def int_hexagon_V6_vasrh : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vasrh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrh_128B,VI_ftype_VISI,2) +// tag : V6_vasrh_128B +def int_hexagon_V6_vasrh_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vasrh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslh,VI_ftype_VISI,2) +// tag : V6_vaslh +def int_hexagon_V6_vaslh : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vaslh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslh_128B,VI_ftype_VISI,2) +// tag : V6_vaslh_128B +def int_hexagon_V6_vaslh_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vaslh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrh,VI_ftype_VISI,2) +// tag : V6_vlsrh +def int_hexagon_V6_vlsrh : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vlsrh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrh_128B,VI_ftype_VISI,2) +// tag : V6_vlsrh_128B +def int_hexagon_V6_vlsrh_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vlsrh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhv,VI_ftype_VIVI,2) +// tag : V6_vasrhv +def int_hexagon_V6_vasrhv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vasrhv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhv_128B,VI_ftype_VIVI,2) +// tag : V6_vasrhv_128B +def int_hexagon_V6_vasrhv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vasrhv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslhv,VI_ftype_VIVI,2) +// tag : V6_vaslhv +def int_hexagon_V6_vaslhv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaslhv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslhv_128B,VI_ftype_VIVI,2) +// tag : V6_vaslhv_128B +def int_hexagon_V6_vaslhv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaslhv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrhv,VI_ftype_VIVI,2) +// tag : V6_vlsrhv +def int_hexagon_V6_vlsrhv : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vlsrhv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlsrhv_128B,VI_ftype_VIVI,2) +// tag : V6_vlsrhv_128B +def int_hexagon_V6_vlsrhv_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vlsrhv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwh,VI_ftype_VIVISI,3) +// tag : V6_vasrwh +def int_hexagon_V6_vasrwh : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrwh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwh_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrwh_128B +def int_hexagon_V6_vasrwh_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrwh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwhsat,VI_ftype_VIVISI,3) +// tag : V6_vasrwhsat +def int_hexagon_V6_vasrwhsat : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrwhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwhsat_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrwhsat_128B +def int_hexagon_V6_vasrwhsat_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrwhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwhrndsat,VI_ftype_VIVISI,3) +// tag : V6_vasrwhrndsat +def int_hexagon_V6_vasrwhrndsat : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrwhrndsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwhrndsat_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrwhrndsat_128B +def int_hexagon_V6_vasrwhrndsat_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrwhrndsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwuhsat,VI_ftype_VIVISI,3) +// tag : V6_vasrwuhsat +def int_hexagon_V6_vasrwuhsat : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrwuhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrwuhsat_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrwuhsat_128B +def int_hexagon_V6_vasrwuhsat_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrwuhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundwh,VI_ftype_VIVI,2) +// tag : V6_vroundwh +def int_hexagon_V6_vroundwh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vroundwh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundwh_128B,VI_ftype_VIVI,2) +// tag : V6_vroundwh_128B +def int_hexagon_V6_vroundwh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vroundwh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundwuh,VI_ftype_VIVI,2) +// tag : V6_vroundwuh +def int_hexagon_V6_vroundwuh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vroundwuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundwuh_128B,VI_ftype_VIVI,2) +// tag : V6_vroundwuh_128B +def int_hexagon_V6_vroundwuh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vroundwuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhubsat,VI_ftype_VIVISI,3) +// tag : V6_vasrhubsat +def int_hexagon_V6_vasrhubsat : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrhubsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhubsat_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrhubsat_128B +def int_hexagon_V6_vasrhubsat_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrhubsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhubrndsat,VI_ftype_VIVISI,3) +// tag : V6_vasrhubrndsat +def int_hexagon_V6_vasrhubrndsat : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrhubrndsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhubrndsat_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrhubrndsat_128B +def int_hexagon_V6_vasrhubrndsat_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrhubrndsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhbrndsat,VI_ftype_VIVISI,3) +// tag : V6_vasrhbrndsat +def int_hexagon_V6_vasrhbrndsat : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrhbrndsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrhbrndsat_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrhbrndsat_128B +def int_hexagon_V6_vasrhbrndsat_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrhbrndsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundhb,VI_ftype_VIVI,2) +// tag : V6_vroundhb +def int_hexagon_V6_vroundhb : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vroundhb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundhb_128B,VI_ftype_VIVI,2) +// tag : V6_vroundhb_128B +def int_hexagon_V6_vroundhb_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vroundhb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundhub,VI_ftype_VIVI,2) +// tag : V6_vroundhub +def int_hexagon_V6_vroundhub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vroundhub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vroundhub_128B,VI_ftype_VIVI,2) +// tag : V6_vroundhub_128B +def int_hexagon_V6_vroundhub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vroundhub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslw_acc,VI_ftype_VIVISI,3) +// tag : V6_vaslw_acc +def int_hexagon_V6_vaslw_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vaslw_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaslw_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vaslw_acc_128B +def int_hexagon_V6_vaslw_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vaslw_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrw_acc,VI_ftype_VIVISI,3) +// tag : V6_vasrw_acc +def int_hexagon_V6_vasrw_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vasrw_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vasrw_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vasrw_acc_128B +def int_hexagon_V6_vasrw_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vasrw_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddb,VI_ftype_VIVI,2) +// tag : V6_vaddb +def int_hexagon_V6_vaddb : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaddb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddb_128B,VI_ftype_VIVI,2) +// tag : V6_vaddb_128B +def int_hexagon_V6_vaddb_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubb,VI_ftype_VIVI,2) +// tag : V6_vsubb +def int_hexagon_V6_vsubb : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsubb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubb_128B,VI_ftype_VIVI,2) +// tag : V6_vsubb_128B +def int_hexagon_V6_vsubb_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddb_dv,VD_ftype_VDVD,2) +// tag : V6_vaddb_dv +def int_hexagon_V6_vaddb_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddb_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddb_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vaddb_dv_128B +def int_hexagon_V6_vaddb_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddb_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubb_dv,VD_ftype_VDVD,2) +// tag : V6_vsubb_dv +def int_hexagon_V6_vsubb_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubb_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubb_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsubb_dv_128B +def int_hexagon_V6_vsubb_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubb_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddh,VI_ftype_VIVI,2) +// tag : V6_vaddh +def int_hexagon_V6_vaddh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaddh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddh_128B,VI_ftype_VIVI,2) +// tag : V6_vaddh_128B +def int_hexagon_V6_vaddh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubh,VI_ftype_VIVI,2) +// tag : V6_vsubh +def int_hexagon_V6_vsubh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsubh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubh_128B,VI_ftype_VIVI,2) +// tag : V6_vsubh_128B +def int_hexagon_V6_vsubh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddh_dv,VD_ftype_VDVD,2) +// tag : V6_vaddh_dv +def int_hexagon_V6_vaddh_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddh_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddh_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vaddh_dv_128B +def int_hexagon_V6_vaddh_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddh_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubh_dv,VD_ftype_VDVD,2) +// tag : V6_vsubh_dv +def int_hexagon_V6_vsubh_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubh_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubh_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsubh_dv_128B +def int_hexagon_V6_vsubh_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubh_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddw,VI_ftype_VIVI,2) +// tag : V6_vaddw +def int_hexagon_V6_vaddw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaddw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddw_128B,VI_ftype_VIVI,2) +// tag : V6_vaddw_128B +def int_hexagon_V6_vaddw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubw,VI_ftype_VIVI,2) +// tag : V6_vsubw +def int_hexagon_V6_vsubw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsubw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubw_128B,VI_ftype_VIVI,2) +// tag : V6_vsubw_128B +def int_hexagon_V6_vsubw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddw_dv,VD_ftype_VDVD,2) +// tag : V6_vaddw_dv +def int_hexagon_V6_vaddw_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddw_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddw_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vaddw_dv_128B +def int_hexagon_V6_vaddw_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddw_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubw_dv,VD_ftype_VDVD,2) +// tag : V6_vsubw_dv +def int_hexagon_V6_vsubw_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubw_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubw_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsubw_dv_128B +def int_hexagon_V6_vsubw_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubw_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddubsat,VI_ftype_VIVI,2) +// tag : V6_vaddubsat +def int_hexagon_V6_vaddubsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaddubsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddubsat_128B,VI_ftype_VIVI,2) +// tag : V6_vaddubsat_128B +def int_hexagon_V6_vaddubsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddubsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddubsat_dv,VD_ftype_VDVD,2) +// tag : V6_vaddubsat_dv +def int_hexagon_V6_vaddubsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddubsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddubsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vaddubsat_dv_128B +def int_hexagon_V6_vaddubsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddubsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsububsat,VI_ftype_VIVI,2) +// tag : V6_vsububsat +def int_hexagon_V6_vsububsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsububsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsububsat_128B,VI_ftype_VIVI,2) +// tag : V6_vsububsat_128B +def int_hexagon_V6_vsububsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsububsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsububsat_dv,VD_ftype_VDVD,2) +// tag : V6_vsububsat_dv +def int_hexagon_V6_vsububsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsububsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsububsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsububsat_dv_128B +def int_hexagon_V6_vsububsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsububsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vadduhsat,VI_ftype_VIVI,2) +// tag : V6_vadduhsat +def int_hexagon_V6_vadduhsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vadduhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vadduhsat_128B,VI_ftype_VIVI,2) +// tag : V6_vadduhsat_128B +def int_hexagon_V6_vadduhsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vadduhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vadduhsat_dv,VD_ftype_VDVD,2) +// tag : V6_vadduhsat_dv +def int_hexagon_V6_vadduhsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vadduhsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vadduhsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vadduhsat_dv_128B +def int_hexagon_V6_vadduhsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vadduhsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubuhsat,VI_ftype_VIVI,2) +// tag : V6_vsubuhsat +def int_hexagon_V6_vsubuhsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsubuhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubuhsat_128B,VI_ftype_VIVI,2) +// tag : V6_vsubuhsat_128B +def int_hexagon_V6_vsubuhsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubuhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubuhsat_dv,VD_ftype_VDVD,2) +// tag : V6_vsubuhsat_dv +def int_hexagon_V6_vsubuhsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubuhsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubuhsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsubuhsat_dv_128B +def int_hexagon_V6_vsubuhsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubuhsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhsat,VI_ftype_VIVI,2) +// tag : V6_vaddhsat +def int_hexagon_V6_vaddhsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaddhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhsat_128B,VI_ftype_VIVI,2) +// tag : V6_vaddhsat_128B +def int_hexagon_V6_vaddhsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhsat_dv,VD_ftype_VDVD,2) +// tag : V6_vaddhsat_dv +def int_hexagon_V6_vaddhsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddhsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vaddhsat_dv_128B +def int_hexagon_V6_vaddhsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddhsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhsat,VI_ftype_VIVI,2) +// tag : V6_vsubhsat +def int_hexagon_V6_vsubhsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsubhsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhsat_128B,VI_ftype_VIVI,2) +// tag : V6_vsubhsat_128B +def int_hexagon_V6_vsubhsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubhsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhsat_dv,VD_ftype_VDVD,2) +// tag : V6_vsubhsat_dv +def int_hexagon_V6_vsubhsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubhsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsubhsat_dv_128B +def int_hexagon_V6_vsubhsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubhsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwsat,VI_ftype_VIVI,2) +// tag : V6_vaddwsat +def int_hexagon_V6_vaddwsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vaddwsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwsat_128B,VI_ftype_VIVI,2) +// tag : V6_vaddwsat_128B +def int_hexagon_V6_vaddwsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddwsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwsat_dv,VD_ftype_VDVD,2) +// tag : V6_vaddwsat_dv +def int_hexagon_V6_vaddwsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vaddwsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vaddwsat_dv_128B +def int_hexagon_V6_vaddwsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vaddwsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwsat,VI_ftype_VIVI,2) +// tag : V6_vsubwsat +def int_hexagon_V6_vsubwsat : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsubwsat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwsat_128B,VI_ftype_VIVI,2) +// tag : V6_vsubwsat_128B +def int_hexagon_V6_vsubwsat_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubwsat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwsat_dv,VD_ftype_VDVD,2) +// tag : V6_vsubwsat_dv +def int_hexagon_V6_vsubwsat_dv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsubwsat_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwsat_dv_128B,VD_ftype_VDVD,2) +// tag : V6_vsubwsat_dv_128B +def int_hexagon_V6_vsubwsat_dv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vsubwsat_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgub,VI_ftype_VIVI,2) +// tag : V6_vavgub +def int_hexagon_V6_vavgub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavgub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgub_128B,VI_ftype_VIVI,2) +// tag : V6_vavgub_128B +def int_hexagon_V6_vavgub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavgub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgubrnd,VI_ftype_VIVI,2) +// tag : V6_vavgubrnd +def int_hexagon_V6_vavgubrnd : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavgubrnd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgubrnd_128B,VI_ftype_VIVI,2) +// tag : V6_vavgubrnd_128B +def int_hexagon_V6_vavgubrnd_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavgubrnd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavguh,VI_ftype_VIVI,2) +// tag : V6_vavguh +def int_hexagon_V6_vavguh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavguh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavguh_128B,VI_ftype_VIVI,2) +// tag : V6_vavguh_128B +def int_hexagon_V6_vavguh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavguh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavguhrnd,VI_ftype_VIVI,2) +// tag : V6_vavguhrnd +def int_hexagon_V6_vavguhrnd : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavguhrnd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavguhrnd_128B,VI_ftype_VIVI,2) +// tag : V6_vavguhrnd_128B +def int_hexagon_V6_vavguhrnd_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavguhrnd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgh,VI_ftype_VIVI,2) +// tag : V6_vavgh +def int_hexagon_V6_vavgh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavgh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgh_128B,VI_ftype_VIVI,2) +// tag : V6_vavgh_128B +def int_hexagon_V6_vavgh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavgh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavghrnd,VI_ftype_VIVI,2) +// tag : V6_vavghrnd +def int_hexagon_V6_vavghrnd : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavghrnd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavghrnd_128B,VI_ftype_VIVI,2) +// tag : V6_vavghrnd_128B +def int_hexagon_V6_vavghrnd_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavghrnd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnavgh,VI_ftype_VIVI,2) +// tag : V6_vnavgh +def int_hexagon_V6_vnavgh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vnavgh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnavgh_128B,VI_ftype_VIVI,2) +// tag : V6_vnavgh_128B +def int_hexagon_V6_vnavgh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vnavgh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgw,VI_ftype_VIVI,2) +// tag : V6_vavgw +def int_hexagon_V6_vavgw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavgw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgw_128B,VI_ftype_VIVI,2) +// tag : V6_vavgw_128B +def int_hexagon_V6_vavgw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavgw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgwrnd,VI_ftype_VIVI,2) +// tag : V6_vavgwrnd +def int_hexagon_V6_vavgwrnd : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vavgwrnd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vavgwrnd_128B,VI_ftype_VIVI,2) +// tag : V6_vavgwrnd_128B +def int_hexagon_V6_vavgwrnd_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vavgwrnd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnavgw,VI_ftype_VIVI,2) +// tag : V6_vnavgw +def int_hexagon_V6_vnavgw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vnavgw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnavgw_128B,VI_ftype_VIVI,2) +// tag : V6_vnavgw_128B +def int_hexagon_V6_vnavgw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vnavgw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffub,VI_ftype_VIVI,2) +// tag : V6_vabsdiffub +def int_hexagon_V6_vabsdiffub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vabsdiffub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffub_128B,VI_ftype_VIVI,2) +// tag : V6_vabsdiffub_128B +def int_hexagon_V6_vabsdiffub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vabsdiffub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffuh,VI_ftype_VIVI,2) +// tag : V6_vabsdiffuh +def int_hexagon_V6_vabsdiffuh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vabsdiffuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffuh_128B,VI_ftype_VIVI,2) +// tag : V6_vabsdiffuh_128B +def int_hexagon_V6_vabsdiffuh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vabsdiffuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffh,VI_ftype_VIVI,2) +// tag : V6_vabsdiffh +def int_hexagon_V6_vabsdiffh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vabsdiffh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffh_128B,VI_ftype_VIVI,2) +// tag : V6_vabsdiffh_128B +def int_hexagon_V6_vabsdiffh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vabsdiffh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffw,VI_ftype_VIVI,2) +// tag : V6_vabsdiffw +def int_hexagon_V6_vabsdiffw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vabsdiffw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsdiffw_128B,VI_ftype_VIVI,2) +// tag : V6_vabsdiffw_128B +def int_hexagon_V6_vabsdiffw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vabsdiffw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnavgub,VI_ftype_VIVI,2) +// tag : V6_vnavgub +def int_hexagon_V6_vnavgub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vnavgub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnavgub_128B,VI_ftype_VIVI,2) +// tag : V6_vnavgub_128B +def int_hexagon_V6_vnavgub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vnavgub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddubh,VD_ftype_VIVI,2) +// tag : V6_vaddubh +def int_hexagon_V6_vaddubh : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vaddubh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddubh_128B,VD_ftype_VIVI,2) +// tag : V6_vaddubh_128B +def int_hexagon_V6_vaddubh_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vaddubh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsububh,VD_ftype_VIVI,2) +// tag : V6_vsububh +def int_hexagon_V6_vsububh : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vsububh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsububh_128B,VD_ftype_VIVI,2) +// tag : V6_vsububh_128B +def int_hexagon_V6_vsububh_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vsububh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhw,VD_ftype_VIVI,2) +// tag : V6_vaddhw +def int_hexagon_V6_vaddhw : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vaddhw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhw_128B,VD_ftype_VIVI,2) +// tag : V6_vaddhw_128B +def int_hexagon_V6_vaddhw_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vaddhw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhw,VD_ftype_VIVI,2) +// tag : V6_vsubhw +def int_hexagon_V6_vsubhw : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vsubhw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhw_128B,VD_ftype_VIVI,2) +// tag : V6_vsubhw_128B +def int_hexagon_V6_vsubhw_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vsubhw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vadduhw,VD_ftype_VIVI,2) +// tag : V6_vadduhw +def int_hexagon_V6_vadduhw : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vadduhw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vadduhw_128B,VD_ftype_VIVI,2) +// tag : V6_vadduhw_128B +def int_hexagon_V6_vadduhw_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vadduhw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubuhw,VD_ftype_VIVI,2) +// tag : V6_vsubuhw +def int_hexagon_V6_vsubuhw : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vsubuhw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubuhw_128B,VD_ftype_VIVI,2) +// tag : V6_vsubuhw_128B +def int_hexagon_V6_vsubuhw_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vsubuhw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vd0,VI_ftype_,0) +// tag : V6_vd0 +def int_hexagon_V6_vd0 : +Hexagon_v512_Intrinsic<"HEXAGON_V6_vd0">; + +// +// BUILTIN_INFO(HEXAGON.V6_vd0_128B,VI_ftype_,0) +// tag : V6_vd0_128B +def int_hexagon_V6_vd0_128B : +Hexagon_v1024_Intrinsic<"HEXAGON_V6_vd0_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddbq,VI_ftype_QVVIVI,3) +// tag : V6_vaddbq +def int_hexagon_V6_vaddbq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vaddbq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddbq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vaddbq_128B +def int_hexagon_V6_vaddbq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vaddbq_128B">; + + +// +// BUILTIN_INFO(HEXAGON.V6_vsubbq,VI_ftype_QVVIVI,3) +// tag : V6_vsubbq +def int_hexagon_V6_vsubbq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vsubbq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubbq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vsubbq_128B +def int_hexagon_V6_vsubbq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vsubbq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddbnq,VI_ftype_QVVIVI,3) +// tag : V6_vaddbnq +def int_hexagon_V6_vaddbnq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vaddbnq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddbnq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vaddbnq_128B +def int_hexagon_V6_vaddbnq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vaddbnq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubbnq,VI_ftype_QVVIVI,3) +// tag : V6_vsubbnq +def int_hexagon_V6_vsubbnq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vsubbnq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubbnq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vsubbnq_128B +def int_hexagon_V6_vsubbnq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vsubbnq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhq,VI_ftype_QVVIVI,3) +// tag : V6_vaddhq +def int_hexagon_V6_vaddhq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vaddhq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vaddhq_128B +def int_hexagon_V6_vaddhq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vaddhq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhq,VI_ftype_QVVIVI,3) +// tag : V6_vsubhq +def int_hexagon_V6_vsubhq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vsubhq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vsubhq_128B +def int_hexagon_V6_vsubhq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vsubhq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhnq,VI_ftype_QVVIVI,3) +// tag : V6_vaddhnq +def int_hexagon_V6_vaddhnq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vaddhnq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddhnq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vaddhnq_128B +def int_hexagon_V6_vaddhnq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vaddhnq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhnq,VI_ftype_QVVIVI,3) +// tag : V6_vsubhnq +def int_hexagon_V6_vsubhnq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vsubhnq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubhnq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vsubhnq_128B +def int_hexagon_V6_vsubhnq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vsubhnq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwq,VI_ftype_QVVIVI,3) +// tag : V6_vaddwq +def int_hexagon_V6_vaddwq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vaddwq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vaddwq_128B +def int_hexagon_V6_vaddwq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vaddwq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwq,VI_ftype_QVVIVI,3) +// tag : V6_vsubwq +def int_hexagon_V6_vsubwq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vsubwq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vsubwq_128B +def int_hexagon_V6_vsubwq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vsubwq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwnq,VI_ftype_QVVIVI,3) +// tag : V6_vaddwnq +def int_hexagon_V6_vaddwnq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vaddwnq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vaddwnq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vaddwnq_128B +def int_hexagon_V6_vaddwnq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vaddwnq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwnq,VI_ftype_QVVIVI,3) +// tag : V6_vsubwnq +def int_hexagon_V6_vsubwnq : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vsubwnq">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsubwnq_128B,VI_ftype_QVVIVI,3) +// tag : V6_vsubwnq_128B +def int_hexagon_V6_vsubwnq_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vsubwnq_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsh,VI_ftype_VI,1) +// tag : V6_vabsh +def int_hexagon_V6_vabsh : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vabsh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsh_128B,VI_ftype_VI,1) +// tag : V6_vabsh_128B +def int_hexagon_V6_vabsh_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vabsh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsh_sat,VI_ftype_VI,1) +// tag : V6_vabsh_sat +def int_hexagon_V6_vabsh_sat : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vabsh_sat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsh_sat_128B,VI_ftype_VI,1) +// tag : V6_vabsh_sat_128B +def int_hexagon_V6_vabsh_sat_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vabsh_sat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsw,VI_ftype_VI,1) +// tag : V6_vabsw +def int_hexagon_V6_vabsw : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vabsw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsw_128B,VI_ftype_VI,1) +// tag : V6_vabsw_128B +def int_hexagon_V6_vabsw_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vabsw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsw_sat,VI_ftype_VI,1) +// tag : V6_vabsw_sat +def int_hexagon_V6_vabsw_sat : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vabsw_sat">; + +// +// BUILTIN_INFO(HEXAGON.V6_vabsw_sat_128B,VI_ftype_VI,1) +// tag : V6_vabsw_sat_128B +def int_hexagon_V6_vabsw_sat_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vabsw_sat_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybv,VD_ftype_VIVI,2) +// tag : V6_vmpybv +def int_hexagon_V6_vmpybv : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpybv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybv_128B,VD_ftype_VIVI,2) +// tag : V6_vmpybv_128B +def int_hexagon_V6_vmpybv_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpybv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybv_acc,VD_ftype_VDVIVI,3) +// tag : V6_vmpybv_acc +def int_hexagon_V6_vmpybv_acc : +Hexagon_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpybv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybv_acc_128B,VD_ftype_VDVIVI,3) +// tag : V6_vmpybv_acc_128B +def int_hexagon_V6_vmpybv_acc_128B : +Hexagon_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpybv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyubv,VD_ftype_VIVI,2) +// tag : V6_vmpyubv +def int_hexagon_V6_vmpyubv : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyubv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyubv_128B,VD_ftype_VIVI,2) +// tag : V6_vmpyubv_128B +def int_hexagon_V6_vmpyubv_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyubv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyubv_acc,VD_ftype_VDVIVI,3) +// tag : V6_vmpyubv_acc +def int_hexagon_V6_vmpyubv_acc : +Hexagon_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyubv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyubv_acc_128B,VD_ftype_VDVIVI,3) +// tag : V6_vmpyubv_acc_128B +def int_hexagon_V6_vmpyubv_acc_128B : +Hexagon_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyubv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybusv,VD_ftype_VIVI,2) +// tag : V6_vmpybusv +def int_hexagon_V6_vmpybusv : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpybusv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybusv_128B,VD_ftype_VIVI,2) +// tag : V6_vmpybusv_128B +def int_hexagon_V6_vmpybusv_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpybusv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybusv_acc,VD_ftype_VDVIVI,3) +// tag : V6_vmpybusv_acc +def int_hexagon_V6_vmpybusv_acc : +Hexagon_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpybusv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybusv_acc_128B,VD_ftype_VDVIVI,3) +// tag : V6_vmpybusv_acc_128B +def int_hexagon_V6_vmpybusv_acc_128B : +Hexagon_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpybusv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabusv,VD_ftype_VDVD,2) +// tag : V6_vmpabusv +def int_hexagon_V6_vmpabusv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpabusv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabusv_128B,VD_ftype_VDVD,2) +// tag : V6_vmpabusv_128B +def int_hexagon_V6_vmpabusv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vmpabusv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabuuv,VD_ftype_VDVD,2) +// tag : V6_vmpabuuv +def int_hexagon_V6_vmpabuuv : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpabuuv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabuuv_128B,VD_ftype_VDVD,2) +// tag : V6_vmpabuuv_128B +def int_hexagon_V6_vmpabuuv_128B : +Hexagon_v2048v2048v2048_Intrinsic<"HEXAGON_V6_vmpabuuv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhv,VD_ftype_VIVI,2) +// tag : V6_vmpyhv +def int_hexagon_V6_vmpyhv : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyhv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhv_128B,VD_ftype_VIVI,2) +// tag : V6_vmpyhv_128B +def int_hexagon_V6_vmpyhv_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyhv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhv_acc,VD_ftype_VDVIVI,3) +// tag : V6_vmpyhv_acc +def int_hexagon_V6_vmpyhv_acc : +Hexagon_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyhv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhv_acc_128B,VD_ftype_VDVIVI,3) +// tag : V6_vmpyhv_acc_128B +def int_hexagon_V6_vmpyhv_acc_128B : +Hexagon_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyhv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuhv,VD_ftype_VIVI,2) +// tag : V6_vmpyuhv +def int_hexagon_V6_vmpyuhv : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyuhv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuhv_128B,VD_ftype_VIVI,2) +// tag : V6_vmpyuhv_128B +def int_hexagon_V6_vmpyuhv_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyuhv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuhv_acc,VD_ftype_VDVIVI,3) +// tag : V6_vmpyuhv_acc +def int_hexagon_V6_vmpyuhv_acc : +Hexagon_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyuhv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuhv_acc_128B,VD_ftype_VDVIVI,3) +// tag : V6_vmpyuhv_acc_128B +def int_hexagon_V6_vmpyuhv_acc_128B : +Hexagon_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyuhv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhvsrs,VI_ftype_VIVI,2) +// tag : V6_vmpyhvsrs +def int_hexagon_V6_vmpyhvsrs : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyhvsrs">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhvsrs_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyhvsrs_128B +def int_hexagon_V6_vmpyhvsrs_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyhvsrs_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhus,VD_ftype_VIVI,2) +// tag : V6_vmpyhus +def int_hexagon_V6_vmpyhus : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyhus">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhus_128B,VD_ftype_VIVI,2) +// tag : V6_vmpyhus_128B +def int_hexagon_V6_vmpyhus_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyhus_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhus_acc,VD_ftype_VDVIVI,3) +// tag : V6_vmpyhus_acc +def int_hexagon_V6_vmpyhus_acc : +Hexagon_v1024v1024v512v512_Intrinsic<"HEXAGON_V6_vmpyhus_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhus_acc_128B,VD_ftype_VDVIVI,3) +// tag : V6_vmpyhus_acc_128B +def int_hexagon_V6_vmpyhus_acc_128B : +Hexagon_v2048v2048v1024v1024_Intrinsic<"HEXAGON_V6_vmpyhus_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyih,VI_ftype_VIVI,2) +// tag : V6_vmpyih +def int_hexagon_V6_vmpyih : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyih">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyih_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyih_128B +def int_hexagon_V6_vmpyih_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyih_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyih_acc,VI_ftype_VIVIVI,3) +// tag : V6_vmpyih_acc +def int_hexagon_V6_vmpyih_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vmpyih_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyih_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vmpyih_acc_128B +def int_hexagon_V6_vmpyih_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyih_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyewuh,VI_ftype_VIVI,2) +// tag : V6_vmpyewuh +def int_hexagon_V6_vmpyewuh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyewuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyewuh_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyewuh_128B +def int_hexagon_V6_vmpyewuh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyewuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh,VI_ftype_VIVI,2) +// tag : V6_vmpyowh +def int_hexagon_V6_vmpyowh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyowh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyowh_128B +def int_hexagon_V6_vmpyowh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyowh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_rnd,VI_ftype_VIVI,2) +// tag : V6_vmpyowh_rnd +def int_hexagon_V6_vmpyowh_rnd : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyowh_rnd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_rnd_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyowh_rnd_128B +def int_hexagon_V6_vmpyowh_rnd_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_sacc,VI_ftype_VIVIVI,3) +// tag : V6_vmpyowh_sacc +def int_hexagon_V6_vmpyowh_sacc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vmpyowh_sacc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_sacc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vmpyowh_sacc_128B +def int_hexagon_V6_vmpyowh_sacc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyowh_sacc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_rnd_sacc,VI_ftype_VIVIVI,3) +// tag : V6_vmpyowh_rnd_sacc +def int_hexagon_V6_vmpyowh_rnd_sacc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_sacc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyowh_rnd_sacc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vmpyowh_rnd_sacc_128B +def int_hexagon_V6_vmpyowh_rnd_sacc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_sacc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyieoh,VI_ftype_VIVI,2) +// tag : V6_vmpyieoh +def int_hexagon_V6_vmpyieoh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyieoh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyieoh_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyieoh_128B +def int_hexagon_V6_vmpyieoh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyieoh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiewuh,VI_ftype_VIVI,2) +// tag : V6_vmpyiewuh +def int_hexagon_V6_vmpyiewuh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyiewuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiewuh_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyiewuh_128B +def int_hexagon_V6_vmpyiewuh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyiewuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiowh,VI_ftype_VIVI,2) +// tag : V6_vmpyiowh +def int_hexagon_V6_vmpyiowh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmpyiowh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiowh_128B,VI_ftype_VIVI,2) +// tag : V6_vmpyiowh_128B +def int_hexagon_V6_vmpyiowh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyiowh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiewh_acc,VI_ftype_VIVIVI,3) +// tag : V6_vmpyiewh_acc +def int_hexagon_V6_vmpyiewh_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vmpyiewh_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiewh_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vmpyiewh_acc_128B +def int_hexagon_V6_vmpyiewh_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyiewh_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiewuh_acc,VI_ftype_VIVIVI,3) +// tag : V6_vmpyiewuh_acc +def int_hexagon_V6_vmpyiewuh_acc : +Hexagon_v512v512v512v512_Intrinsic<"HEXAGON_V6_vmpyiewuh_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiewuh_acc_128B,VI_ftype_VIVIVI,3) +// tag : V6_vmpyiewuh_acc_128B +def int_hexagon_V6_vmpyiewuh_acc_128B : +Hexagon_v1024v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmpyiewuh_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyub,VD_ftype_VISI,2) +// tag : V6_vmpyub +def int_hexagon_V6_vmpyub : +Hexagon_v1024v512i_Intrinsic<"HEXAGON_V6_vmpyub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyub_128B,VD_ftype_VISI,2) +// tag : V6_vmpyub_128B +def int_hexagon_V6_vmpyub_128B : +Hexagon_v2048v1024i_Intrinsic<"HEXAGON_V6_vmpyub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyub_acc,VD_ftype_VDVISI,3) +// tag : V6_vmpyub_acc +def int_hexagon_V6_vmpyub_acc : +Hexagon_v1024v1024v512i_Intrinsic<"HEXAGON_V6_vmpyub_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyub_acc_128B,VD_ftype_VDVISI,3) +// tag : V6_vmpyub_acc_128B +def int_hexagon_V6_vmpyub_acc_128B : +Hexagon_v2048v2048v1024i_Intrinsic<"HEXAGON_V6_vmpyub_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybus,VD_ftype_VISI,2) +// tag : V6_vmpybus +def int_hexagon_V6_vmpybus : +Hexagon_v1024v512i_Intrinsic<"HEXAGON_V6_vmpybus">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybus_128B,VD_ftype_VISI,2) +// tag : V6_vmpybus_128B +def int_hexagon_V6_vmpybus_128B : +Hexagon_v2048v1024i_Intrinsic<"HEXAGON_V6_vmpybus_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybus_acc,VD_ftype_VDVISI,3) +// tag : V6_vmpybus_acc +def int_hexagon_V6_vmpybus_acc : +Hexagon_v1024v1024v512i_Intrinsic<"HEXAGON_V6_vmpybus_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpybus_acc_128B,VD_ftype_VDVISI,3) +// tag : V6_vmpybus_acc_128B +def int_hexagon_V6_vmpybus_acc_128B : +Hexagon_v2048v2048v1024i_Intrinsic<"HEXAGON_V6_vmpybus_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabus,VD_ftype_VDSI,2) +// tag : V6_vmpabus +def int_hexagon_V6_vmpabus : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpabus">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabus_128B,VD_ftype_VDSI,2) +// tag : V6_vmpabus_128B +def int_hexagon_V6_vmpabus_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vmpabus_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabus_acc,VD_ftype_VDVDSI,3) +// tag : V6_vmpabus_acc +def int_hexagon_V6_vmpabus_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpabus_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpabus_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vmpabus_acc_128B +def int_hexagon_V6_vmpabus_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vmpabus_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpahb,VD_ftype_VDSI,2) +// tag : V6_vmpahb +def int_hexagon_V6_vmpahb : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpahb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpahb_128B,VD_ftype_VDSI,2) +// tag : V6_vmpahb_128B +def int_hexagon_V6_vmpahb_128B : +Hexagon_v2048v2048i_Intrinsic<"HEXAGON_V6_vmpahb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpahb_acc,VD_ftype_VDVDSI,3) +// tag : V6_vmpahb_acc +def int_hexagon_V6_vmpahb_acc : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpahb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpahb_acc_128B,VD_ftype_VDVDSI,3) +// tag : V6_vmpahb_acc_128B +def int_hexagon_V6_vmpahb_acc_128B : +Hexagon_v2048v2048v2048i_Intrinsic<"HEXAGON_V6_vmpahb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyh,VD_ftype_VISI,2) +// tag : V6_vmpyh +def int_hexagon_V6_vmpyh : +Hexagon_v1024v512i_Intrinsic<"HEXAGON_V6_vmpyh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyh_128B,VD_ftype_VISI,2) +// tag : V6_vmpyh_128B +def int_hexagon_V6_vmpyh_128B : +Hexagon_v2048v1024i_Intrinsic<"HEXAGON_V6_vmpyh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhsat_acc,VD_ftype_VDVISI,3) +// tag : V6_vmpyhsat_acc +def int_hexagon_V6_vmpyhsat_acc : +Hexagon_v1024v1024v512i_Intrinsic<"HEXAGON_V6_vmpyhsat_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhsat_acc_128B,VD_ftype_VDVISI,3) +// tag : V6_vmpyhsat_acc_128B +def int_hexagon_V6_vmpyhsat_acc_128B : +Hexagon_v2048v2048v1024i_Intrinsic<"HEXAGON_V6_vmpyhsat_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhss,VI_ftype_VISI,2) +// tag : V6_vmpyhss +def int_hexagon_V6_vmpyhss : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vmpyhss">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhss_128B,VI_ftype_VISI,2) +// tag : V6_vmpyhss_128B +def int_hexagon_V6_vmpyhss_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyhss_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhsrs,VI_ftype_VISI,2) +// tag : V6_vmpyhsrs +def int_hexagon_V6_vmpyhsrs : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vmpyhsrs">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyhsrs_128B,VI_ftype_VISI,2) +// tag : V6_vmpyhsrs_128B +def int_hexagon_V6_vmpyhsrs_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyhsrs_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuh,VD_ftype_VISI,2) +// tag : V6_vmpyuh +def int_hexagon_V6_vmpyuh : +Hexagon_v1024v512i_Intrinsic<"HEXAGON_V6_vmpyuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuh_128B,VD_ftype_VISI,2) +// tag : V6_vmpyuh_128B +def int_hexagon_V6_vmpyuh_128B : +Hexagon_v2048v1024i_Intrinsic<"HEXAGON_V6_vmpyuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuh_acc,VD_ftype_VDVISI,3) +// tag : V6_vmpyuh_acc +def int_hexagon_V6_vmpyuh_acc : +Hexagon_v1024v1024v512i_Intrinsic<"HEXAGON_V6_vmpyuh_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyuh_acc_128B,VD_ftype_VDVISI,3) +// tag : V6_vmpyuh_acc_128B +def int_hexagon_V6_vmpyuh_acc_128B : +Hexagon_v2048v2048v1024i_Intrinsic<"HEXAGON_V6_vmpyuh_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyihb,VI_ftype_VISI,2) +// tag : V6_vmpyihb +def int_hexagon_V6_vmpyihb : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vmpyihb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyihb_128B,VI_ftype_VISI,2) +// tag : V6_vmpyihb_128B +def int_hexagon_V6_vmpyihb_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyihb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyihb_acc,VI_ftype_VIVISI,3) +// tag : V6_vmpyihb_acc +def int_hexagon_V6_vmpyihb_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vmpyihb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyihb_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vmpyihb_acc_128B +def int_hexagon_V6_vmpyihb_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyihb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwb,VI_ftype_VISI,2) +// tag : V6_vmpyiwb +def int_hexagon_V6_vmpyiwb : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vmpyiwb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwb_128B,VI_ftype_VISI,2) +// tag : V6_vmpyiwb_128B +def int_hexagon_V6_vmpyiwb_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyiwb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwb_acc,VI_ftype_VIVISI,3) +// tag : V6_vmpyiwb_acc +def int_hexagon_V6_vmpyiwb_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vmpyiwb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwb_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vmpyiwb_acc_128B +def int_hexagon_V6_vmpyiwb_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyiwb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwh,VI_ftype_VISI,2) +// tag : V6_vmpyiwh +def int_hexagon_V6_vmpyiwh : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vmpyiwh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwh_128B,VI_ftype_VISI,2) +// tag : V6_vmpyiwh_128B +def int_hexagon_V6_vmpyiwh_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyiwh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwh_acc,VI_ftype_VIVISI,3) +// tag : V6_vmpyiwh_acc +def int_hexagon_V6_vmpyiwh_acc : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vmpyiwh_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmpyiwh_acc_128B,VI_ftype_VIVISI,3) +// tag : V6_vmpyiwh_acc_128B +def int_hexagon_V6_vmpyiwh_acc_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vmpyiwh_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vand,VI_ftype_VIVI,2) +// tag : V6_vand +def int_hexagon_V6_vand : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vand">; + +// +// BUILTIN_INFO(HEXAGON.V6_vand_128B,VI_ftype_VIVI,2) +// tag : V6_vand_128B +def int_hexagon_V6_vand_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vand_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vor,VI_ftype_VIVI,2) +// tag : V6_vor +def int_hexagon_V6_vor : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vor_128B,VI_ftype_VIVI,2) +// tag : V6_vor_128B +def int_hexagon_V6_vor_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vxor,VI_ftype_VIVI,2) +// tag : V6_vxor +def int_hexagon_V6_vxor : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vxor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vxor_128B,VI_ftype_VIVI,2) +// tag : V6_vxor_128B +def int_hexagon_V6_vxor_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vxor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnot,VI_ftype_VI,1) +// tag : V6_vnot +def int_hexagon_V6_vnot : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vnot">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnot_128B,VI_ftype_VI,1) +// tag : V6_vnot_128B +def int_hexagon_V6_vnot_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vnot_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandqrt,VI_ftype_QVSI,2) +// tag : V6_vandqrt +def int_hexagon_V6_vandqrt : +Hexagon_v512v64ii_Intrinsic<"HEXAGON_V6_vandqrt">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandqrt_128B,VI_ftype_QVSI,2) +// tag : V6_vandqrt_128B +def int_hexagon_V6_vandqrt_128B : +Hexagon_v1024v128ii_Intrinsic<"HEXAGON_V6_vandqrt_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandqrt_acc,VI_ftype_VIQVSI,3) +// tag : V6_vandqrt_acc +def int_hexagon_V6_vandqrt_acc : +Hexagon_v512v512v64ii_Intrinsic<"HEXAGON_V6_vandqrt_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandqrt_acc_128B,VI_ftype_VIQVSI,3) +// tag : V6_vandqrt_acc_128B +def int_hexagon_V6_vandqrt_acc_128B : +Hexagon_v1024v1024v128ii_Intrinsic<"HEXAGON_V6_vandqrt_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandvrt,QV_ftype_VISI,2) +// tag : V6_vandvrt +def int_hexagon_V6_vandvrt : +Hexagon_v64iv512i_Intrinsic<"HEXAGON_V6_vandvrt">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandvrt_128B,QV_ftype_VISI,2) +// tag : V6_vandvrt_128B +def int_hexagon_V6_vandvrt_128B : +Hexagon_v128iv1024i_Intrinsic<"HEXAGON_V6_vandvrt_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandvrt_acc,QV_ftype_QVVISI,3) +// tag : V6_vandvrt_acc +def int_hexagon_V6_vandvrt_acc : +Hexagon_v64iv64iv512i_Intrinsic<"HEXAGON_V6_vandvrt_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vandvrt_acc_128B,QV_ftype_QVVISI,3) +// tag : V6_vandvrt_acc_128B +def int_hexagon_V6_vandvrt_acc_128B : +Hexagon_v128iv128iv1024i_Intrinsic<"HEXAGON_V6_vandvrt_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw,QV_ftype_VIVI,2) +// tag : V6_vgtw +def int_hexagon_V6_vgtw : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_vgtw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_128B,QV_ftype_VIVI,2) +// tag : V6_vgtw_128B +def int_hexagon_V6_vgtw_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_and,QV_ftype_QVVIVI,3) +// tag : V6_vgtw_and +def int_hexagon_V6_vgtw_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtw_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtw_and_128B +def int_hexagon_V6_vgtw_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtw_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_or,QV_ftype_QVVIVI,3) +// tag : V6_vgtw_or +def int_hexagon_V6_vgtw_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtw_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtw_or_128B +def int_hexagon_V6_vgtw_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtw_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_xor,QV_ftype_QVVIVI,3) +// tag : V6_vgtw_xor +def int_hexagon_V6_vgtw_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtw_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtw_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtw_xor_128B +def int_hexagon_V6_vgtw_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtw_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw,QV_ftype_VIVI,2) +// tag : V6_veqw +def int_hexagon_V6_veqw : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_veqw">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_128B,QV_ftype_VIVI,2) +// tag : V6_veqw_128B +def int_hexagon_V6_veqw_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_veqw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_and,QV_ftype_QVVIVI,3) +// tag : V6_veqw_and +def int_hexagon_V6_veqw_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqw_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqw_and_128B +def int_hexagon_V6_veqw_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqw_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_or,QV_ftype_QVVIVI,3) +// tag : V6_veqw_or +def int_hexagon_V6_veqw_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqw_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqw_or_128B +def int_hexagon_V6_veqw_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqw_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_xor,QV_ftype_QVVIVI,3) +// tag : V6_veqw_xor +def int_hexagon_V6_veqw_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqw_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqw_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqw_xor_128B +def int_hexagon_V6_veqw_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqw_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth,QV_ftype_VIVI,2) +// tag : V6_vgth +def int_hexagon_V6_vgth : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_vgth">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_128B,QV_ftype_VIVI,2) +// tag : V6_vgth_128B +def int_hexagon_V6_vgth_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_vgth_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_and,QV_ftype_QVVIVI,3) +// tag : V6_vgth_and +def int_hexagon_V6_vgth_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgth_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgth_and_128B +def int_hexagon_V6_vgth_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgth_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_or,QV_ftype_QVVIVI,3) +// tag : V6_vgth_or +def int_hexagon_V6_vgth_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgth_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgth_or_128B +def int_hexagon_V6_vgth_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgth_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_xor,QV_ftype_QVVIVI,3) +// tag : V6_vgth_xor +def int_hexagon_V6_vgth_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgth_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgth_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgth_xor_128B +def int_hexagon_V6_vgth_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgth_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh,QV_ftype_VIVI,2) +// tag : V6_veqh +def int_hexagon_V6_veqh : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_veqh">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_128B,QV_ftype_VIVI,2) +// tag : V6_veqh_128B +def int_hexagon_V6_veqh_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_veqh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_and,QV_ftype_QVVIVI,3) +// tag : V6_veqh_and +def int_hexagon_V6_veqh_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqh_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqh_and_128B +def int_hexagon_V6_veqh_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqh_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_or,QV_ftype_QVVIVI,3) +// tag : V6_veqh_or +def int_hexagon_V6_veqh_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqh_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqh_or_128B +def int_hexagon_V6_veqh_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqh_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_xor,QV_ftype_QVVIVI,3) +// tag : V6_veqh_xor +def int_hexagon_V6_veqh_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqh_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqh_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqh_xor_128B +def int_hexagon_V6_veqh_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqh_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb,QV_ftype_VIVI,2) +// tag : V6_vgtb +def int_hexagon_V6_vgtb : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_vgtb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_128B,QV_ftype_VIVI,2) +// tag : V6_vgtb_128B +def int_hexagon_V6_vgtb_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_and,QV_ftype_QVVIVI,3) +// tag : V6_vgtb_and +def int_hexagon_V6_vgtb_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtb_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtb_and_128B +def int_hexagon_V6_vgtb_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtb_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_or,QV_ftype_QVVIVI,3) +// tag : V6_vgtb_or +def int_hexagon_V6_vgtb_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtb_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtb_or_128B +def int_hexagon_V6_vgtb_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtb_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_xor,QV_ftype_QVVIVI,3) +// tag : V6_vgtb_xor +def int_hexagon_V6_vgtb_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtb_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtb_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtb_xor_128B +def int_hexagon_V6_vgtb_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtb_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb,QV_ftype_VIVI,2) +// tag : V6_veqb +def int_hexagon_V6_veqb : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_veqb">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_128B,QV_ftype_VIVI,2) +// tag : V6_veqb_128B +def int_hexagon_V6_veqb_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_veqb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_and,QV_ftype_QVVIVI,3) +// tag : V6_veqb_and +def int_hexagon_V6_veqb_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqb_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqb_and_128B +def int_hexagon_V6_veqb_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqb_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_or,QV_ftype_QVVIVI,3) +// tag : V6_veqb_or +def int_hexagon_V6_veqb_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqb_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqb_or_128B +def int_hexagon_V6_veqb_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqb_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_xor,QV_ftype_QVVIVI,3) +// tag : V6_veqb_xor +def int_hexagon_V6_veqb_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_veqb_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_veqb_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_veqb_xor_128B +def int_hexagon_V6_veqb_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_veqb_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw,QV_ftype_VIVI,2) +// tag : V6_vgtuw +def int_hexagon_V6_vgtuw : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_vgtuw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_128B,QV_ftype_VIVI,2) +// tag : V6_vgtuw_128B +def int_hexagon_V6_vgtuw_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_and,QV_ftype_QVVIVI,3) +// tag : V6_vgtuw_and +def int_hexagon_V6_vgtuw_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtuw_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtuw_and_128B +def int_hexagon_V6_vgtuw_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuw_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_or,QV_ftype_QVVIVI,3) +// tag : V6_vgtuw_or +def int_hexagon_V6_vgtuw_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtuw_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtuw_or_128B +def int_hexagon_V6_vgtuw_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuw_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_xor,QV_ftype_QVVIVI,3) +// tag : V6_vgtuw_xor +def int_hexagon_V6_vgtuw_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtuw_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuw_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtuw_xor_128B +def int_hexagon_V6_vgtuw_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuw_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh,QV_ftype_VIVI,2) +// tag : V6_vgtuh +def int_hexagon_V6_vgtuh : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_vgtuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_128B,QV_ftype_VIVI,2) +// tag : V6_vgtuh_128B +def int_hexagon_V6_vgtuh_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_and,QV_ftype_QVVIVI,3) +// tag : V6_vgtuh_and +def int_hexagon_V6_vgtuh_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtuh_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtuh_and_128B +def int_hexagon_V6_vgtuh_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuh_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_or,QV_ftype_QVVIVI,3) +// tag : V6_vgtuh_or +def int_hexagon_V6_vgtuh_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtuh_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtuh_or_128B +def int_hexagon_V6_vgtuh_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuh_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_xor,QV_ftype_QVVIVI,3) +// tag : V6_vgtuh_xor +def int_hexagon_V6_vgtuh_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtuh_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtuh_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtuh_xor_128B +def int_hexagon_V6_vgtuh_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtuh_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub,QV_ftype_VIVI,2) +// tag : V6_vgtub +def int_hexagon_V6_vgtub : +Hexagon_v64iv512v512_Intrinsic<"HEXAGON_V6_vgtub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_128B,QV_ftype_VIVI,2) +// tag : V6_vgtub_128B +def int_hexagon_V6_vgtub_128B : +Hexagon_v128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_and,QV_ftype_QVVIVI,3) +// tag : V6_vgtub_and +def int_hexagon_V6_vgtub_and : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtub_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_and_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtub_and_128B +def int_hexagon_V6_vgtub_and_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtub_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_or,QV_ftype_QVVIVI,3) +// tag : V6_vgtub_or +def int_hexagon_V6_vgtub_or : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtub_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_or_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtub_or_128B +def int_hexagon_V6_vgtub_or_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtub_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_xor,QV_ftype_QVVIVI,3) +// tag : V6_vgtub_xor +def int_hexagon_V6_vgtub_xor : +Hexagon_v64iv64iv512v512_Intrinsic<"HEXAGON_V6_vgtub_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_vgtub_xor_128B,QV_ftype_QVVIVI,3) +// tag : V6_vgtub_xor_128B +def int_hexagon_V6_vgtub_xor_128B : +Hexagon_v128iv128iv1024v1024_Intrinsic<"HEXAGON_V6_vgtub_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_or,QV_ftype_QVQV,2) +// tag : V6_pred_or +def int_hexagon_V6_pred_or : +Hexagon_v64iv64iv64i_Intrinsic<"HEXAGON_V6_pred_or">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_or_128B,QV_ftype_QVQV,2) +// tag : V6_pred_or_128B +def int_hexagon_V6_pred_or_128B : +Hexagon_v128iv128iv128i_Intrinsic<"HEXAGON_V6_pred_or_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_and,QV_ftype_QVQV,2) +// tag : V6_pred_and +def int_hexagon_V6_pred_and : +Hexagon_v64iv64iv64i_Intrinsic<"HEXAGON_V6_pred_and">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_and_128B,QV_ftype_QVQV,2) +// tag : V6_pred_and_128B +def int_hexagon_V6_pred_and_128B : +Hexagon_v128iv128iv128i_Intrinsic<"HEXAGON_V6_pred_and_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_not,QV_ftype_QV,1) +// tag : V6_pred_not +def int_hexagon_V6_pred_not : +Hexagon_v64iv64i_Intrinsic<"HEXAGON_V6_pred_not">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_not_128B,QV_ftype_QV,1) +// tag : V6_pred_not_128B +def int_hexagon_V6_pred_not_128B : +Hexagon_v128iv128i_Intrinsic<"HEXAGON_V6_pred_not_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_xor,QV_ftype_QVQV,2) +// tag : V6_pred_xor +def int_hexagon_V6_pred_xor : +Hexagon_v64iv64iv64i_Intrinsic<"HEXAGON_V6_pred_xor">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_xor_128B,QV_ftype_QVQV,2) +// tag : V6_pred_xor_128B +def int_hexagon_V6_pred_xor_128B : +Hexagon_v128iv128iv128i_Intrinsic<"HEXAGON_V6_pred_xor_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_and_n,QV_ftype_QVQV,2) +// tag : V6_pred_and_n +def int_hexagon_V6_pred_and_n : +Hexagon_v64iv64iv64i_Intrinsic<"HEXAGON_V6_pred_and_n">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_and_n_128B,QV_ftype_QVQV,2) +// tag : V6_pred_and_n_128B +def int_hexagon_V6_pred_and_n_128B : +Hexagon_v128iv128iv128i_Intrinsic<"HEXAGON_V6_pred_and_n_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_or_n,QV_ftype_QVQV,2) +// tag : V6_pred_or_n +def int_hexagon_V6_pred_or_n : +Hexagon_v64iv64iv64i_Intrinsic<"HEXAGON_V6_pred_or_n">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_or_n_128B,QV_ftype_QVQV,2) +// tag : V6_pred_or_n_128B +def int_hexagon_V6_pred_or_n_128B : +Hexagon_v128iv128iv128i_Intrinsic<"HEXAGON_V6_pred_or_n_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_scalar2,QV_ftype_SI,1) +// tag : V6_pred_scalar2 +def int_hexagon_V6_pred_scalar2 : +Hexagon_v64ii_Intrinsic<"HEXAGON_V6_pred_scalar2">; + +// +// BUILTIN_INFO(HEXAGON.V6_pred_scalar2_128B,QV_ftype_SI,1) +// tag : V6_pred_scalar2_128B +def int_hexagon_V6_pred_scalar2_128B : +Hexagon_v128ii_Intrinsic<"HEXAGON_V6_pred_scalar2_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmux,VI_ftype_QVVIVI,3) +// tag : V6_vmux +def int_hexagon_V6_vmux : +Hexagon_v512v64iv512v512_Intrinsic<"HEXAGON_V6_vmux">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmux_128B,VI_ftype_QVVIVI,3) +// tag : V6_vmux_128B +def int_hexagon_V6_vmux_128B : +Hexagon_v1024v128iv1024v1024_Intrinsic<"HEXAGON_V6_vmux_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vswap,VD_ftype_QVVIVI,3) +// tag : V6_vswap +def int_hexagon_V6_vswap : +Hexagon_v1024v64iv512v512_Intrinsic<"HEXAGON_V6_vswap">; + +// +// BUILTIN_INFO(HEXAGON.V6_vswap_128B,VD_ftype_QVVIVI,3) +// tag : V6_vswap_128B +def int_hexagon_V6_vswap_128B : +Hexagon_v2048v128iv1024v1024_Intrinsic<"HEXAGON_V6_vswap_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxub,VI_ftype_VIVI,2) +// tag : V6_vmaxub +def int_hexagon_V6_vmaxub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmaxub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxub_128B,VI_ftype_VIVI,2) +// tag : V6_vmaxub_128B +def int_hexagon_V6_vmaxub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmaxub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminub,VI_ftype_VIVI,2) +// tag : V6_vminub +def int_hexagon_V6_vminub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vminub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminub_128B,VI_ftype_VIVI,2) +// tag : V6_vminub_128B +def int_hexagon_V6_vminub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vminub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxuh,VI_ftype_VIVI,2) +// tag : V6_vmaxuh +def int_hexagon_V6_vmaxuh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmaxuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxuh_128B,VI_ftype_VIVI,2) +// tag : V6_vmaxuh_128B +def int_hexagon_V6_vmaxuh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmaxuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminuh,VI_ftype_VIVI,2) +// tag : V6_vminuh +def int_hexagon_V6_vminuh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vminuh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminuh_128B,VI_ftype_VIVI,2) +// tag : V6_vminuh_128B +def int_hexagon_V6_vminuh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vminuh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxh,VI_ftype_VIVI,2) +// tag : V6_vmaxh +def int_hexagon_V6_vmaxh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmaxh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxh_128B,VI_ftype_VIVI,2) +// tag : V6_vmaxh_128B +def int_hexagon_V6_vmaxh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmaxh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminh,VI_ftype_VIVI,2) +// tag : V6_vminh +def int_hexagon_V6_vminh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vminh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminh_128B,VI_ftype_VIVI,2) +// tag : V6_vminh_128B +def int_hexagon_V6_vminh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vminh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxw,VI_ftype_VIVI,2) +// tag : V6_vmaxw +def int_hexagon_V6_vmaxw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vmaxw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vmaxw_128B,VI_ftype_VIVI,2) +// tag : V6_vmaxw_128B +def int_hexagon_V6_vmaxw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vmaxw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminw,VI_ftype_VIVI,2) +// tag : V6_vminw +def int_hexagon_V6_vminw : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vminw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vminw_128B,VI_ftype_VIVI,2) +// tag : V6_vminw_128B +def int_hexagon_V6_vminw_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vminw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsathub,VI_ftype_VIVI,2) +// tag : V6_vsathub +def int_hexagon_V6_vsathub : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsathub">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsathub_128B,VI_ftype_VIVI,2) +// tag : V6_vsathub_128B +def int_hexagon_V6_vsathub_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsathub_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsatwh,VI_ftype_VIVI,2) +// tag : V6_vsatwh +def int_hexagon_V6_vsatwh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vsatwh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vsatwh_128B,VI_ftype_VIVI,2) +// tag : V6_vsatwh_128B +def int_hexagon_V6_vsatwh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vsatwh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffeb,VI_ftype_VIVI,2) +// tag : V6_vshuffeb +def int_hexagon_V6_vshuffeb : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vshuffeb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffeb_128B,VI_ftype_VIVI,2) +// tag : V6_vshuffeb_128B +def int_hexagon_V6_vshuffeb_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vshuffeb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffob,VI_ftype_VIVI,2) +// tag : V6_vshuffob +def int_hexagon_V6_vshuffob : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vshuffob">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffob_128B,VI_ftype_VIVI,2) +// tag : V6_vshuffob_128B +def int_hexagon_V6_vshuffob_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vshuffob_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufeh,VI_ftype_VIVI,2) +// tag : V6_vshufeh +def int_hexagon_V6_vshufeh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vshufeh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufeh_128B,VI_ftype_VIVI,2) +// tag : V6_vshufeh_128B +def int_hexagon_V6_vshufeh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vshufeh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufoh,VI_ftype_VIVI,2) +// tag : V6_vshufoh +def int_hexagon_V6_vshufoh : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vshufoh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufoh_128B,VI_ftype_VIVI,2) +// tag : V6_vshufoh_128B +def int_hexagon_V6_vshufoh_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vshufoh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffvdd,VD_ftype_VIVISI,3) +// tag : V6_vshuffvdd +def int_hexagon_V6_vshuffvdd : +Hexagon_v1024v512v512i_Intrinsic<"HEXAGON_V6_vshuffvdd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffvdd_128B,VD_ftype_VIVISI,3) +// tag : V6_vshuffvdd_128B +def int_hexagon_V6_vshuffvdd_128B : +Hexagon_v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vshuffvdd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealvdd,VD_ftype_VIVISI,3) +// tag : V6_vdealvdd +def int_hexagon_V6_vdealvdd : +Hexagon_v1024v512v512i_Intrinsic<"HEXAGON_V6_vdealvdd">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealvdd_128B,VD_ftype_VIVISI,3) +// tag : V6_vdealvdd_128B +def int_hexagon_V6_vdealvdd_128B : +Hexagon_v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vdealvdd_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufoeh,VD_ftype_VIVI,2) +// tag : V6_vshufoeh +def int_hexagon_V6_vshufoeh : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vshufoeh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufoeh_128B,VD_ftype_VIVI,2) +// tag : V6_vshufoeh_128B +def int_hexagon_V6_vshufoeh_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vshufoeh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufoeb,VD_ftype_VIVI,2) +// tag : V6_vshufoeb +def int_hexagon_V6_vshufoeb : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vshufoeb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshufoeb_128B,VD_ftype_VIVI,2) +// tag : V6_vshufoeb_128B +def int_hexagon_V6_vshufoeb_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vshufoeb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealh,VI_ftype_VI,1) +// tag : V6_vdealh +def int_hexagon_V6_vdealh : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vdealh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealh_128B,VI_ftype_VI,1) +// tag : V6_vdealh_128B +def int_hexagon_V6_vdealh_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vdealh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealb,VI_ftype_VI,1) +// tag : V6_vdealb +def int_hexagon_V6_vdealb : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vdealb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealb_128B,VI_ftype_VI,1) +// tag : V6_vdealb_128B +def int_hexagon_V6_vdealb_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vdealb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealb4w,VI_ftype_VIVI,2) +// tag : V6_vdealb4w +def int_hexagon_V6_vdealb4w : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vdealb4w">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdealb4w_128B,VI_ftype_VIVI,2) +// tag : V6_vdealb4w_128B +def int_hexagon_V6_vdealb4w_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vdealb4w_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffh,VI_ftype_VI,1) +// tag : V6_vshuffh +def int_hexagon_V6_vshuffh : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vshuffh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffh_128B,VI_ftype_VI,1) +// tag : V6_vshuffh_128B +def int_hexagon_V6_vshuffh_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vshuffh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffb,VI_ftype_VI,1) +// tag : V6_vshuffb +def int_hexagon_V6_vshuffb : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vshuffb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vshuffb_128B,VI_ftype_VI,1) +// tag : V6_vshuffb_128B +def int_hexagon_V6_vshuffb_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vshuffb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_extractw,SI_ftype_VISI,2) +// tag : V6_extractw +def int_hexagon_V6_extractw : +Hexagon_iv512i_Intrinsic<"HEXAGON_V6_extractw">; + +// +// BUILTIN_INFO(HEXAGON.V6_extractw_128B,SI_ftype_VISI,2) +// tag : V6_extractw_128B +def int_hexagon_V6_extractw_128B : +Hexagon_iv1024i_Intrinsic<"HEXAGON_V6_extractw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vinsertwr,VI_ftype_VISI,2) +// tag : V6_vinsertwr +def int_hexagon_V6_vinsertwr : +Hexagon_v512v512i_Intrinsic<"HEXAGON_V6_vinsertwr">; + +// +// BUILTIN_INFO(HEXAGON.V6_vinsertwr_128B,VI_ftype_VISI,2) +// tag : V6_vinsertwr_128B +def int_hexagon_V6_vinsertwr_128B : +Hexagon_v1024v1024i_Intrinsic<"HEXAGON_V6_vinsertwr_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_lvsplatw,VI_ftype_SI,1) +// tag : V6_lvsplatw +def int_hexagon_V6_lvsplatw : +Hexagon_v512i_Intrinsic<"HEXAGON_V6_lvsplatw">; + +// +// BUILTIN_INFO(HEXAGON.V6_lvsplatw_128B,VI_ftype_SI,1) +// tag : V6_lvsplatw_128B +def int_hexagon_V6_lvsplatw_128B : +Hexagon_v1024i_Intrinsic<"HEXAGON_V6_lvsplatw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vassign,VI_ftype_VI,1) +// tag : V6_vassign +def int_hexagon_V6_vassign : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vassign">; + +// +// BUILTIN_INFO(HEXAGON.V6_vassign_128B,VI_ftype_VI,1) +// tag : V6_vassign_128B +def int_hexagon_V6_vassign_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vassign_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vcombine,VD_ftype_VIVI,2) +// tag : V6_vcombine +def int_hexagon_V6_vcombine : +Hexagon_v1024v512v512_Intrinsic<"HEXAGON_V6_vcombine">; + +// +// BUILTIN_INFO(HEXAGON.V6_vcombine_128B,VD_ftype_VIVI,2) +// tag : V6_vcombine_128B +def int_hexagon_V6_vcombine_128B : +Hexagon_v2048v1024v1024_Intrinsic<"HEXAGON_V6_vcombine_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb,VI_ftype_VIDISI,3) +// tag : V6_vlutb +def int_hexagon_V6_vlutb : +Hexagon_v512v512LLii_Intrinsic<"HEXAGON_V6_vlutb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_128B,VI_ftype_VIDISI,3) +// tag : V6_vlutb_128B +def int_hexagon_V6_vlutb_128B : +Hexagon_v1024v1024LLii_Intrinsic<"HEXAGON_V6_vlutb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_acc,VI_ftype_VIVIDISI,4) +// tag : V6_vlutb_acc +def int_hexagon_V6_vlutb_acc : +Hexagon_v512v512v512LLii_Intrinsic<"HEXAGON_V6_vlutb_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_acc_128B,VI_ftype_VIVIDISI,4) +// tag : V6_vlutb_acc_128B +def int_hexagon_V6_vlutb_acc_128B : +Hexagon_v1024v1024v1024LLii_Intrinsic<"HEXAGON_V6_vlutb_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_dv,VD_ftype_VDDISI,3) +// tag : V6_vlutb_dv +def int_hexagon_V6_vlutb_dv : +Hexagon_v1024v1024LLii_Intrinsic<"HEXAGON_V6_vlutb_dv">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_dv_128B,VD_ftype_VDDISI,3) +// tag : V6_vlutb_dv_128B +def int_hexagon_V6_vlutb_dv_128B : +Hexagon_v2048v2048LLii_Intrinsic<"HEXAGON_V6_vlutb_dv_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_dv_acc,VD_ftype_VDVDDISI,4) +// tag : V6_vlutb_dv_acc +def int_hexagon_V6_vlutb_dv_acc : +Hexagon_v1024v1024v1024LLii_Intrinsic<"HEXAGON_V6_vlutb_dv_acc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutb_dv_acc_128B,VD_ftype_VDVDDISI,4) +// tag : V6_vlutb_dv_acc_128B +def int_hexagon_V6_vlutb_dv_acc_128B : +Hexagon_v2048v2048v2048LLii_Intrinsic<"HEXAGON_V6_vlutb_dv_acc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdelta,VI_ftype_VIVI,2) +// tag : V6_vdelta +def int_hexagon_V6_vdelta : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vdelta">; + +// +// BUILTIN_INFO(HEXAGON.V6_vdelta_128B,VI_ftype_VIVI,2) +// tag : V6_vdelta_128B +def int_hexagon_V6_vdelta_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vdelta_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrdelta,VI_ftype_VIVI,2) +// tag : V6_vrdelta +def int_hexagon_V6_vrdelta : +Hexagon_v512v512v512_Intrinsic<"HEXAGON_V6_vrdelta">; + +// +// BUILTIN_INFO(HEXAGON.V6_vrdelta_128B,VI_ftype_VIVI,2) +// tag : V6_vrdelta_128B +def int_hexagon_V6_vrdelta_128B : +Hexagon_v1024v1024v1024_Intrinsic<"HEXAGON_V6_vrdelta_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vcl0w,VI_ftype_VI,1) +// tag : V6_vcl0w +def int_hexagon_V6_vcl0w : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vcl0w">; + +// +// BUILTIN_INFO(HEXAGON.V6_vcl0w_128B,VI_ftype_VI,1) +// tag : V6_vcl0w_128B +def int_hexagon_V6_vcl0w_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vcl0w_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vcl0h,VI_ftype_VI,1) +// tag : V6_vcl0h +def int_hexagon_V6_vcl0h : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vcl0h">; + +// +// BUILTIN_INFO(HEXAGON.V6_vcl0h_128B,VI_ftype_VI,1) +// tag : V6_vcl0h_128B +def int_hexagon_V6_vcl0h_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vcl0h_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnormamtw,VI_ftype_VI,1) +// tag : V6_vnormamtw +def int_hexagon_V6_vnormamtw : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vnormamtw">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnormamtw_128B,VI_ftype_VI,1) +// tag : V6_vnormamtw_128B +def int_hexagon_V6_vnormamtw_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vnormamtw_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnormamth,VI_ftype_VI,1) +// tag : V6_vnormamth +def int_hexagon_V6_vnormamth : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vnormamth">; + +// +// BUILTIN_INFO(HEXAGON.V6_vnormamth_128B,VI_ftype_VI,1) +// tag : V6_vnormamth_128B +def int_hexagon_V6_vnormamth_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vnormamth_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpopcounth,VI_ftype_VI,1) +// tag : V6_vpopcounth +def int_hexagon_V6_vpopcounth : +Hexagon_v512v512_Intrinsic<"HEXAGON_V6_vpopcounth">; + +// +// BUILTIN_INFO(HEXAGON.V6_vpopcounth_128B,VI_ftype_VI,1) +// tag : V6_vpopcounth_128B +def int_hexagon_V6_vpopcounth_128B : +Hexagon_v1024v1024_Intrinsic<"HEXAGON_V6_vpopcounth_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvvb,VI_ftype_VIVISI,3) +// tag : V6_vlutvvb +def int_hexagon_V6_vlutvvb : +Hexagon_v512v512v512i_Intrinsic<"HEXAGON_V6_vlutvvb">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvvb_128B,VI_ftype_VIVISI,3) +// tag : V6_vlutvvb_128B +def int_hexagon_V6_vlutvvb_128B : +Hexagon_v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvvb_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvvb_oracc,VI_ftype_VIVIVISI,4) +// tag : V6_vlutvvb_oracc +def int_hexagon_V6_vlutvvb_oracc : +Hexagon_v512v512v512v512i_Intrinsic<"HEXAGON_V6_vlutvvb_oracc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvvb_oracc_128B,VI_ftype_VIVIVISI,4) +// tag : V6_vlutvvb_oracc_128B +def int_hexagon_V6_vlutvvb_oracc_128B : +Hexagon_v1024v1024v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvvb_oracc_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvwh,VD_ftype_VIVISI,3) +// tag : V6_vlutvwh +def int_hexagon_V6_vlutvwh : +Hexagon_v1024v512v512i_Intrinsic<"HEXAGON_V6_vlutvwh">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvwh_128B,VD_ftype_VIVISI,3) +// tag : V6_vlutvwh_128B +def int_hexagon_V6_vlutvwh_128B : +Hexagon_v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvwh_128B">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvwh_oracc,VD_ftype_VDVIVISI,4) +// tag : V6_vlutvwh_oracc +def int_hexagon_V6_vlutvwh_oracc : +Hexagon_v1024v1024v512v512i_Intrinsic<"HEXAGON_V6_vlutvwh_oracc">; + +// +// BUILTIN_INFO(HEXAGON.V6_vlutvwh_oracc_128B,VD_ftype_VDVIVISI,4) +// tag : V6_vlutvwh_oracc_128B +def int_hexagon_V6_vlutvwh_oracc_128B : +Hexagon_v2048v2048v1024v1024i_Intrinsic<"HEXAGON_V6_vlutvwh_oracc_128B">; + +// +// BUILTIN_INFO(HEXAGON.M6_vabsdiffb,DI_ftype_DIDI,2) +// tag : M6_vabsdiffb +def int_hexagon_M6_vabsdiffb : +Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_M6_vabsdiffb">; + +// +// BUILTIN_INFO(HEXAGON.M6_vabsdiffub,DI_ftype_DIDI,2) +// tag : M6_vabsdiffub +def int_hexagon_M6_vabsdiffub : +Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_M6_vabsdiffub">; + +// +// BUILTIN_INFO(HEXAGON.S6_vsplatrbp,DI_ftype_SI,1) +// tag : S6_vsplatrbp +def int_hexagon_S6_vsplatrbp : +Hexagon_LLii_Intrinsic<"HEXAGON_S6_vsplatrbp">; + +// +// BUILTIN_INFO(HEXAGON.S6_vtrunehb_ppp,DI_ftype_DIDI,2) +// tag : S6_vtrunehb_ppp +def int_hexagon_S6_vtrunehb_ppp : +Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_S6_vtrunehb_ppp">; + +// +// BUILTIN_INFO(HEXAGON.S6_vtrunohb_ppp,DI_ftype_DIDI,2) +// tag : S6_vtrunohb_ppp +def int_hexagon_S6_vtrunohb_ppp : +Hexagon_LLiLLiLLi_Intrinsic<"HEXAGON_S6_vtrunohb_ppp">; diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index eb8f1e6cd079..06dfc329fe32 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -710,21 +710,39 @@ def int_ppc_vsx_xvrsqrtedp : GCCBuiltin<"__builtin_vsx_xvrsqrtedp">, def int_ppc_vsx_xvcmpeqdp : PowerPC_VSX_Intrinsic<"xvcmpeqdp", [llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpeqdp_p : GCCBuiltin<"__builtin_vsx_xvcmpeqdp_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2f64_ty,llvm_v2f64_ty], + [IntrNoMem]>; def int_ppc_vsx_xvcmpeqsp : PowerPC_VSX_Intrinsic<"xvcmpeqsp", [llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpeqsp_p : GCCBuiltin<"__builtin_vsx_xvcmpeqsp_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty], + [IntrNoMem]>; def int_ppc_vsx_xvcmpgedp : PowerPC_VSX_Intrinsic<"xvcmpgedp", [llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgedp_p : GCCBuiltin<"__builtin_vsx_xvcmpgedp_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2f64_ty,llvm_v2f64_ty], + [IntrNoMem]>; def int_ppc_vsx_xvcmpgesp : PowerPC_VSX_Intrinsic<"xvcmpgesp", [llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgesp_p : GCCBuiltin<"__builtin_vsx_xvcmpgesp_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty], + [IntrNoMem]>; def int_ppc_vsx_xvcmpgtdp : PowerPC_VSX_Intrinsic<"xvcmpgtdp", [llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgtdp_p : GCCBuiltin<"__builtin_vsx_xvcmpgtdp_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2f64_ty,llvm_v2f64_ty], + [IntrNoMem]>; def int_ppc_vsx_xvcmpgtsp : PowerPC_VSX_Intrinsic<"xvcmpgtsp", [llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgtsp_p : GCCBuiltin<"__builtin_vsx_xvcmpgtsp_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty], + [IntrNoMem]>; def int_ppc_vsx_xxleqv : PowerPC_VSX_Intrinsic<"xxleqv", [llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td index 3ccde4742384..3953aef43dad 100644 --- a/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -13,4 +13,10 @@ //===----------------------------------------------------------------------===// let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.". + +// Note that memory_size is not IntrNoMem because it must be sequenced with +// respect to grow_memory calls. +def int_wasm_memory_size : Intrinsic<[llvm_anyint_ty], [], [IntrReadMem]>; +def int_wasm_grow_memory : Intrinsic<[], [llvm_anyint_ty], []>; + } diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index a3bc4af84308..18390f853510 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -22,10 +22,8 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>; - // Restores the frame, base, and stack pointers as necessary after recovering - // from an exception. Any block resuming control flow in the parent function - // should call this before accessing any stack memory. - def int_x86_seh_restoreframe : Intrinsic<[], [], []>; + // Marks the EH registration node created in LLVM IR prior to code generation. + def int_x86_seh_ehregnode : Intrinsic<[], [llvm_ptr_ty], []>; // Given a pointer to the end of an EH registration object, returns the true // parent frame address that can be used with llvm.localrecover. @@ -1406,6 +1404,78 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vpermil_pd_128 : + GCCBuiltin<"__builtin_ia32_vpermilpd_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_i32_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermil_pd_256 : + GCCBuiltin<"__builtin_ia32_vpermilpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermil_pd_512 : + GCCBuiltin<"__builtin_ia32_vpermilpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermil_ps_128 : + GCCBuiltin<"__builtin_ia32_vpermilps_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermil_ps_256 : + GCCBuiltin<"__builtin_ia32_vpermilps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermil_ps_512 : + GCCBuiltin<"__builtin_ia32_vpermilps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermilvar_pd_256 : + GCCBuiltin<"__builtin_ia32_vpermilvarpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermilvar_pd_512 : + GCCBuiltin<"__builtin_ia32_vpermilvarpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermilvar_pd_128 : + GCCBuiltin<"__builtin_ia32_vpermilvarpd_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermilvar_ps_256 : + GCCBuiltin<"__builtin_ia32_vpermilvarps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermilvar_ps_512 : + GCCBuiltin<"__builtin_ia32_vpermilvarps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermilvar_ps_128 : + GCCBuiltin<"__builtin_ia32_vpermilvarps_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pshuf_b_128 : GCCBuiltin<"__builtin_ia32_pshufb128_mask">, Intrinsic<[llvm_v16i8_ty], @@ -1423,8 +1493,145 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>; -} + def int_x86_avx512_mask_shuf_f32x4_256 : + GCCBuiltin<"__builtin_ia32_shuf_f32x4_256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_f32x4 : + GCCBuiltin<"__builtin_ia32_shuf_f32x4_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_f64x2_256 : + GCCBuiltin<"__builtin_ia32_shuf_f64x2_256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_f64x2 : + GCCBuiltin<"__builtin_ia32_shuf_f64x2_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_i32x4_256 : + GCCBuiltin<"__builtin_ia32_shuf_i32x4_256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_i32x4 : + GCCBuiltin<"__builtin_ia32_shuf_i32x4_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_i64x2_256 : + GCCBuiltin<"__builtin_ia32_shuf_i64x2_256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_i64x2 : + GCCBuiltin<"__builtin_ia32_shuf_i64x2_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_pd_128 : + GCCBuiltin<"__builtin_ia32_shufpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_pd_256 : + GCCBuiltin<"__builtin_ia32_shufpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_pd_512 : + GCCBuiltin<"__builtin_ia32_shufpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_ps_128 : + GCCBuiltin<"__builtin_ia32_shufps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_ps_256 : + GCCBuiltin<"__builtin_ia32_shufps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_shuf_ps_512 : + GCCBuiltin<"__builtin_ia32_shufps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movshdup_128 : + GCCBuiltin<"__builtin_ia32_movshdup128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movshdup_256 : + GCCBuiltin<"__builtin_ia32_movshdup256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movshdup_512 : + GCCBuiltin<"__builtin_ia32_movshdup512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movsldup_128 : + GCCBuiltin<"__builtin_ia32_movsldup128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movsldup_256 : + GCCBuiltin<"__builtin_ia32_movsldup256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movsldup_512 : + GCCBuiltin<"__builtin_ia32_movsldup512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movddup_128 : + GCCBuiltin<"__builtin_ia32_movddup128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movddup_256 : + GCCBuiltin<"__builtin_ia32_movddup256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_movddup_512 : + GCCBuiltin<"__builtin_ia32_movddup512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; +} // Vector blend let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". @@ -1526,6 +1733,38 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_mask_ptestm_q_512 : GCCBuiltin<"__builtin_ia32_ptestmq512">, Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_pd_128 : + GCCBuiltin<"__builtin_ia32_fpclasspd128_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_pd_256 : + GCCBuiltin<"__builtin_ia32_fpclasspd256_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v4f64_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_pd_512 : + GCCBuiltin<"__builtin_ia32_fpclasspd512_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_ps_128 : + GCCBuiltin<"__builtin_ia32_fpclassps128_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_ps_256 : + GCCBuiltin<"__builtin_ia32_fpclassps256_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v8f32_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_ps_512 : + GCCBuiltin<"__builtin_ia32_fpclassps512_mask">, + Intrinsic<[llvm_i16_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_sd : + GCCBuiltin<"__builtin_ia32_fpclasssd">, + Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_fpclass_ss : + GCCBuiltin<"__builtin_ia32_fpclassss">, + Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i8_ty], + [IntrNoMem]>; } // Vector extract sign mask @@ -1573,16 +1812,16 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Conditional load ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_maskload_pd : GCCBuiltin<"__builtin_ia32_maskloadpd">, - Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty, llvm_v2f64_ty], + Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty, llvm_v2i64_ty], [IntrReadArgMem]>; def int_x86_avx_maskload_ps : GCCBuiltin<"__builtin_ia32_maskloadps">, - Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty, llvm_v4f32_ty], + Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty, llvm_v4i32_ty], [IntrReadArgMem]>; def int_x86_avx_maskload_pd_256 : GCCBuiltin<"__builtin_ia32_maskloadpd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty, llvm_v4f64_ty], + Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty, llvm_v4i64_ty], [IntrReadArgMem]>; def int_x86_avx_maskload_ps_256 : GCCBuiltin<"__builtin_ia32_maskloadps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8f32_ty], + Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8i32_ty], [IntrReadArgMem]>; def int_x86_avx512_mask_loadu_ps_512 : GCCBuiltin<"__builtin_ia32_loadups512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty], @@ -1596,24 +1835,31 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_mask_load_pd_512 : GCCBuiltin<"__builtin_ia32_loadapd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrReadArgMem]>; + + def int_x86_avx512_mask_move_ss : GCCBuiltin<"__builtin_ia32_movss_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_move_sd : GCCBuiltin<"__builtin_ia32_movsd_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; } // Conditional store ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_maskstore_pd : GCCBuiltin<"__builtin_ia32_maskstorepd">, Intrinsic<[], [llvm_ptr_ty, - llvm_v2f64_ty, llvm_v2f64_ty], [IntrReadWriteArgMem]>; + llvm_v2i64_ty, llvm_v2f64_ty], [IntrReadWriteArgMem]>; def int_x86_avx_maskstore_ps : GCCBuiltin<"__builtin_ia32_maskstoreps">, Intrinsic<[], [llvm_ptr_ty, - llvm_v4f32_ty, llvm_v4f32_ty], [IntrReadWriteArgMem]>; + llvm_v4i32_ty, llvm_v4f32_ty], [IntrReadWriteArgMem]>; def int_x86_avx_maskstore_pd_256 : GCCBuiltin<"__builtin_ia32_maskstorepd256">, Intrinsic<[], [llvm_ptr_ty, - llvm_v4f64_ty, llvm_v4f64_ty], [IntrReadWriteArgMem]>; + llvm_v4i64_ty, llvm_v4f64_ty], [IntrReadWriteArgMem]>; def int_x86_avx_maskstore_ps_256 : GCCBuiltin<"__builtin_ia32_maskstoreps256">, Intrinsic<[], [llvm_ptr_ty, - llvm_v8f32_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>; + llvm_v8i32_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>; def int_x86_avx512_mask_storeu_ps_512 : GCCBuiltin<"__builtin_ia32_storeups512_mask">, Intrinsic<[], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty], @@ -1946,6 +2192,25 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_i32_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psrl_w_128 : GCCBuiltin<"__builtin_ia32_psrlw128_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, + llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psrl_w_256 : GCCBuiltin<"__builtin_ia32_psrlw256_mask">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, + llvm_v8i16_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psrl_w_512 : GCCBuiltin<"__builtin_ia32_psrlw512_mask">, + Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, + llvm_v8i16_ty, llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psrl_wi_128 : GCCBuiltin<"__builtin_ia32_psrlwi128_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, + llvm_i8_ty, llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psrl_wi_256 : GCCBuiltin<"__builtin_ia32_psrlwi256_mask">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, + llvm_i8_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psrl_wi_512 : GCCBuiltin<"__builtin_ia32_psrlwi512_mask">, + Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, + llvm_i8_ty, llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_psll_d : GCCBuiltin<"__builtin_ia32_pslld512_mask">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v4i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; @@ -2167,39 +2432,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Vector load with broadcast let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx2_vbroadcast_ss_ps : - GCCBuiltin<"__builtin_ia32_vbroadcastss_ps">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_avx2_vbroadcast_sd_pd_256 : - GCCBuiltin<"__builtin_ia32_vbroadcastsd_pd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_avx2_vbroadcast_ss_ps_256 : - GCCBuiltin<"__builtin_ia32_vbroadcastss_ps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastb_128 : - GCCBuiltin<"__builtin_ia32_pbroadcastb128">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastb_256 : - GCCBuiltin<"__builtin_ia32_pbroadcastb256">, - Intrinsic<[llvm_v32i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastw_128 : - GCCBuiltin<"__builtin_ia32_pbroadcastw128">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastw_256 : - GCCBuiltin<"__builtin_ia32_pbroadcastw256">, - Intrinsic<[llvm_v16i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastd_128 : - GCCBuiltin<"__builtin_ia32_pbroadcastd128">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastd_256 : - GCCBuiltin<"__builtin_ia32_pbroadcastd256">, - Intrinsic<[llvm_v8i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastq_128 : - GCCBuiltin<"__builtin_ia32_pbroadcastq128">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; - def int_x86_avx2_pbroadcastq_256 : - GCCBuiltin<"__builtin_ia32_pbroadcastq256">, - Intrinsic<[llvm_v4i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; def int_x86_avx512_mask_pbroadcast_d_gpr_512 : GCCBuiltin<"__builtin_ia32_pbroadcastd512_gpr_mask">, Intrinsic<[llvm_v16i32_ty], [llvm_i32_ty, llvm_v16i32_ty, @@ -2220,7 +2452,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; def int_x86_avx2_permps : GCCBuiltin<"__builtin_ia32_permvarsf256">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8i32_ty], [IntrNoMem]>; def int_x86_avx2_vperm2i128 : GCCBuiltin<"__builtin_ia32_permti256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, @@ -2231,20 +2463,124 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_mask_vextractf32x4_512 : GCCBuiltin<"__builtin_ia32_extractf32x4_mask">, - Intrinsic<[llvm_v4f32_ty], [llvm_v16f32_ty, llvm_i8_ty, - llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4f32_ty], [llvm_v16f32_ty, llvm_i32_ty, + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_vextracti32x4_512 : GCCBuiltin<"__builtin_ia32_extracti32x4_mask">, - Intrinsic<[llvm_v4i32_ty], [llvm_v16i32_ty, llvm_i8_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v16i32_ty, llvm_i32_ty, + llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextractf32x4_256 : + GCCBuiltin<"__builtin_ia32_extractf32x4_256_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i32_ty, + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextracti32x4_256 : + GCCBuiltin<"__builtin_ia32_extracti32x4_256_mask">, + Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i32_ty, + llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextractf64x2_256 : + GCCBuiltin<"__builtin_ia32_extractf64x2_256_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i32_ty, + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextracti64x2_256 : + GCCBuiltin<"__builtin_ia32_extracti64x2_256_mask">, + Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty, llvm_i32_ty, + llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextractf64x2_512 : + GCCBuiltin<"__builtin_ia32_extractf64x2_512_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v8f64_ty, llvm_i32_ty, + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextracti64x2_512 : + GCCBuiltin<"__builtin_ia32_extracti64x2_512_mask">, + Intrinsic<[llvm_v2i64_ty], [llvm_v8i64_ty, llvm_i32_ty, + llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextractf32x8_512 : + GCCBuiltin<"__builtin_ia32_extractf32x8_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v16f32_ty, llvm_i32_ty, + llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vextracti32x8_512 : + GCCBuiltin<"__builtin_ia32_extracti32x8_mask">, + Intrinsic<[llvm_v8i32_ty],[llvm_v16i32_ty, llvm_i32_ty, + llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_vextractf64x4_512 : GCCBuiltin<"__builtin_ia32_extractf64x4_mask">, - Intrinsic<[llvm_v4f64_ty], [llvm_v8f64_ty, llvm_i8_ty, - llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4f64_ty], [llvm_v8f64_ty, llvm_i32_ty, + llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_vextracti64x4_512 : GCCBuiltin<"__builtin_ia32_extracti64x4_mask">, - Intrinsic<[llvm_v4i64_ty], [llvm_v8i64_ty, llvm_i8_ty, - llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i64_ty], [llvm_v8i64_ty, llvm_i32_ty, + llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_insertf32x4_256 : + GCCBuiltin<"__builtin_ia32_insertf32x4_256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_insertf32x4_512 : + GCCBuiltin<"__builtin_ia32_insertf32x4_512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_insertf32x8_512 : + GCCBuiltin<"__builtin_ia32_insertf32x8_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v8f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_insertf64x2_256 : + GCCBuiltin<"__builtin_ia32_insertf64x2_256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_insertf64x2_512 : + GCCBuiltin<"__builtin_ia32_insertf64x2_512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_insertf64x4_512 : + GCCBuiltin<"__builtin_ia32_insertf64x4_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v4f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_inserti32x4_256 : + GCCBuiltin<"__builtin_ia32_inserti32x4_256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_inserti32x4_512 : + GCCBuiltin<"__builtin_ia32_inserti32x4_512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_v16i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_inserti32x8_512 : + GCCBuiltin<"__builtin_ia32_inserti32x8_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_inserti64x2_256 : + GCCBuiltin<"__builtin_ia32_inserti64x2_256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_inserti64x2_512 : + GCCBuiltin<"__builtin_ia32_inserti64x2_512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_inserti64x4_512 : + GCCBuiltin<"__builtin_ia32_inserti64x4_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; } // Conditional load ops @@ -2354,6 +2690,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_psll_dq_512 : GCCBuiltin<"__builtin_ia32_pslldq512">, + Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_psrl_dq_512 : GCCBuiltin<"__builtin_ia32_psrldq512">, + Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_i32_ty], + [IntrNoMem]>; } // Gather ops @@ -3545,6 +3887,43 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". } //===----------------------------------------------------------------------===// +// XSAVE +let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + def int_x86_xsave : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsave64 : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xrstor : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xrstor64 : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsaveopt : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsaveopt64 : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xrstors : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xrstors64 : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsavec : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsavec64 : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsaves : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_xsaves64 : + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], []>; +} + +//===----------------------------------------------------------------------===// +// Support protection key +let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + def int_x86_rdpkru : GCCBuiltin <"__builtin_ia32_rdpkru">, + Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + def int_x86_wrpkru : GCCBuiltin<"__builtin_ia32_wrpkru">, + Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>; +} +//===----------------------------------------------------------------------===// // Half float conversion let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". @@ -3561,9 +3940,21 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_mask_vcvtph2ps_512 : GCCBuiltin<"__builtin_ia32_vcvtph2ps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16i16_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vcvtph2ps_256 : GCCBuiltin<"__builtin_ia32_vcvtph2ps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vcvtph2ps_128 : GCCBuiltin<"__builtin_ia32_vcvtph2ps_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_vcvtps2ph_512 : GCCBuiltin<"__builtin_ia32_vcvtps2ph512_mask">, Intrinsic<[llvm_v16i16_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty, + llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty, + llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; } //===----------------------------------------------------------------------===// @@ -3657,6 +4048,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_kunpck_bw : GCCBuiltin<"__builtin_ia32_kunpckhi">, Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_kunpck_wd : GCCBuiltin<"__builtin_ia32_kunpcksi">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_kunpck_dq : GCCBuiltin<"__builtin_ia32_kunpckdi">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], + [IntrNoMem]>; def int_x86_avx512_kortestz_w : GCCBuiltin<"__builtin_ia32_kortestzhi">, Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty], [IntrNoMem]>; @@ -3671,10 +4068,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; def int_x86_avx512_cvtss2usi64 : GCCBuiltin<"__builtin_ia32_cvtss2usi64">, Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_avx512_cvttss2usi : GCCBuiltin<"__builtin_ia32_cvttss2usi">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_avx512_cvttss2usi64 : GCCBuiltin<"__builtin_ia32_cvttss2usi64">, - Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttss2si : GCCBuiltin<"__builtin_ia32_vcvttss2si32">, + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttss2si64 : GCCBuiltin<"__builtin_ia32_vcvttss2si64">, + Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttss2usi : GCCBuiltin<"__builtin_ia32_vcvttss2usi32">, + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttss2usi64 : GCCBuiltin<"__builtin_ia32_vcvttss2usi64">, + Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtusi2ss : GCCBuiltin<"__builtin_ia32_cvtusi2ss32">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; @@ -3686,10 +4087,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>; def int_x86_avx512_cvtsd2usi64 : GCCBuiltin<"__builtin_ia32_cvtsd2usi64">, Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_avx512_cvttsd2usi : GCCBuiltin<"__builtin_ia32_cvttsd2usi">, - Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_avx512_cvttsd2usi64 : GCCBuiltin<"__builtin_ia32_cvttsd2usi64">, - Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + def int_x86_avx512_cvttsd2si : GCCBuiltin<"__builtin_ia32_vcvttsd2si32">, + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttsd2si64 : GCCBuiltin<"__builtin_ia32_vcvttsd2si64">, + Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttsd2usi : GCCBuiltin<"__builtin_ia32_vcvttsd2usi32">, + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvttsd2usi64 : GCCBuiltin<"__builtin_ia32_vcvttsd2usi64">, + Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtusi2sd : GCCBuiltin<"__builtin_ia32_cvtusi2sd32">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; @@ -3698,17 +4103,74 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtsi2ss32 : GCCBuiltin<"__builtin_ia32_cvtsi2ss32">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtsi2ss64 : GCCBuiltin<"__builtin_ia32_cvtsi2ss64">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, + llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtsi2sd32 : GCCBuiltin<"__builtin_ia32_cvtsi2sd32">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, + llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtsi2sd64 : GCCBuiltin<"__builtin_ia32_cvtsi2sd64">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, + llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtb2mask_128 : GCCBuiltin<"__builtin_ia32_cvtb2mask128">, + Intrinsic<[llvm_i16_ty], [llvm_v16i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtb2mask_256 : GCCBuiltin<"__builtin_ia32_cvtb2mask256">, + Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtb2mask_512 : GCCBuiltin<"__builtin_ia32_cvtb2mask512">, + Intrinsic<[llvm_i64_ty], [llvm_v64i8_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtw2mask_128 : GCCBuiltin<"__builtin_ia32_cvtw2mask128">, + Intrinsic<[llvm_i8_ty], [llvm_v8i16_ty], [IntrNoMem]>; + def int_x86_avx512_cvtw2mask_256 : GCCBuiltin<"__builtin_ia32_cvtw2mask256">, + Intrinsic<[llvm_i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; + def int_x86_avx512_cvtw2mask_512 : GCCBuiltin<"__builtin_ia32_cvtw2mask512">, + Intrinsic<[llvm_i32_ty], [llvm_v32i16_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtd2mask_128 : GCCBuiltin<"__builtin_ia32_cvtd2mask128">, + Intrinsic<[llvm_i8_ty], [llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvtd2mask_256 : GCCBuiltin<"__builtin_ia32_cvtd2mask256">, + Intrinsic<[llvm_i8_ty], [llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvtd2mask_512 : GCCBuiltin<"__builtin_ia32_cvtd2mask512">, + Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtq2mask_128 : GCCBuiltin<"__builtin_ia32_cvtq2mask128">, + Intrinsic<[llvm_i8_ty], [llvm_v2i64_ty], [IntrNoMem]>; + def int_x86_avx512_cvtq2mask_256 : GCCBuiltin<"__builtin_ia32_cvtq2mask256">, + Intrinsic<[llvm_i8_ty], [llvm_v4i64_ty], [IntrNoMem]>; + def int_x86_avx512_cvtq2mask_512 : GCCBuiltin<"__builtin_ia32_cvtq2mask512">, + Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtmask2b_128 : GCCBuiltin<"__builtin_ia32_cvtmask2b128">, + Intrinsic<[llvm_v16i8_ty], [llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2b_256 : GCCBuiltin<"__builtin_ia32_cvtmask2b256">, + Intrinsic<[llvm_v32i8_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2b_512 : GCCBuiltin<"__builtin_ia32_cvtmask2b512">, + Intrinsic<[llvm_v64i8_ty], [llvm_i64_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtmask2w_128 : GCCBuiltin<"__builtin_ia32_cvtmask2w128">, + Intrinsic<[llvm_v8i16_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2w_256 : GCCBuiltin<"__builtin_ia32_cvtmask2w256">, + Intrinsic<[llvm_v16i16_ty], [llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2w_512 : GCCBuiltin<"__builtin_ia32_cvtmask2w512">, + Intrinsic<[llvm_v32i16_ty], [llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtmask2d_128 : GCCBuiltin<"__builtin_ia32_cvtmask2d128">, + Intrinsic<[llvm_v4i32_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2d_256 : GCCBuiltin<"__builtin_ia32_cvtmask2d256">, + Intrinsic<[llvm_v8i32_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2d_512 : GCCBuiltin<"__builtin_ia32_cvtmask2d512">, + Intrinsic<[llvm_v16i32_ty], [llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_cvtmask2q_128 : GCCBuiltin<"__builtin_ia32_cvtmask2q128">, + Intrinsic<[llvm_v2i64_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2q_256 : GCCBuiltin<"__builtin_ia32_cvtmask2q256">, + Intrinsic<[llvm_v4i64_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_cvtmask2q_512 : GCCBuiltin<"__builtin_ia32_cvtmask2q512">, + Intrinsic<[llvm_v8i64_ty], [llvm_i8_ty], [IntrNoMem]>; + } // Pack ops. @@ -3751,53 +4213,761 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; } +// Unpack ops. +let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + def int_x86_avx512_mask_unpckh_pd_128 : + GCCBuiltin<"__builtin_ia32_unpckhpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckh_pd_256 : + GCCBuiltin<"__builtin_ia32_unpckhpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckh_pd_512 : + GCCBuiltin<"__builtin_ia32_unpckhpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckh_ps_128 : + GCCBuiltin<"__builtin_ia32_unpckhps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckh_ps_256 : + GCCBuiltin<"__builtin_ia32_unpckhps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckh_ps_512 : + GCCBuiltin<"__builtin_ia32_unpckhps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckl_pd_128 : + GCCBuiltin<"__builtin_ia32_unpcklpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckl_pd_256 : + GCCBuiltin<"__builtin_ia32_unpcklpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckl_pd_512 : + GCCBuiltin<"__builtin_ia32_unpcklpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckl_ps_128 : + GCCBuiltin<"__builtin_ia32_unpcklps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckl_ps_256 : + GCCBuiltin<"__builtin_ia32_unpcklps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_unpckl_ps_512 : + GCCBuiltin<"__builtin_ia32_unpcklps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhb_w_128 : + GCCBuiltin<"__builtin_ia32_punpckhbw128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhb_w_256 : + GCCBuiltin<"__builtin_ia32_punpckhbw256_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhb_w_512 : + GCCBuiltin<"__builtin_ia32_punpckhbw512_mask">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhd_q_128 : + GCCBuiltin<"__builtin_ia32_punpckhdq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhd_q_256 : + GCCBuiltin<"__builtin_ia32_punpckhdq256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhd_q_512 : + GCCBuiltin<"__builtin_ia32_punpckhdq512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhqd_q_128 : + GCCBuiltin<"__builtin_ia32_punpckhqdq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhqd_q_256 : + GCCBuiltin<"__builtin_ia32_punpckhqdq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhqd_q_512 : + GCCBuiltin<"__builtin_ia32_punpckhqdq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhw_d_128 : + GCCBuiltin<"__builtin_ia32_punpckhwd128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhw_d_256 : + GCCBuiltin<"__builtin_ia32_punpckhwd256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckhw_d_512 : + GCCBuiltin<"__builtin_ia32_punpckhwd512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklb_w_128 : + GCCBuiltin<"__builtin_ia32_punpcklbw128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklb_w_256 : + GCCBuiltin<"__builtin_ia32_punpcklbw256_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklb_w_512 : + GCCBuiltin<"__builtin_ia32_punpcklbw512_mask">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckld_q_128 : + GCCBuiltin<"__builtin_ia32_punpckldq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckld_q_256 : + GCCBuiltin<"__builtin_ia32_punpckldq256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpckld_q_512 : + GCCBuiltin<"__builtin_ia32_punpckldq512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklqd_q_128 : + GCCBuiltin<"__builtin_ia32_punpcklqdq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklqd_q_256 : + GCCBuiltin<"__builtin_ia32_punpcklqdq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklqd_q_512 : + GCCBuiltin<"__builtin_ia32_punpcklqdq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklw_d_128 : + GCCBuiltin<"__builtin_ia32_punpcklwd128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklw_d_256 : + GCCBuiltin<"__builtin_ia32_punpcklwd256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_punpcklw_d_512 : + GCCBuiltin<"__builtin_ia32_punpcklwd512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; +} + // Vector convert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx512_mask_cvttps2dq_512: GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvttps2udq_512: GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvttpd2dq_512: GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvttpd2udq_512: GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_rndscale_ps_512: GCCBuiltin<"__builtin_ia32_rndscaleps_mask">, + def int_x86_avx512_mask_cvtdq2pd_128 : + GCCBuiltin<"__builtin_ia32_cvtdq2pd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtdq2pd_256 : + GCCBuiltin<"__builtin_ia32_cvtdq2pd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtdq2pd_512 : + GCCBuiltin<"__builtin_ia32_cvtdq2pd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtdq2ps_128 : + GCCBuiltin<"__builtin_ia32_cvtdq2ps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtdq2ps_256 : + GCCBuiltin<"__builtin_ia32_cvtdq2ps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtdq2ps_512 : + GCCBuiltin<"__builtin_ia32_cvtdq2ps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2dq_128 : + GCCBuiltin<"__builtin_ia32_cvtpd2dq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2dq_256 : + GCCBuiltin<"__builtin_ia32_cvtpd2dq256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2dq_512 : + GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2ps_256 : + GCCBuiltin<"__builtin_ia32_cvtpd2ps256_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f64_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2ps_512 : + GCCBuiltin<"__builtin_ia32_cvtpd2ps512_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f64_ty, llvm_v8f32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtsd2ss_round : + GCCBuiltin<"__builtin_ia32_cvtsd2ss_round">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtss2sd_round : + GCCBuiltin<"__builtin_ia32_cvtss2sd_round">, + Intrinsic<[llvm_v2f64_ty], + [ llvm_v4f32_ty, llvm_v4f32_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2ps : + GCCBuiltin<"__builtin_ia32_cvtpd2ps_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v2f64_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2qq_128 : + GCCBuiltin<"__builtin_ia32_cvtpd2qq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2qq_256 : + GCCBuiltin<"__builtin_ia32_cvtpd2qq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2qq_512 : + GCCBuiltin<"__builtin_ia32_cvtpd2qq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2udq_128 : + GCCBuiltin<"__builtin_ia32_cvtpd2udq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2udq_256 : + GCCBuiltin<"__builtin_ia32_cvtpd2udq256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2udq_512 : + GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2uqq_128 : + GCCBuiltin<"__builtin_ia32_cvtpd2uqq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2uqq_256 : + GCCBuiltin<"__builtin_ia32_cvtpd2uqq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtpd2uqq_512 : + GCCBuiltin<"__builtin_ia32_cvtpd2uqq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2dq_128 : + GCCBuiltin<"__builtin_ia32_cvtps2dq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2dq_256 : + GCCBuiltin<"__builtin_ia32_cvtps2dq256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2dq_512 : + GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2pd_128 : + GCCBuiltin<"__builtin_ia32_cvtps2pd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v4f32_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2pd_256 : + GCCBuiltin<"__builtin_ia32_cvtps2pd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2pd_512 : + GCCBuiltin<"__builtin_ia32_cvtps2pd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f32_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2qq_128 : + GCCBuiltin<"__builtin_ia32_cvtps2qq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v4f32_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2qq_256 : + GCCBuiltin<"__builtin_ia32_cvtps2qq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f32_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2qq_512 : + GCCBuiltin<"__builtin_ia32_cvtps2qq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2udq_128 : + GCCBuiltin<"__builtin_ia32_cvtps2udq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2udq_256 : + GCCBuiltin<"__builtin_ia32_cvtps2udq256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2udq_512 : + GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2uqq_128 : + GCCBuiltin<"__builtin_ia32_cvtps2uqq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v4f32_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2uqq_256 : + GCCBuiltin<"__builtin_ia32_cvtps2uqq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f32_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtps2uqq_512 : + GCCBuiltin<"__builtin_ia32_cvtps2uqq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtqq2pd_128 : + GCCBuiltin<"__builtin_ia32_cvtqq2pd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtqq2pd_256 : + GCCBuiltin<"__builtin_ia32_cvtqq2pd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtqq2pd_512 : + GCCBuiltin<"__builtin_ia32_cvtqq2pd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtqq2ps_128 : + GCCBuiltin<"__builtin_ia32_cvtqq2ps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtqq2ps_256 : + GCCBuiltin<"__builtin_ia32_cvtqq2ps256_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtqq2ps_512 : + GCCBuiltin<"__builtin_ia32_cvtqq2ps512_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8i64_ty, llvm_v8f32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2dq_128 : + GCCBuiltin<"__builtin_ia32_cvttpd2dq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2dq_256 : + GCCBuiltin<"__builtin_ia32_cvttpd2dq256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2dq_512 : + GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2qq_128 : + GCCBuiltin<"__builtin_ia32_cvttpd2qq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2qq_256 : + GCCBuiltin<"__builtin_ia32_cvttpd2qq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2qq_512 : + GCCBuiltin<"__builtin_ia32_cvttpd2qq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2udq_128 : + GCCBuiltin<"__builtin_ia32_cvttpd2udq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2udq_256 : + GCCBuiltin<"__builtin_ia32_cvttpd2udq256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2udq_512 : + GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2uqq_128 : + GCCBuiltin<"__builtin_ia32_cvttpd2uqq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2uqq_256 : + GCCBuiltin<"__builtin_ia32_cvttpd2uqq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttpd2uqq_512 : + GCCBuiltin<"__builtin_ia32_cvttpd2uqq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2dq_128 : + GCCBuiltin<"__builtin_ia32_cvttps2dq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2dq_256 : + GCCBuiltin<"__builtin_ia32_cvttps2dq256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2dq_512 : + GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2qq_128 : + GCCBuiltin<"__builtin_ia32_cvttps2qq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v4f32_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2qq_256 : + GCCBuiltin<"__builtin_ia32_cvttps2qq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f32_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2qq_512 : + GCCBuiltin<"__builtin_ia32_cvttps2qq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2udq_128 : + GCCBuiltin<"__builtin_ia32_cvttps2udq128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2udq_256 : + GCCBuiltin<"__builtin_ia32_cvttps2udq256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2udq_512 : + GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2uqq_128 : + GCCBuiltin<"__builtin_ia32_cvttps2uqq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v4f32_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2uqq_256 : + GCCBuiltin<"__builtin_ia32_cvttps2uqq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4f32_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvttps2uqq_512 : + GCCBuiltin<"__builtin_ia32_cvttps2uqq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtudq2pd_128 : + GCCBuiltin<"__builtin_ia32_cvtudq2pd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtudq2pd_256 : + GCCBuiltin<"__builtin_ia32_cvtudq2pd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtudq2pd_512 : + GCCBuiltin<"__builtin_ia32_cvtudq2pd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8i32_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtudq2ps_128 : + GCCBuiltin<"__builtin_ia32_cvtudq2ps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtudq2ps_256 : + GCCBuiltin<"__builtin_ia32_cvtudq2ps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtudq2ps_512 : + GCCBuiltin<"__builtin_ia32_cvtudq2ps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtuqq2pd_128 : + GCCBuiltin<"__builtin_ia32_cvtuqq2pd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtuqq2pd_256 : + GCCBuiltin<"__builtin_ia32_cvtuqq2pd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtuqq2pd_512 : + GCCBuiltin<"__builtin_ia32_cvtuqq2pd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtuqq2ps_128 : + GCCBuiltin<"__builtin_ia32_cvtuqq2ps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtuqq2ps_256 : + GCCBuiltin<"__builtin_ia32_cvtuqq2ps256_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_cvtuqq2ps_512 : + GCCBuiltin<"__builtin_ia32_cvtuqq2ps512_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8i64_ty, llvm_v8f32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_rndscale_pd_128 : GCCBuiltin<"__builtin_ia32_rndscalepd_128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i32_ty, + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_rndscale_pd_256 : GCCBuiltin<"__builtin_ia32_rndscalepd_256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i32_ty, + llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_rndscale_pd_512 : GCCBuiltin<"__builtin_ia32_rndscalepd_mask">, + Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_rndscale_ps_128 : GCCBuiltin<"__builtin_ia32_rndscaleps_128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_rndscale_ps_256 : GCCBuiltin<"__builtin_ia32_rndscaleps_256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i32_ty, + llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_rndscale_ps_512 : GCCBuiltin<"__builtin_ia32_rndscaleps_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_rndscale_pd_512: GCCBuiltin<"__builtin_ia32_rndscalepd_mask">, + def int_x86_avx512_mask_reduce_pd_128 : GCCBuiltin<"__builtin_ia32_reducepd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i32_ty, + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_reduce_pd_256 : GCCBuiltin<"__builtin_ia32_reducepd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i32_ty, + llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_reduce_pd_512 : GCCBuiltin<"__builtin_ia32_reducepd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtps2dq_512: GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2dq_512: GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtps2udq_512: GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2udq_512: GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtdq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512_mask">, - Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtdq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtdq2pd512_mask">, - Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtudq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtudq2ps512_mask">, - Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty, + def int_x86_avx512_mask_reduce_ps_128 : GCCBuiltin<"__builtin_ia32_reduceps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_reduce_ps_256 : GCCBuiltin<"__builtin_ia32_reduceps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i32_ty, + llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_reduce_ps_512 : GCCBuiltin<"__builtin_ia32_reduceps512_mask">, + Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtudq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtudq2pd512_mask">, - Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2ps_512 : GCCBuiltin<"__builtin_ia32_cvtpd2ps512_mask">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8f64_ty, llvm_v8f32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; +def int_x86_avx512_mask_range_pd_128 : GCCBuiltin<"__builtin_ia32_rangepd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty, + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; +def int_x86_avx512_mask_range_pd_256 : GCCBuiltin<"__builtin_ia32_rangepd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_i32_ty, + llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; +def int_x86_avx512_mask_range_pd_512 : GCCBuiltin<"__builtin_ia32_rangepd512_mask">, + Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty, + llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; +def int_x86_avx512_mask_range_ps_128 : GCCBuiltin<"__builtin_ia32_rangeps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; +def int_x86_avx512_mask_range_ps_256 : GCCBuiltin<"__builtin_ia32_rangeps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_i32_ty, + llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; +def int_x86_avx512_mask_range_ps_512 : GCCBuiltin<"__builtin_ia32_rangeps512_mask">, + Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty, + llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; } // Vector load with broadcast @@ -3805,28 +4975,183 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_vbroadcast_ss_512 : GCCBuiltin<"__builtin_ia32_vbroadcastss512">, Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; - def int_x86_avx512_vbroadcast_ss_ps_512 : - GCCBuiltin<"__builtin_ia32_vbroadcastss_ps512">, - Intrinsic<[llvm_v16f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_broadcast_ss_ps_512 : + GCCBuiltin<"__builtin_ia32_broadcastss512">, + Intrinsic<[llvm_v16f32_ty], [llvm_v4f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_broadcast_ss_ps_256 : + GCCBuiltin<"__builtin_ia32_broadcastss256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_broadcast_ss_ps_128 : + GCCBuiltin<"__builtin_ia32_broadcastss128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_vbroadcast_sd_512 : GCCBuiltin<"__builtin_ia32_vbroadcastsd512">, Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>; - def int_x86_avx512_vbroadcast_sd_pd_512 : - GCCBuiltin<"__builtin_ia32_vbroadcastsd_pd512">, - Intrinsic<[llvm_v8f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + def int_x86_avx512_mask_broadcast_sd_pd_512 : + GCCBuiltin<"__builtin_ia32_broadcastsd512">, + Intrinsic<[llvm_v8f64_ty], [llvm_v2f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_broadcast_sd_pd_256 : + GCCBuiltin<"__builtin_ia32_broadcastsd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v2f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastb_128 : + GCCBuiltin<"__builtin_ia32_pbroadcastb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastb_256 : + GCCBuiltin<"__builtin_ia32_pbroadcastb256_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v16i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastb_512 : + GCCBuiltin<"__builtin_ia32_pbroadcastb512_mask">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v16i8_ty, llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastw_128 : + GCCBuiltin<"__builtin_ia32_pbroadcastw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastw_256 : + GCCBuiltin<"__builtin_ia32_pbroadcastw256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v8i16_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastw_512 : + GCCBuiltin<"__builtin_ia32_pbroadcastw512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v8i16_ty, llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastd_128 : + GCCBuiltin<"__builtin_ia32_pbroadcastd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastd_256 : + GCCBuiltin<"__builtin_ia32_pbroadcastd256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v4i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_pbroadcastd_512 : - GCCBuiltin<"__builtin_ia32_pbroadcastd512">, - Intrinsic<[llvm_v16i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; + GCCBuiltin<"__builtin_ia32_pbroadcastd512">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v4i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastq_128 : + GCCBuiltin<"__builtin_ia32_pbroadcastq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastq_256 : + GCCBuiltin<"__builtin_ia32_pbroadcastq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v2i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastq_512 : + GCCBuiltin<"__builtin_ia32_pbroadcastq512">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v2i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf32x2_256 : + GCCBuiltin<"__builtin_ia32_broadcastf32x2_256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v4f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf32x2_512 : + GCCBuiltin<"__builtin_ia32_broadcastf32x2_512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v4f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti32x2_128 : + GCCBuiltin<"__builtin_ia32_broadcasti32x2_128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti32x2_256 : + GCCBuiltin<"__builtin_ia32_broadcasti32x2_256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v4i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti32x2_512 : + GCCBuiltin<"__builtin_ia32_broadcasti32x2_512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v4i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf32x4_256 : + GCCBuiltin<"__builtin_ia32_broadcastf32x4_256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v4f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf32x4_512 : + GCCBuiltin<"__builtin_ia32_broadcastf32x4_512">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v4f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf32x8_512 : + GCCBuiltin<"__builtin_ia32_broadcastf32x8_512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v8f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf64x2_256 : + GCCBuiltin<"__builtin_ia32_broadcastf64x2_256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v2f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf64x2_512 : + GCCBuiltin<"__builtin_ia32_broadcastf64x2_512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v2f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcastf64x4_512 : + GCCBuiltin<"__builtin_ia32_broadcastf64x4_512">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v4f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti32x4_256 : + GCCBuiltin<"__builtin_ia32_broadcasti32x4_256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v4i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti32x4_512 : + GCCBuiltin<"__builtin_ia32_broadcasti32x4_512">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v4i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti32x8_512 : + GCCBuiltin<"__builtin_ia32_broadcasti32x8_512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v8i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti64x2_256 : + GCCBuiltin<"__builtin_ia32_broadcasti64x2_256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v2i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti64x2_512 : + GCCBuiltin<"__builtin_ia32_broadcasti64x2_512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v2i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_broadcasti64x4_512 : + GCCBuiltin<"__builtin_ia32_broadcasti64x4_512">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v4i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_pbroadcastd_i32_512 : Intrinsic<[llvm_v16i32_ty], [llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_pbroadcastq_512 : - GCCBuiltin<"__builtin_ia32_pbroadcastq512">, - Intrinsic<[llvm_v8i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; def int_x86_avx512_pbroadcastq_i64_512 : Intrinsic<[llvm_v8i64_ty], [llvm_i64_ty], [IntrNoMem]>; + def int_x86_avx512_broadcastmw_512 : + GCCBuiltin<"__builtin_ia32_broadcastmw512">, + Intrinsic<[llvm_v16i32_ty], [llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_broadcastmw_256 : + GCCBuiltin<"__builtin_ia32_broadcastmw256">, + Intrinsic<[llvm_v8i32_ty], [llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_broadcastmw_128 : + GCCBuiltin<"__builtin_ia32_broadcastmw128">, + Intrinsic<[llvm_v4i32_ty], [llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_broadcastmb_512 : + GCCBuiltin<"__builtin_ia32_broadcastmb512">, + Intrinsic<[llvm_v8i64_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_broadcastmb_256 : + GCCBuiltin<"__builtin_ia32_broadcastmb256">, + Intrinsic<[llvm_v4i64_ty], [llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_broadcastmb_128 : + GCCBuiltin<"__builtin_ia32_broadcastmb128">, + Intrinsic<[llvm_v2i64_ty], [llvm_i8_ty], [IntrNoMem]>; } // Vector sign and zero extend @@ -4071,15 +5396,36 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless_mask">, + def int_x86_avx512_mask_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless_round">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_rndscale_sd : GCCBuiltin<"__builtin_ia32_rndscalesd_mask">, + def int_x86_avx512_mask_rndscale_sd : GCCBuiltin<"__builtin_ia32_rndscalesd_round">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - + def int_x86_avx512_mask_range_ss : GCCBuiltin<"__builtin_ia32_rangess128_round">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_range_sd : GCCBuiltin<"__builtin_ia32_rangesd128_round">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_reduce_ss : GCCBuiltin<"__builtin_ia32_reducess">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_reduce_sd : GCCBuiltin<"__builtin_ia32_reducesd">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_scalef_sd : GCCBuiltin<"__builtin_ia32_scalefsd_round">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_scalef_ss : GCCBuiltin<"__builtin_ia32_scalefss_round">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_mask_scalef_pd_128 : GCCBuiltin<"__builtin_ia32_scalefpd128_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; @@ -4099,12 +5445,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtrndss">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_avx512_sqrt_sd : GCCBuiltin<"__builtin_ia32_sqrtrndsd">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtss_round">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_sd : GCCBuiltin<"__builtin_ia32_sqrtsd_round">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_mask_sqrt_pd_128 : GCCBuiltin<"__builtin_ia32_sqrtpd128_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, @@ -4143,29 +5489,108 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss_mask">, + def int_x86_avx512_mask_getexp_ss : GCCBuiltin<"__builtin_ia32_getexpss_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_sd : GCCBuiltin<"__builtin_ia32_getexpsd_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_pd_128 : + GCCBuiltin<"__builtin_ia32_getmantpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty,llvm_i32_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_pd_256 : + GCCBuiltin<"__builtin_ia32_getmantpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty,llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_pd_512 : + GCCBuiltin<"__builtin_ia32_getmantpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty,llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty,llvm_i32_ty ], + [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_ps_128 : + GCCBuiltin<"__builtin_ia32_getmantps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_ps_256 : + GCCBuiltin<"__builtin_ia32_getmantps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_ps_512 : + GCCBuiltin<"__builtin_ia32_getmantps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty,llvm_i32_ty, llvm_v16f32_ty,llvm_i16_ty,llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_ss : + GCCBuiltin<"__builtin_ia32_getmantss_round">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_getmant_sd : + GCCBuiltin<"__builtin_ia32_getmantsd_round">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v2f64_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_rsqrt14_sd : GCCBuiltin<"__builtin_ia32_rsqrt14sd_mask">, + def int_x86_avx512_rsqrt14_sd : GCCBuiltin<"__builtin_ia32_rsqrt14sd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rsqrt14_pd_128 : GCCBuiltin<"__builtin_ia32_rsqrt14pd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rsqrt14_pd_256 : GCCBuiltin<"__builtin_ia32_rsqrt14pd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_rsqrt14_pd_512 : GCCBuiltin<"__builtin_ia32_rsqrt14pd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rsqrt14_ps_128 : GCCBuiltin<"__builtin_ia32_rsqrt14ps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rsqrt14_ps_256 : GCCBuiltin<"__builtin_ia32_rsqrt14ps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_rsqrt14_ps_512 : GCCBuiltin<"__builtin_ia32_rsqrt14ps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_rcp14_ss : GCCBuiltin<"__builtin_ia32_rcp14ss_mask">, + def int_x86_avx512_rcp14_ss : GCCBuiltin<"__builtin_ia32_rcp14ss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_rcp14_sd : GCCBuiltin<"__builtin_ia32_rcp14sd_mask">, + def int_x86_avx512_rcp14_sd : GCCBuiltin<"__builtin_ia32_rcp14sd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rcp14_pd_128 : GCCBuiltin<"__builtin_ia32_rcp14pd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rcp14_pd_256 : GCCBuiltin<"__builtin_ia32_rcp14pd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_rcp14_pd_512 : GCCBuiltin<"__builtin_ia32_rcp14pd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rcp14_ps_128 : GCCBuiltin<"__builtin_ia32_rcp14ps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_rcp14_ps_256 : GCCBuiltin<"__builtin_ia32_rcp14ps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_rcp14_ps_512 : GCCBuiltin<"__builtin_ia32_rcp14ps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; @@ -4183,11 +5608,11 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss_mask">, + def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss_round">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd_mask">, + def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd_round">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; @@ -4199,14 +5624,17 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss_mask">, + def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss_round">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd_mask">, + def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd_round">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; +def int_x86_avx512_psad_bw_512 : GCCBuiltin<"__builtin_ia32_psadbw512">, + Intrinsic<[llvm_v8i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty], + [IntrNoMem]>; } // FP logical ops let TargetPrefix = "x86" in { @@ -4511,6 +5939,54 @@ let TargetPrefix = "x86" in { def int_x86_avx512_mask_pavg_w_256 : GCCBuiltin<"__builtin_ia32_pavgw256_mask">, Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmaddw_d_128 : + GCCBuiltin<"__builtin_ia32_pmaddwd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmaddw_d_256 : + GCCBuiltin<"__builtin_ia32_pmaddwd256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmaddw_d_512 : + GCCBuiltin<"__builtin_ia32_pmaddwd512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmaddubs_w_128 : + GCCBuiltin<"__builtin_ia32_pmaddubsw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmaddubs_w_256 : + GCCBuiltin<"__builtin_ia32_pmaddubsw256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmaddubs_w_512 : + GCCBuiltin<"__builtin_ia32_pmaddubsw512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_dbpsadbw_128 : + GCCBuiltin<"__builtin_ia32_dbpsadbw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_v8i16_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_dbpsadbw_256 : + GCCBuiltin<"__builtin_ia32_dbpsadbw256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty, llvm_v16i16_ty, + llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_dbpsadbw_512 : + GCCBuiltin<"__builtin_ia32_dbpsadbw512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty, llvm_v32i16_ty, + llvm_i32_ty], [IntrNoMem]>; } // Gather and Scatter ops @@ -4807,27 +6283,71 @@ let TargetPrefix = "x86" in { llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; } -// AVX-512 conflict detection +// AVX-512 conflict detection instruction +// Instructions that count the number of leading zero bits let TargetPrefix = "x86" in { + def int_x86_avx512_mask_conflict_d_128 : + GCCBuiltin<"__builtin_ia32_vpconflictsi_128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_conflict_d_256 : + GCCBuiltin<"__builtin_ia32_vpconflictsi_256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_avx512_mask_conflict_d_512 : GCCBuiltin<"__builtin_ia32_vpconflictsi_512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_conflict_q_128 : + GCCBuiltin<"__builtin_ia32_vpconflictdi_128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_conflict_q_256 : + GCCBuiltin<"__builtin_ia32_vpconflictdi_256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_conflict_q_512 : GCCBuiltin<"__builtin_ia32_vpconflictdi_512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, - llvm_v8i64_ty, llvm_i8_ty], + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_lzcnt_d_128 : + GCCBuiltin<"__builtin_ia32_vplzcntd_128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_lzcnt_d_256 : + GCCBuiltin<"__builtin_ia32_vplzcntd_256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_lzcnt_d_512 : GCCBuiltin<"__builtin_ia32_vplzcntd_512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_lzcnt_q_128 : + GCCBuiltin<"__builtin_ia32_vplzcntq_128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_lzcnt_q_256 : + GCCBuiltin<"__builtin_ia32_vplzcntq_256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_lzcnt_q_512 : GCCBuiltin<"__builtin_ia32_vplzcntq_512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, - llvm_v8i64_ty, llvm_i8_ty], + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; } @@ -4911,20 +6431,70 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". } let TargetPrefix = "x86" in { - def int_x86_avx512_mask_valign_q_512 : GCCBuiltin<"__builtin_ia32_alignq512_mask">, + def int_x86_avx512_mask_valign_q_512 : + GCCBuiltin<"__builtin_ia32_alignq512_mask">, Intrinsic<[llvm_v8i64_ty], - [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, llvm_v8i64_ty, + llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_valign_d_512 : GCCBuiltin<"__builtin_ia32_alignd512_mask">, + def int_x86_avx512_mask_valign_d_512 : + GCCBuiltin<"__builtin_ia32_alignd512_mask">, Intrinsic<[llvm_v16i32_ty], - [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i8_ty, llvm_v16i32_ty, llvm_i16_ty], - [IntrNoMem]>; + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, llvm_v16i32_ty, + llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_valign_q_256 : + GCCBuiltin<"__builtin_ia32_alignq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_v4i64_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_valign_d_256 : + GCCBuiltin<"__builtin_ia32_alignd256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_v8i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_valign_q_128 : + GCCBuiltin<"__builtin_ia32_alignq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_v2i64_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_valign_d_128 : + GCCBuiltin<"__builtin_ia32_alignd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_palignr_128 : + GCCBuiltin<"__builtin_ia32_palignr128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, + llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_palignr_256 : + GCCBuiltin<"__builtin_ia32_palignr256_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty, llvm_v32i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_palignr_512 : + GCCBuiltin<"__builtin_ia32_palignr512_mask">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty, llvm_v64i8_ty, + llvm_i64_ty], [IntrNoMem]>; } // Compares let TargetPrefix = "x86" in { // 512-bit + def int_x86_avx512_vcomi_sd : GCCBuiltin<"__builtin_ia32_vcomisd">, + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, + llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_vcomi_ss : GCCBuiltin<"__builtin_ia32_vcomiss">, + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, + llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_mask_pcmpeq_b_512 : GCCBuiltin<"__builtin_ia32_pcmpeqb512_mask">, Intrinsic<[llvm_i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>; @@ -5288,6 +6858,626 @@ let TargetPrefix = "x86" in { llvm_i8_ty], [IntrReadArgMem]>; } + +// truncate +let TargetPrefix = "x86" in { + def int_x86_avx512_mask_pmov_qb_128 : + GCCBuiltin<"__builtin_ia32_pmovqb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v2i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qb_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovqb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qb_128 : + GCCBuiltin<"__builtin_ia32_pmovsqb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v2i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qb_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovsqb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qb_128 : + GCCBuiltin<"__builtin_ia32_pmovusqb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v2i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qb_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovusqb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qb_256 : + GCCBuiltin<"__builtin_ia32_pmovqb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v4i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qb_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovqb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qb_256 : + GCCBuiltin<"__builtin_ia32_pmovsqb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v4i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qb_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovsqb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qb_256 : + GCCBuiltin<"__builtin_ia32_pmovusqb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v4i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qb_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovusqb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qb_512 : + GCCBuiltin<"__builtin_ia32_pmovqb512_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qb_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovqb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qb_512 : + GCCBuiltin<"__builtin_ia32_pmovsqb512_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qb_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovsqb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qb_512 : + GCCBuiltin<"__builtin_ia32_pmovusqb512_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i64_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qb_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovusqb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qw_128 : + GCCBuiltin<"__builtin_ia32_pmovqw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v2i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qw_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovqw128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qw_128 : + GCCBuiltin<"__builtin_ia32_pmovsqw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v2i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qw_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovsqw128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qw_128 : + GCCBuiltin<"__builtin_ia32_pmovusqw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v2i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qw_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovusqw128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qw_256 : + GCCBuiltin<"__builtin_ia32_pmovqw256_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v4i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qw_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovqw256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qw_256 : + GCCBuiltin<"__builtin_ia32_pmovsqw256_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v4i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qw_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovsqw256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qw_256 : + GCCBuiltin<"__builtin_ia32_pmovusqw256_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v4i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qw_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovusqw256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qw_512 : + GCCBuiltin<"__builtin_ia32_pmovqw512_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qw_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovqw512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qw_512 : + GCCBuiltin<"__builtin_ia32_pmovsqw512_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qw_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovsqw512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qw_512 : + GCCBuiltin<"__builtin_ia32_pmovusqw512_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i64_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qw_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovusqw512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qd_128 : + GCCBuiltin<"__builtin_ia32_pmovqd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qd_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovqd128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qd_128 : + GCCBuiltin<"__builtin_ia32_pmovsqd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qd_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovsqd128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qd_128 : + GCCBuiltin<"__builtin_ia32_pmovusqd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qd_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovusqd128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qd_256 : + GCCBuiltin<"__builtin_ia32_pmovqd256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qd_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovqd256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qd_256 : + GCCBuiltin<"__builtin_ia32_pmovsqd256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qd_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovsqd256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qd_256 : + GCCBuiltin<"__builtin_ia32_pmovusqd256_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qd_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovusqd256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_qd_512 : + GCCBuiltin<"__builtin_ia32_pmovqd512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i64_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_qd_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovqd512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_qd_512 : + GCCBuiltin<"__builtin_ia32_pmovsqd512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i64_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_qd_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovsqd512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_qd_512 : + GCCBuiltin<"__builtin_ia32_pmovusqd512_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i64_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_qd_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovusqd512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_db_128 : + GCCBuiltin<"__builtin_ia32_pmovdb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v4i32_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_db_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovdb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_db_128 : + GCCBuiltin<"__builtin_ia32_pmovsdb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v4i32_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_db_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovsdb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_db_128 : + GCCBuiltin<"__builtin_ia32_pmovusdb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v4i32_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_db_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovusdb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_db_256 : + GCCBuiltin<"__builtin_ia32_pmovdb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i32_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_db_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovdb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_db_256 : + GCCBuiltin<"__builtin_ia32_pmovsdb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i32_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_db_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovsdb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_db_256 : + GCCBuiltin<"__builtin_ia32_pmovusdb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i32_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_db_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovusdb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_db_512 : + GCCBuiltin<"__builtin_ia32_pmovdb512_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i32_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_db_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovdb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_db_512 : + GCCBuiltin<"__builtin_ia32_pmovsdb512_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i32_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_db_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovsdb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_db_512 : + GCCBuiltin<"__builtin_ia32_pmovusdb512_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i32_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_db_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovusdb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_dw_128 : + GCCBuiltin<"__builtin_ia32_pmovdw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v4i32_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_dw_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovdw128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_dw_128 : + GCCBuiltin<"__builtin_ia32_pmovsdw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v4i32_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_dw_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovsdw128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_dw_128 : + GCCBuiltin<"__builtin_ia32_pmovusdw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v4i32_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_dw_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovusdw128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_dw_256 : + GCCBuiltin<"__builtin_ia32_pmovdw256_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i32_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_dw_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovdw256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_dw_256 : + GCCBuiltin<"__builtin_ia32_pmovsdw256_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i32_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_dw_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovsdw256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_dw_256 : + GCCBuiltin<"__builtin_ia32_pmovusdw256_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i32_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_dw_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovusdw256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_dw_512 : + GCCBuiltin<"__builtin_ia32_pmovdw512_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i32_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_dw_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovdw512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_dw_512 : + GCCBuiltin<"__builtin_ia32_pmovsdw512_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i32_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_dw_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovsdw512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_dw_512 : + GCCBuiltin<"__builtin_ia32_pmovusdw512_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i32_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_dw_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovusdw512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_wb_128 : + GCCBuiltin<"__builtin_ia32_pmovwb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i16_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_wb_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovwb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_wb_128 : + GCCBuiltin<"__builtin_ia32_pmovswb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i16_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_wb_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovswb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_wb_128 : + GCCBuiltin<"__builtin_ia32_pmovuswb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v8i16_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_wb_mem_128 : + GCCBuiltin<"__builtin_ia32_pmovuswb128mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_wb_256 : + GCCBuiltin<"__builtin_ia32_pmovwb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i16_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_wb_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovwb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_wb_256 : + GCCBuiltin<"__builtin_ia32_pmovswb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i16_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_wb_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovswb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_wb_256 : + GCCBuiltin<"__builtin_ia32_pmovuswb256_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i16_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_wb_mem_256 : + GCCBuiltin<"__builtin_ia32_pmovuswb256mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmov_wb_512 : + GCCBuiltin<"__builtin_ia32_pmovwb512_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i16_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmov_wb_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovwb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovs_wb_512 : + GCCBuiltin<"__builtin_ia32_pmovswb512_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i16_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovs_wb_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovswb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + def int_x86_avx512_mask_pmovus_wb_512 : + GCCBuiltin<"__builtin_ia32_pmovuswb512_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i16_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_x86_avx512_mask_pmovus_wb_mem_512 : + GCCBuiltin<"__builtin_ia32_pmovuswb512mem_mask">, + Intrinsic<[], + [llvm_ptr_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; +} + +// Bitwise ternary logic +let TargetPrefix = "x86" in { + def int_x86_avx512_mask_pternlog_d_128 : + GCCBuiltin<"__builtin_ia32_pternlogd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_pternlog_d_128 : + GCCBuiltin<"__builtin_ia32_pternlogd128_maskz">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_pternlog_d_256 : + GCCBuiltin<"__builtin_ia32_pternlogd256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_pternlog_d_256 : + GCCBuiltin<"__builtin_ia32_pternlogd256_maskz">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_pternlog_d_512 : + GCCBuiltin<"__builtin_ia32_pternlogd512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, + llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_pternlog_d_512 : + GCCBuiltin<"__builtin_ia32_pternlogd512_maskz">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, + llvm_i16_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_pternlog_q_128 : + GCCBuiltin<"__builtin_ia32_pternlogq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_pternlog_q_128 : + GCCBuiltin<"__builtin_ia32_pternlogq128_maskz">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_pternlog_q_256 : + GCCBuiltin<"__builtin_ia32_pternlogq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_pternlog_q_256 : + GCCBuiltin<"__builtin_ia32_pternlogq256_maskz">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_pternlog_q_512 : + GCCBuiltin<"__builtin_ia32_pternlogq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_pternlog_q_512 : + GCCBuiltin<"__builtin_ia32_pternlogq512_maskz">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, + llvm_i8_ty], [IntrNoMem]>; +} + // Misc. let TargetPrefix = "x86" in { def int_x86_avx512_mask_cmp_ps_512 : @@ -5314,6 +7504,14 @@ let TargetPrefix = "x86" in { GCCBuiltin<"__builtin_ia32_cmppd128_mask">, Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_cmp_ss : + GCCBuiltin<"__builtin_ia32_cmpss_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_cmp_sd : + GCCBuiltin<"__builtin_ia32_cmpsd_mask">, + Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa512">, diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index e6c22090ab6d..c546fc3d1ee0 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -15,7 +15,6 @@ #ifndef LLVM_IR_LLVMCONTEXT_H #define LLVM_IR_LLVMCONTEXT_H -#include "llvm-c/Core.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Options.h" @@ -60,7 +59,20 @@ public: MD_mem_parallel_loop_access = 10, // "llvm.mem.parallel_loop_access" MD_nonnull = 11, // "nonnull" MD_dereferenceable = 12, // "dereferenceable" - MD_dereferenceable_or_null = 13 // "dereferenceable_or_null" + MD_dereferenceable_or_null = 13, // "dereferenceable_or_null" + MD_make_implicit = 14, // "make.implicit" + MD_unpredictable = 15, // "unpredictable" + MD_invariant_group = 16, // "invariant.group" + MD_align = 17 // "align" + }; + + /// Known operand bundle tag IDs, which always have the same value. All + /// operand bundle tags that LLVM has special knowledge of are listed here. + /// Additionally, this scheme allows LLVM to efficiently check for specific + /// operand bundle tags without comparing strings. + enum { + OB_deopt = 0, // "deopt" + OB_funclet = 1, // "funclet" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. @@ -71,6 +83,15 @@ public: /// custom metadata IDs registered in this LLVMContext. void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; + /// getOperandBundleTags - Populate client supplied SmallVector with the + /// bundle tags registered in this LLVMContext. The bundle tags are ordered + /// by increasing bundle IDs. + /// \see LLVMContext::getOperandBundleTagID + void getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const; + + /// getOperandBundleTagID - Maps a bundle tag to an integer ID. Every bundle + /// tag registered with an LLVMContext has an unique ID. + uint32_t getOperandBundleTagID(StringRef Tag) const; typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context, unsigned LocCookie); diff --git a/include/llvm/IR/LegacyPassManagers.h b/include/llvm/IR/LegacyPassManagers.h index 7f7889ad5fb3..b8e33478d6a9 100644 --- a/include/llvm/IR/LegacyPassManagers.h +++ b/include/llvm/IR/LegacyPassManagers.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Pass.h" @@ -118,6 +119,7 @@ class PassManagerPrettyStackEntry : public PrettyStackTraceEntry { Pass *P; Value *V; Module *M; + public: explicit PassManagerPrettyStackEntry(Pass *p) : P(p), V(nullptr), M(nullptr) {} // When P is releaseMemory'd. @@ -130,7 +132,6 @@ public: void print(raw_ostream &OS) const override; }; - //===----------------------------------------------------------------------===// // PMStack // @@ -158,7 +159,6 @@ private: std::vector<PMDataManager *> S; }; - //===----------------------------------------------------------------------===// // PMTopLevelManager // @@ -204,10 +204,7 @@ public: virtual ~PMTopLevelManager(); /// Add immutable pass and initialize it. - inline void addImmutablePass(ImmutablePass *P) { - P->initializePass(); - ImmutablePasses.push_back(P); - } + void addImmutablePass(ImmutablePass *P); inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() { return ImmutablePasses; @@ -231,12 +228,10 @@ public: PMStack activeStack; protected: - /// Collection of pass managers SmallVector<PMDataManager *, 8> PassManagers; private: - /// Collection of pass managers that are not directly maintained /// by this pass manager SmallVector<PMDataManager *, 8> IndirectPassManagers; @@ -253,7 +248,46 @@ private: /// Immutable passes are managed by top level manager. SmallVector<ImmutablePass *, 16> ImmutablePasses; - DenseMap<Pass *, AnalysisUsage *> AnUsageMap; + /// Map from ID to immutable passes. + SmallDenseMap<AnalysisID, ImmutablePass *, 8> ImmutablePassMap; + + + /// A wrapper around AnalysisUsage for the purpose of uniqueing. The wrapper + /// is used to avoid needing to make AnalysisUsage itself a folding set node. + struct AUFoldingSetNode : public FoldingSetNode { + AnalysisUsage AU; + AUFoldingSetNode(const AnalysisUsage &AU) : AU(AU) {} + void Profile(FoldingSetNodeID &ID) const { + Profile(ID, AU); + } + static void Profile(FoldingSetNodeID &ID, const AnalysisUsage &AU) { + // TODO: We could consider sorting the dependency arrays within the + // AnalysisUsage (since they are conceptually unordered). + ID.AddBoolean(AU.getPreservesAll()); + auto ProfileVec = [&](const SmallVectorImpl<AnalysisID>& Vec) { + ID.AddInteger(Vec.size()); + for(AnalysisID AID : Vec) + ID.AddPointer(AID); + }; + ProfileVec(AU.getRequiredSet()); + ProfileVec(AU.getRequiredTransitiveSet()); + ProfileVec(AU.getPreservedSet()); + ProfileVec(AU.getUsedSet()); + } + }; + + // Contains all of the unique combinations of AnalysisUsage. This is helpful + // when we have multiple instances of the same pass since they'll usually + // have the same analysis usage and can share storage. + FoldingSet<AUFoldingSetNode> UniqueAnalysisUsages; + + // Allocator used for allocating UAFoldingSetNodes. This handles deletion of + // all allocated nodes in one fell swoop. + SpecificBumpPtrAllocator<AUFoldingSetNode> AUFoldingSetNodeAllocator; + + // Maps from a pass to it's associated entry in UniqueAnalysisUsages. Does + // not own the storage associated with either key or value.. + DenseMap<Pass *, AnalysisUsage*> AnUsageMap; /// Collection of PassInfo objects found via analysis IDs and in this top /// level manager. This is used to memoize queries to the pass registry. @@ -262,8 +296,6 @@ private: mutable DenseMap<AnalysisID, const PassInfo *> AnalysisPassInfos; }; - - //===----------------------------------------------------------------------===// // PMDataManager @@ -271,7 +303,6 @@ private: /// used by pass managers. class PMDataManager { public: - explicit PMDataManager() : TPM(nullptr), Depth(0) { initializeAnalysisInfo(); } @@ -319,13 +350,12 @@ public: // passes that are managed by this manager. bool preserveHigherLevelAnalysis(Pass *P); - - /// Populate RequiredPasses with analysis pass that are required by - /// pass P and are available. Populate ReqPassNotAvailable with analysis - /// pass that are required by pass P but are not available. - void collectRequiredAnalysis(SmallVectorImpl<Pass *> &RequiredPasses, - SmallVectorImpl<AnalysisID> &ReqPassNotAvailable, - Pass *P); + /// Populate UsedPasses with analysis pass that are used or required by pass + /// P and are available. Populate ReqPassNotAvailable with analysis pass that + /// are required by pass P but are not available. + void collectRequiredAndUsedAnalyses( + SmallVectorImpl<Pass *> &UsedPasses, + SmallVectorImpl<AnalysisID> &ReqPassNotAvailable, Pass *P); /// All Required analyses should be available to the pass as it runs! Here /// we fill in the AnalysisImpls member of the pass so that it can @@ -351,6 +381,7 @@ public: enum PassDebuggingString S2, StringRef Msg); void dumpRequiredSet(const Pass *P) const; void dumpPreservedSet(const Pass *P) const; + void dumpUsedSet(const Pass *P) const; unsigned getNumContainedPasses() const { return (unsigned)PassVector.size(); @@ -374,7 +405,6 @@ public: } protected: - // Top level manager. PMTopLevelManager *TPM; @@ -439,9 +469,9 @@ public: /// doFinalization - Overrides ModulePass doFinalization for global /// finalization tasks - /// + /// using ModulePass::doFinalization; - + /// doFinalization - Run all of the finalizers for the function passes. /// bool doFinalization(Module &M) override; @@ -473,7 +503,6 @@ public: }; Timer *getPassTimer(Pass *); - } #endif diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h index ceb1c736e5c7..35341e3271ff 100644 --- a/include/llvm/IR/MDBuilder.h +++ b/include/llvm/IR/MDBuilder.h @@ -60,6 +60,9 @@ public: /// \brief Return metadata containing a number of branch weights. MDNode *createBranchWeights(ArrayRef<uint32_t> Weights); + /// Return metadata specifying that a branch or switch is unpredictable. + MDNode *createUnpredictable(); + /// Return metadata containing the entry count for a function. MDNode *createFunctionEntryCount(uint64_t Count); diff --git a/include/llvm/IR/Mangler.h b/include/llvm/IR/Mangler.h index b72b259097c3..ea2f0c3f09f3 100644 --- a/include/llvm/IR/Mangler.h +++ b/include/llvm/IR/Mangler.h @@ -15,12 +15,12 @@ #define LLVM_IR_MANGLER_H #include "llvm/ADT/DenseMap.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/Support/raw_ostream.h" namespace llvm { class DataLayout; -class GlobalValue; template <typename T> class SmallVectorImpl; class Twine; diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def index 857e4637d1e4..b1d22178e262 100644 --- a/include/llvm/IR/Metadata.def +++ b/include/llvm/IR/Metadata.def @@ -13,7 +13,8 @@ #if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \ defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \ - defined HANDLE_MDNODE_BRANCH || \ + defined HANDLE_MDNODE_LEAF_UNIQUABLE || defined HANDLE_MDNODE_BRANCH || \ + defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE || \ defined HANDLE_SPECIALIZED_MDNODE_LEAF || \ defined HANDLE_SPECIALIZED_MDNODE_BRANCH) #error "Missing macro definition of HANDLE_METADATA*" @@ -34,6 +35,24 @@ #define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS) #endif +// Handler for specialized and uniquable leaf nodes under MDNode. Defers to +// HANDLE_MDNODE_LEAF_UNIQUABLE if it's defined, otherwise to +// HANDLE_SPECIALIZED_MDNODE_LEAF. +#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE +#ifdef HANDLE_MDNODE_LEAF_UNIQUABLE +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(CLASS) \ + HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) +#else +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(CLASS) \ + HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) +#endif +#endif + +// Handler for leaf nodes under MDNode. +#ifndef HANDLE_MDNODE_LEAF_UNIQUABLE +#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) HANDLE_MDNODE_LEAF(CLASS) +#endif + // Handler for leaf nodes under MDNode. #ifndef HANDLE_MDNODE_LEAF #define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS) @@ -59,43 +78,46 @@ HANDLE_METADATA_BRANCH(ValueAsMetadata) HANDLE_METADATA_LEAF(ConstantAsMetadata) HANDLE_METADATA_LEAF(LocalAsMetadata) HANDLE_MDNODE_BRANCH(MDNode) -HANDLE_MDNODE_LEAF(MDTuple) -HANDLE_SPECIALIZED_MDNODE_LEAF(DILocation) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIExpression) +HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIExpression) HANDLE_SPECIALIZED_MDNODE_BRANCH(DINode) -HANDLE_SPECIALIZED_MDNODE_LEAF(GenericDINode) -HANDLE_SPECIALIZED_MDNODE_LEAF(DISubrange) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIEnumerator) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(GenericDINode) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubrange) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIEnumerator) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIScope) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIType) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIBasicType) -HANDLE_SPECIALIZED_MDNODE_BRANCH(DIDerivedTypeBase) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIDerivedType) -HANDLE_SPECIALIZED_MDNODE_BRANCH(DICompositeTypeBase) -HANDLE_SPECIALIZED_MDNODE_LEAF(DICompositeType) -HANDLE_SPECIALIZED_MDNODE_LEAF(DISubroutineType) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIFile) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIBasicType) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIDerivedType) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICompositeType) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubroutineType) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFile) HANDLE_SPECIALIZED_MDNODE_LEAF(DICompileUnit) HANDLE_SPECIALIZED_MDNODE_BRANCH(DILocalScope) -HANDLE_SPECIALIZED_MDNODE_LEAF(DISubprogram) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubprogram) HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase) -HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlock) -HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlockFile) -HANDLE_SPECIALIZED_MDNODE_LEAF(DINamespace) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIModule) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILexicalBlock) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILexicalBlockFile) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DINamespace) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIModule) HANDLE_SPECIALIZED_MDNODE_BRANCH(DITemplateParameter) -HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateTypeParameter) -HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateValueParameter) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DITemplateTypeParameter) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DITemplateValueParameter) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIVariable) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIGlobalVariable) -HANDLE_SPECIALIZED_MDNODE_LEAF(DILocalVariable) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIObjCProperty) -HANDLE_SPECIALIZED_MDNODE_LEAF(DIImportedEntity) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariable) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocalVariable) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIObjCProperty) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity) +HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile) #undef HANDLE_METADATA #undef HANDLE_METADATA_LEAF #undef HANDLE_METADATA_BRANCH #undef HANDLE_MDNODE_LEAF +#undef HANDLE_MDNODE_LEAF_UNIQUABLE #undef HANDLE_MDNODE_BRANCH #undef HANDLE_SPECIALIZED_MDNODE_LEAF +#undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE #undef HANDLE_SPECIALIZED_MDNODE_BRANCH diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index c639625bf16c..2ea591383f82 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -18,10 +18,11 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Constant.h" -#include "llvm/IR/MetadataTracking.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Value.h" #include "llvm/Support/ErrorHandling.h" #include <type_traits> @@ -32,9 +33,6 @@ class LLVMContext; class Module; class ModuleSlotTracker; -template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; - enum LLVMConstants : uint32_t { DEBUG_METADATA_VERSION = 3 // Current debug info version number. }; @@ -86,7 +84,9 @@ public: DIImportedEntityKind, ConstantAsMetadataKind, LocalAsMetadataKind, - MDStringKind + MDStringKind, + DIMacroKind, + DIMacroFileKind }; protected: @@ -126,9 +126,10 @@ public: /// If \c M is provided, metadata nodes will be numbered canonically; /// otherwise, pointer addresses are substituted. /// @{ - void print(raw_ostream &OS, const Module *M = nullptr) const; - void print(raw_ostream &OS, ModuleSlotTracker &MST, - const Module *M = nullptr) const; + void print(raw_ostream &OS, const Module *M = nullptr, + bool IsForDebug = false) const; + void print(raw_ostream &OS, ModuleSlotTracker &MST, const Module *M = nullptr, + bool IsForDebug = false) const; /// @} /// \brief Print as operand. @@ -196,6 +197,77 @@ private: void untrack(); }; +/// \brief API for tracking metadata references through RAUW and deletion. +/// +/// Shared API for updating \a Metadata pointers in subclasses that support +/// RAUW. +/// +/// This API is not meant to be used directly. See \a TrackingMDRef for a +/// user-friendly tracking reference. +class MetadataTracking { +public: + /// \brief Track the reference to metadata. + /// + /// Register \c MD with \c *MD, if the subclass supports tracking. If \c *MD + /// gets RAUW'ed, \c MD will be updated to the new address. If \c *MD gets + /// deleted, \c MD will be set to \c nullptr. + /// + /// If tracking isn't supported, \c *MD will not change. + /// + /// \return true iff tracking is supported by \c MD. + static bool track(Metadata *&MD) { + return track(&MD, *MD, static_cast<Metadata *>(nullptr)); + } + + /// \brief Track the reference to metadata for \a Metadata. + /// + /// As \a track(Metadata*&), but with support for calling back to \c Owner to + /// tell it that its operand changed. This could trigger \c Owner being + /// re-uniqued. + static bool track(void *Ref, Metadata &MD, Metadata &Owner) { + return track(Ref, MD, &Owner); + } + + /// \brief Track the reference to metadata for \a MetadataAsValue. + /// + /// As \a track(Metadata*&), but with support for calling back to \c Owner to + /// tell it that its operand changed. This could trigger \c Owner being + /// re-uniqued. + static bool track(void *Ref, Metadata &MD, MetadataAsValue &Owner) { + return track(Ref, MD, &Owner); + } + + /// \brief Stop tracking a reference to metadata. + /// + /// Stops \c *MD from tracking \c MD. + static void untrack(Metadata *&MD) { untrack(&MD, *MD); } + static void untrack(void *Ref, Metadata &MD); + + /// \brief Move tracking from one reference to another. + /// + /// Semantically equivalent to \c untrack(MD) followed by \c track(New), + /// except that ownership callbacks are maintained. + /// + /// Note: it is an error if \c *MD does not equal \c New. + /// + /// \return true iff tracking is supported by \c MD. + static bool retrack(Metadata *&MD, Metadata *&New) { + return retrack(&MD, *MD, &New); + } + static bool retrack(void *Ref, Metadata &MD, void *New); + + /// \brief Check whether metadata is replaceable. + static bool isReplaceable(const Metadata &MD); + + typedef PointerUnion<MetadataAsValue *, Metadata *> OwnerTy; + +private: + /// \brief Track a reference to metadata for an owner. + /// + /// Generalized version of tracking. + static bool track(void *Ref, Metadata &MD, OwnerTy Owner); +}; + /// \brief Shared implementation of use-lists for replaceable metadata. /// /// Most metadata cannot be RAUW'ed. This is a shared implementation of @@ -572,10 +644,12 @@ struct AAMDNodes { template<> struct DenseMapInfo<AAMDNodes> { static inline AAMDNodes getEmptyKey() { - return AAMDNodes(DenseMapInfo<MDNode *>::getEmptyKey(), 0, 0); + return AAMDNodes(DenseMapInfo<MDNode *>::getEmptyKey(), + nullptr, nullptr); } static inline AAMDNodes getTombstoneKey() { - return AAMDNodes(DenseMapInfo<MDNode *>::getTombstoneKey(), 0, 0); + return AAMDNodes(DenseMapInfo<MDNode *>::getTombstoneKey(), + nullptr, nullptr); } static unsigned getHashValue(const AAMDNodes &Val) { return DenseMapInfo<MDNode *>::getHashValue(Val.TBAA) ^ @@ -830,10 +904,11 @@ public: /// \brief Resolve cycles. /// /// Once all forward declarations have been resolved, force cycles to be - /// resolved. + /// resolved. If \p MDMaterialized is true, then any temporary metadata + /// is ignored, otherwise it asserts when encountering temporary metadata. /// /// \pre No operands (or operands' operands, etc.) have \a isTemporary(). - void resolveCycles(); + void resolveCycles(bool MDMaterialized = true); /// \brief Replace a temporary node with a permanent one. /// @@ -881,6 +956,7 @@ protected: void storeDistinctInContext(); template <class T, class StoreT> static T *storeImpl(T *N, StorageType Storage, StoreT &Store); + template <class T> static T *storeImpl(T *N, StorageType Storage); private: void handleChangedOperand(void *Ref, Metadata *New); @@ -913,13 +989,13 @@ private: N->recalculateHash(); } template <class NodeTy> - static void dispatchRecalculateHash(NodeTy *N, std::false_type) {} + static void dispatchRecalculateHash(NodeTy *, std::false_type) {} template <class NodeTy> static void dispatchResetHash(NodeTy *N, std::true_type) { N->setHash(0); } template <class NodeTy> - static void dispatchResetHash(NodeTy *N, std::false_type) {} + static void dispatchResetHash(NodeTy *, std::false_type) {} public: typedef const MDOperand *op_iterator; @@ -963,6 +1039,8 @@ public: static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B); static MDNode *getMostGenericRange(MDNode *A, MDNode *B); static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B); + static MDNode *getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B); + }; /// \brief Tuple of metadata. @@ -1125,7 +1203,6 @@ public: /// /// TODO: Inherit from Metadata. class NamedMDNode : public ilist_node<NamedMDNode> { - friend class SymbolTableListTraits<NamedMDNode, Module>; friend struct ilist_traits<NamedMDNode>; friend class LLVMContextImpl; friend class Module; @@ -1193,7 +1270,7 @@ public: void addOperand(MDNode *M); void setOperand(unsigned I, MDNode *New); StringRef getName() const; - void print(raw_ostream &ROS) const; + void print(raw_ostream &ROS, bool IsForDebug = false) const; void dump() const; // --------------------------------------------------------------------------- @@ -1208,13 +1285,13 @@ public: const_op_iterator op_end() const { return const_op_iterator(this, getNumOperands()); } inline iterator_range<op_iterator> operands() { - return iterator_range<op_iterator>(op_begin(), op_end()); + return make_range(op_begin(), op_end()); } inline iterator_range<const_op_iterator> operands() const { - return iterator_range<const_op_iterator>(op_begin(), op_end()); + return make_range(op_begin(), op_end()); } }; } // end llvm namespace -#endif +#endif // LLVM_IR_METADATA_H diff --git a/include/llvm/IR/MetadataTracking.h b/include/llvm/IR/MetadataTracking.h deleted file mode 100644 index 541d9b3b1245..000000000000 --- a/include/llvm/IR/MetadataTracking.h +++ /dev/null @@ -1,99 +0,0 @@ -//===- llvm/IR/MetadataTracking.h - Metadata tracking ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Low-level functions to enable tracking of metadata that could RAUW. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_IR_METADATATRACKING_H -#define LLVM_IR_METADATATRACKING_H - -#include "llvm/ADT/PointerUnion.h" -#include "llvm/Support/Casting.h" -#include <type_traits> - -namespace llvm { - -class Metadata; -class MetadataAsValue; - -/// \brief API for tracking metadata references through RAUW and deletion. -/// -/// Shared API for updating \a Metadata pointers in subclasses that support -/// RAUW. -/// -/// This API is not meant to be used directly. See \a TrackingMDRef for a -/// user-friendly tracking reference. -class MetadataTracking { -public: - /// \brief Track the reference to metadata. - /// - /// Register \c MD with \c *MD, if the subclass supports tracking. If \c *MD - /// gets RAUW'ed, \c MD will be updated to the new address. If \c *MD gets - /// deleted, \c MD will be set to \c nullptr. - /// - /// If tracking isn't supported, \c *MD will not change. - /// - /// \return true iff tracking is supported by \c MD. - static bool track(Metadata *&MD) { - return track(&MD, *MD, static_cast<Metadata *>(nullptr)); - } - - /// \brief Track the reference to metadata for \a Metadata. - /// - /// As \a track(Metadata*&), but with support for calling back to \c Owner to - /// tell it that its operand changed. This could trigger \c Owner being - /// re-uniqued. - static bool track(void *Ref, Metadata &MD, Metadata &Owner) { - return track(Ref, MD, &Owner); - } - - /// \brief Track the reference to metadata for \a MetadataAsValue. - /// - /// As \a track(Metadata*&), but with support for calling back to \c Owner to - /// tell it that its operand changed. This could trigger \c Owner being - /// re-uniqued. - static bool track(void *Ref, Metadata &MD, MetadataAsValue &Owner) { - return track(Ref, MD, &Owner); - } - - /// \brief Stop tracking a reference to metadata. - /// - /// Stops \c *MD from tracking \c MD. - static void untrack(Metadata *&MD) { untrack(&MD, *MD); } - static void untrack(void *Ref, Metadata &MD); - - /// \brief Move tracking from one reference to another. - /// - /// Semantically equivalent to \c untrack(MD) followed by \c track(New), - /// except that ownership callbacks are maintained. - /// - /// Note: it is an error if \c *MD does not equal \c New. - /// - /// \return true iff tracking is supported by \c MD. - static bool retrack(Metadata *&MD, Metadata *&New) { - return retrack(&MD, *MD, &New); - } - static bool retrack(void *Ref, Metadata &MD, void *New); - - /// \brief Check whether metadata is replaceable. - static bool isReplaceable(const Metadata &MD); - - typedef PointerUnion<MetadataAsValue *, Metadata *> OwnerTy; - -private: - /// \brief Track a reference to metadata for an owner. - /// - /// Generalized version of tracking. - static bool track(void *Ref, Metadata &MD, OwnerTy Owner); -}; - -} // end namespace llvm - -#endif diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 1668b95c8bd1..942f68543cb6 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -15,6 +15,7 @@ #ifndef LLVM_IR_MODULE_H #define LLVM_IR_MODULE_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/DataLayout.h" @@ -34,54 +35,6 @@ class LLVMContext; class RandomNumberGenerator; class StructType; -template<> struct ilist_traits<Function> - : public SymbolTableListTraits<Function, Module> { - - // createSentinel is used to get hold of the node that marks the end of the - // list... (same trick used here as in ilist_traits<Instruction>) - Function *createSentinel() const { - return static_cast<Function*>(&Sentinel); - } - static void destroySentinel(Function*) {} - - Function *provideInitialHead() const { return createSentinel(); } - Function *ensureHead(Function*) const { return createSentinel(); } - static void noteHead(Function*, Function*) {} - -private: - mutable ilist_node<Function> Sentinel; -}; - -template<> struct ilist_traits<GlobalVariable> - : public SymbolTableListTraits<GlobalVariable, Module> { - // createSentinel is used to create a node that marks the end of the list. - GlobalVariable *createSentinel() const { - return static_cast<GlobalVariable*>(&Sentinel); - } - static void destroySentinel(GlobalVariable*) {} - - GlobalVariable *provideInitialHead() const { return createSentinel(); } - GlobalVariable *ensureHead(GlobalVariable*) const { return createSentinel(); } - static void noteHead(GlobalVariable*, GlobalVariable*) {} -private: - mutable ilist_node<GlobalVariable> Sentinel; -}; - -template<> struct ilist_traits<GlobalAlias> - : public SymbolTableListTraits<GlobalAlias, Module> { - // createSentinel is used to create a node that marks the end of the list. - GlobalAlias *createSentinel() const { - return static_cast<GlobalAlias*>(&Sentinel); - } - static void destroySentinel(GlobalAlias*) {} - - GlobalAlias *provideInitialHead() const { return createSentinel(); } - GlobalAlias *ensureHead(GlobalAlias*) const { return createSentinel(); } - static void noteHead(GlobalAlias*, GlobalAlias*) {} -private: - mutable ilist_node<GlobalAlias> Sentinel; -}; - template<> struct ilist_traits<NamedMDNode> : public ilist_default_traits<NamedMDNode> { // createSentinel is used to get hold of a node that marks the end of @@ -96,6 +49,7 @@ template<> struct ilist_traits<NamedMDNode> static void noteHead(NamedMDNode*, NamedMDNode*) {} void addNodeToList(NamedMDNode *) {} void removeNodeFromList(NamedMDNode *) {} + private: mutable ilist_node<NamedMDNode> Sentinel; }; @@ -116,11 +70,11 @@ class Module { /// @{ public: /// The type for the list of global variables. - typedef iplist<GlobalVariable> GlobalListType; + typedef SymbolTableList<GlobalVariable> GlobalListType; /// The type for the list of functions. - typedef iplist<Function> FunctionListType; + typedef SymbolTableList<Function> FunctionListType; /// The type for the list of aliases. - typedef iplist<GlobalAlias> AliasListType; + typedef SymbolTableList<GlobalAlias> AliasListType; /// The type for the list of named metadata. typedef ilist<NamedMDNode> NamedMDListType; /// The type of the comdat "symbol" table. @@ -328,6 +282,11 @@ public: /// registered in this LLVMContext. void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; + /// Populate client supplied SmallVector with the bundle tags registered in + /// this LLVMContext. The bundle tags are ordered by increasing bundle IDs. + /// \see LLVMContext::getOperandBundleTagID + void getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const; + /// Return the type with the specified name, or null if there is none by that /// name. StructType *getTypeByName(StringRef Name) const; @@ -472,7 +431,7 @@ public: /// Sets the GVMaterializer to GVM. This module must not yet have a /// Materializer. To reset the materializer for a module that already has one, - /// call MaterializeAllPermanently first. Destroying this module will destroy + /// call materializeAll first. Destroying this module will destroy /// its materializer without materializing any more GlobalValues. Without /// destroying the Module, there is no way to detach or destroy a materializer /// without materializing all the GVs it controls, to avoid leaving orphan @@ -480,27 +439,16 @@ public: void setMaterializer(GVMaterializer *GVM); /// Retrieves the GVMaterializer, if any, for this Module. GVMaterializer *getMaterializer() const { return Materializer.get(); } - - /// Returns true if this GV was loaded from this Module's GVMaterializer and - /// the GVMaterializer knows how to dematerialize the GV. - bool isDematerializable(const GlobalValue *GV) const; + bool isMaterialized() const { return !getMaterializer(); } /// Make sure the GlobalValue is fully read. If the module is corrupt, this /// returns true and fills in the optional string with information about the /// problem. If successful, this returns false. std::error_code materialize(GlobalValue *GV); - /// If the GlobalValue is read in, and if the GVMaterializer supports it, - /// release the memory for the function, and set it up to be materialized - /// lazily. If !isDematerializable(), this method is a no-op. - void dematerialize(GlobalValue *GV); - - /// Make sure all GlobalValues in this Module are fully read. - std::error_code materializeAll(); /// Make sure all GlobalValues in this Module are fully read and clear the - /// Materializer. If the module is corrupt, this DOES NOT clear the old /// Materializer. - std::error_code materializeAllPermanently(); + std::error_code materializeAll(); std::error_code materializeMetadata(); @@ -556,10 +504,10 @@ public: bool global_empty() const { return GlobalList.empty(); } iterator_range<global_iterator> globals() { - return iterator_range<global_iterator>(global_begin(), global_end()); + return make_range(global_begin(), global_end()); } iterator_range<const_global_iterator> globals() const { - return iterator_range<const_global_iterator>(global_begin(), global_end()); + return make_range(global_begin(), global_end()); } /// @} @@ -578,10 +526,10 @@ public: bool empty() const { return FunctionList.empty(); } iterator_range<iterator> functions() { - return iterator_range<iterator>(begin(), end()); + return make_range(begin(), end()); } iterator_range<const_iterator> functions() const { - return iterator_range<const_iterator>(begin(), end()); + return make_range(begin(), end()); } /// @} @@ -596,10 +544,10 @@ public: bool alias_empty() const { return AliasList.empty(); } iterator_range<alias_iterator> aliases() { - return iterator_range<alias_iterator>(alias_begin(), alias_end()); + return make_range(alias_begin(), alias_end()); } iterator_range<const_alias_iterator> aliases() const { - return iterator_range<const_alias_iterator>(alias_begin(), alias_end()); + return make_range(alias_begin(), alias_end()); } /// @} @@ -620,12 +568,10 @@ public: bool named_metadata_empty() const { return NamedMDList.empty(); } iterator_range<named_metadata_iterator> named_metadata() { - return iterator_range<named_metadata_iterator>(named_metadata_begin(), - named_metadata_end()); + return make_range(named_metadata_begin(), named_metadata_end()); } iterator_range<const_named_metadata_iterator> named_metadata() const { - return iterator_range<const_named_metadata_iterator>(named_metadata_begin(), - named_metadata_end()); + return make_range(named_metadata_begin(), named_metadata_end()); } /// Destroy ConstantArrays in LLVMContext if they are not used. @@ -646,11 +592,12 @@ public: /// uselistorder directives so that use-lists can be recreated when reading /// the assembly. void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW, - bool ShouldPreserveUseListOrder = false) const; + bool ShouldPreserveUseListOrder = false, + bool IsForDebug = false) const; /// Dump the module to stderr (for debugging). void dump() const; - + /// This function causes all the subinstructions to "let go" of all references /// that they are maintaining. This allows one to 'delete' a whole class at /// a time, even though there may be circular references... first all @@ -666,6 +613,10 @@ public: /// \brief Returns the Dwarf Version by checking module flags. unsigned getDwarfVersion() const; + /// \brief Returns the CodeView Version by checking module flags. + /// Returns zero if not present in module. + unsigned getCodeViewFlag() const; + /// @} /// @name Utility functions for querying and setting PIC level /// @{ @@ -676,6 +627,16 @@ public: /// \brief Set the PIC level (small or large model) void setPICLevel(PICLevel::Level PL); /// @} + + /// @name Utility functions for querying and setting PGO counts + /// @{ + + /// \brief Set maximum function count in PGO mode + void setMaximumFunctionCount(uint64_t); + + /// \brief Returns maximum function count in PGO mode + Optional<uint64_t> getMaximumFunctionCount(); + /// @} }; /// An raw_ostream inserter for modules. @@ -693,7 +654,7 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef) inline Module *unwrap(LLVMModuleProviderRef MP) { return reinterpret_cast<Module*>(MP); } - + } // End llvm namespace #endif diff --git a/include/llvm/IR/ModuleSlotTracker.h b/include/llvm/IR/ModuleSlotTracker.h index c37dcecf8e40..49730a66bdf6 100644 --- a/include/llvm/IR/ModuleSlotTracker.h +++ b/include/llvm/IR/ModuleSlotTracker.h @@ -17,6 +17,7 @@ namespace llvm { class Module; class Function; class SlotTracker; +class Value; /// Manage lifetime of a slot tracker for printing IR. /// @@ -61,6 +62,13 @@ public: /// Purge the currently incorporated function and incorporate \c F. If \c F /// is currently incorporated, this is a no-op. void incorporateFunction(const Function &F); + + /// Return the slot number of the specified local value. + /// + /// A function that defines this value should be incorporated prior to calling + /// this method. + /// Return -1 if the value is not in the function's SlotTracker. + int getLocalSlot(const Value *V); }; } // end namespace llvm diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 4166babd63e5..2ceb53d21b7a 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -203,7 +203,8 @@ public: for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { if (DebugLogging) - dbgs() << "Running pass: " << Passes[Idx]->name() << "\n"; + dbgs() << "Running pass: " << Passes[Idx]->name() << " on " + << IR.getName() << "\n"; PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM); diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 41154e6441a9..f4d7d8c44416 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -1272,6 +1272,46 @@ inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMax(const Opnd0 &Op0, return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1); } +template <typename Opnd_t> struct Signum_match { + Opnd_t Val; + Signum_match(const Opnd_t &V) : Val(V) {} + + template <typename OpTy> bool match(OpTy *V) { + unsigned TypeSize = V->getType()->getScalarSizeInBits(); + if (TypeSize == 0) + return false; + + unsigned ShiftWidth = TypeSize - 1; + Value *OpL = nullptr, *OpR = nullptr; + + // This is the representation of signum we match: + // + // signum(x) == (x >> 63) | (-x >>u 63) + // + // An i1 value is its own signum, so it's correct to match + // + // signum(x) == (x >> 0) | (-x >>u 0) + // + // for i1 values. + + auto LHS = m_AShr(m_Value(OpL), m_SpecificInt(ShiftWidth)); + auto RHS = m_LShr(m_Neg(m_Value(OpR)), m_SpecificInt(ShiftWidth)); + auto Signum = m_Or(LHS, RHS); + + return Signum.match(V) && OpL == OpR && Val.match(OpL); + } +}; + +/// \brief Matches a signum pattern. +/// +/// signum(x) = +/// x > 0 -> 1 +/// x == 0 -> 0 +/// x < 0 -> -1 +template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) { + return Signum_match<Val_t>(V); +} + } // end namespace PatternMatch } // end namespace llvm diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index 4ab1f8497adb..7310c5697a7e 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -173,7 +173,7 @@ public: /// range adapter for call arguments iterator_range<arg_iterator> call_args() const { - return iterator_range<arg_iterator>(arg_begin(), arg_end()); + return make_range(arg_begin(), arg_end()); } /// \brief Return true if the call or the callee has the given attribute. @@ -201,8 +201,7 @@ public: /// range adapter for GC transition arguments iterator_range<arg_iterator> gc_transition_args() const { - return iterator_range<arg_iterator>(gc_transition_args_begin(), - gc_transition_args_end()); + return make_range(gc_transition_args_begin(), gc_transition_args_end()); } /// Number of additional arguments excluding those intended @@ -225,7 +224,7 @@ public: /// range adapter for vm state arguments iterator_range<arg_iterator> vm_state_args() const { - return iterator_range<arg_iterator>(vm_state_begin(), vm_state_end()); + return make_range(vm_state_begin(), vm_state_end()); } typename CallSiteTy::arg_iterator gc_args_begin() const { @@ -235,9 +234,13 @@ public: return getCallSite().arg_end(); } + unsigned gcArgsStartIdx() const { + return gc_args_begin() - getInstruction()->op_begin(); + } + /// range adapter for gc arguments iterator_range<arg_iterator> gc_args() const { - return iterator_range<arg_iterator>(gc_args_begin(), gc_args_end()); + return make_range(gc_args_begin(), gc_args_end()); } /// Get list of all gc reloactes linked to this statepoint @@ -320,7 +323,7 @@ public: bool isTiedToInvoke() const { const Value *Token = RelocateCS.getArgument(0); - return isa<ExtractValueInst>(Token) || isa<InvokeInst>(Token); + return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token); } /// Get enclosed relocate intrinsic @@ -332,7 +335,7 @@ public: // This takes care both of relocates for call statepoints and relocates // on normal path of invoke statepoint. - if (!isa<ExtractValueInst>(Token)) { + if (!isa<LandingPadInst>(Token)) { return cast<Instruction>(Token); } @@ -396,16 +399,10 @@ StatepointBase<FunTy, InstructionTy, ValueTy, CallSiteTy>::getRelocates() LandingPadInst *LandingPad = cast<InvokeInst>(getInstruction())->getLandingPadInst(); - // Search for extract value from landingpad instruction to which - // gc relocates will be attached + // Search for gc relocates that are attached to this landingpad. for (const User *LandingPadUser : LandingPad->users()) { - if (!isa<ExtractValueInst>(LandingPadUser)) - continue; - - // gc relocates should be attached to this extract value - for (const User *U : LandingPadUser->users()) - if (isGCRelocate(U)) - Result.push_back(GCRelocateOperands(U)); + if (isGCRelocate(LandingPadUser)) + Result.push_back(GCRelocateOperands(LandingPadUser)); } return Result; } diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h index 0a5149c3d938..5fc48d10d63f 100644 --- a/include/llvm/IR/SymbolTableListTraits.h +++ b/include/llvm/IR/SymbolTableListTraits.h @@ -29,31 +29,66 @@ namespace llvm { class ValueSymbolTable; - -template<typename NodeTy> class ilist_iterator; -template<typename NodeTy, typename Traits> class iplist; -template<typename Ty> struct ilist_traits; + +template <typename NodeTy> class ilist_iterator; +template <typename NodeTy, typename Traits> class iplist; +template <typename Ty> struct ilist_traits; + +template <typename NodeTy> +struct SymbolTableListSentinelTraits + : public ilist_embedded_sentinel_traits<NodeTy> {}; + +/// Template metafunction to get the parent type for a symbol table list. +/// +/// Implementations create a typedef called \c type so that we only need a +/// single template parameter for the list and traits. +template <typename NodeTy> struct SymbolTableListParentType {}; +class Argument; +class BasicBlock; +class Function; +class Instruction; +class GlobalVariable; +class GlobalAlias; +class Module; +#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \ + template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; }; +DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock) +DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function) +DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function) +DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module) +DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module) +DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module) +#undef DEFINE_SYMBOL_TABLE_PARENT_TYPE + +template <typename NodeTy> class SymbolTableList; // ValueSubClass - The type of objects that I hold, e.g. Instruction. // ItemParentClass - The type of object that owns the list, e.g. BasicBlock. // -template<typename ValueSubClass, typename ItemParentClass> -class SymbolTableListTraits : public ilist_default_traits<ValueSubClass> { - typedef ilist_traits<ValueSubClass> TraitsClass; +template <typename ValueSubClass> +class SymbolTableListTraits + : public ilist_nextprev_traits<ValueSubClass>, + public SymbolTableListSentinelTraits<ValueSubClass>, + public ilist_node_traits<ValueSubClass> { + typedef SymbolTableList<ValueSubClass> ListTy; + typedef + typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass; + public: SymbolTableListTraits() {} +private: /// getListOwner - Return the object that owns this list. If this is a list /// of instructions, it returns the BasicBlock that owns them. ItemParentClass *getListOwner() { size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass:: getSublistAccess(static_cast<ValueSubClass*>(nullptr))))); - iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this)); + ListTy *Anchor(static_cast<ListTy *>(this)); return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)- Offset); } - static iplist<ValueSubClass> &getList(ItemParentClass *Par) { + static ListTy &getList(ItemParentClass *Par) { return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr)); } @@ -61,9 +96,10 @@ public: return Par ? toPtr(Par->getValueSymbolTable()) : nullptr; } +public: void addNodeToList(ValueSubClass *V); void removeNodeFromList(ValueSubClass *V); - void transferNodesFromList(ilist_traits<ValueSubClass> &L2, + void transferNodesFromList(SymbolTableListTraits &L2, ilist_iterator<ValueSubClass> first, ilist_iterator<ValueSubClass> last); //private: @@ -73,6 +109,14 @@ public: static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; } }; +/// List that automatically updates parent links and symbol tables. +/// +/// When nodes are inserted into and removed from this list, the associated +/// symbol table will be automatically updated. Similarly, parent links get +/// updated automatically. +template <typename NodeTy> +class SymbolTableList : public iplist<NodeTy, SymbolTableListTraits<NodeTy>> {}; + } // End llvm namespace #endif diff --git a/include/llvm/IR/TrackingMDRef.h b/include/llvm/IR/TrackingMDRef.h index e24112154e16..97efaff7a377 100644 --- a/include/llvm/IR/TrackingMDRef.h +++ b/include/llvm/IR/TrackingMDRef.h @@ -14,15 +14,11 @@ #ifndef LLVM_IR_TRACKINGMDREF_H #define LLVM_IR_TRACKINGMDREF_H -#include "llvm/IR/MetadataTracking.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/Casting.h" namespace llvm { -class Metadata; -class MDNode; -class ValueAsMetadata; - /// \brief Tracking metadata reference. /// /// This class behaves like \a TrackingVH, but for metadata. diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index 6ab0bd0631a0..b2920dd3de63 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -15,7 +15,6 @@ #ifndef LLVM_IR_TYPE_H #define LLVM_IR_TYPE_H -#include "llvm-c/Core.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/CBindingWrapping.h" @@ -38,10 +37,10 @@ template<class GraphType> struct GraphTraits; /// they are never changed. Also note that only one instance of a particular /// type is ever created. Thus seeing if two types are equal is a matter of /// doing a trivial pointer comparison. To enforce that no two equal instances -/// are created, Type instances can only be created via static factory methods +/// are created, Type instances can only be created via static factory methods /// in class Type and in derived classes. Once allocated, Types are never /// free'd. -/// +/// class Type { public: //===--------------------------------------------------------------------===// @@ -63,45 +62,36 @@ public: LabelTyID, ///< 7: Labels MetadataTyID, ///< 8: Metadata X86_MMXTyID, ///< 9: MMX vectors (64 bits, X86 specific) + TokenTyID, ///< 10: Tokens // Derived types... see DerivedTypes.h file. // Make sure FirstDerivedTyID stays up to date! - IntegerTyID, ///< 10: Arbitrary bit width integers - FunctionTyID, ///< 11: Functions - StructTyID, ///< 12: Structures - ArrayTyID, ///< 13: Arrays - PointerTyID, ///< 14: Pointers - VectorTyID ///< 15: SIMD 'packed' format, or other vector type + IntegerTyID, ///< 11: Arbitrary bit width integers + FunctionTyID, ///< 12: Functions + StructTyID, ///< 13: Structures + ArrayTyID, ///< 14: Arrays + PointerTyID, ///< 15: Pointers + VectorTyID ///< 16: SIMD 'packed' format, or other vector type }; private: /// Context - This refers to the LLVMContext in which this type was uniqued. LLVMContext &Context; - // Due to Ubuntu GCC bug 910363: - // https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/910363 - // Bitpack ID and SubclassData manually. - // Note: TypeID : low 8 bit; SubclassData : high 24 bit. - uint32_t IDAndSubclassData; + TypeID ID : 8; // The current base type of this type. + unsigned SubclassData : 24; // Space for subclasses to store data. protected: friend class LLVMContextImpl; explicit Type(LLVMContext &C, TypeID tid) - : Context(C), IDAndSubclassData(0), - NumContainedTys(0), ContainedTys(nullptr) { - setTypeID(tid); - } + : Context(C), ID(tid), SubclassData(0), + NumContainedTys(0), ContainedTys(nullptr) {} ~Type() = default; - void setTypeID(TypeID ID) { - IDAndSubclassData = (ID & 0xFF) | (IDAndSubclassData & 0xFFFFFF00); - assert(getTypeID() == ID && "TypeID data too large for field"); - } - - unsigned getSubclassData() const { return IDAndSubclassData >> 8; } - + unsigned getSubclassData() const { return SubclassData; } + void setSubclassData(unsigned val) { - IDAndSubclassData = (IDAndSubclassData & 0xFF) | (val << 8); + SubclassData = val; // Ensure we don't have any accidental truncation. assert(getSubclassData() == val && "Subclass data too large for field"); } @@ -118,7 +108,7 @@ protected: Type * const *ContainedTys; public: - void print(raw_ostream &O) const; + void print(raw_ostream &O, bool IsForDebug = false) const; void dump() const; /// getContext - Return the LLVMContext in which this type was uniqued. @@ -131,7 +121,7 @@ public: /// getTypeID - Return the type id for the type. This will return one /// of the TypeID enum elements defined above. /// - TypeID getTypeID() const { return (TypeID)(IDAndSubclassData & 0xFF); } + TypeID getTypeID() const { return ID; } /// isVoidTy - Return true if this is 'void'. bool isVoidTy() const { return getTypeID() == VoidTyID; } @@ -141,7 +131,7 @@ public: /// isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type. bool isFloatTy() const { return getTypeID() == FloatTyID; } - + /// isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type. bool isDoubleTy() const { return getTypeID() == DoubleTyID; } @@ -181,16 +171,19 @@ public: /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP. /// bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); } - + /// isLabelTy - Return true if this is 'label'. bool isLabelTy() const { return getTypeID() == LabelTyID; } /// isMetadataTy - Return true if this is 'metadata'. bool isMetadataTy() const { return getTypeID() == MetadataTyID; } + /// isTokenTy - Return true if this is 'token'. + bool isTokenTy() const { return getTypeID() == TokenTyID; } + /// isIntegerTy - True if this is an instance of IntegerType. /// - bool isIntegerTy() const { return getTypeID() == IntegerTyID; } + bool isIntegerTy() const { return getTypeID() == IntegerTyID; } /// isIntegerTy - Return true if this is an IntegerType of the given width. bool isIntegerTy(unsigned Bitwidth) const; @@ -199,7 +192,7 @@ public: /// integer types. /// bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); } - + /// isFunctionTy - True if this is an instance of FunctionType. /// bool isFunctionTy() const { return getTypeID() == FunctionTyID; } @@ -220,14 +213,14 @@ public: /// pointer types. /// bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); } - + /// isVectorTy - True if this is an instance of VectorType. /// bool isVectorTy() const { return getTypeID() == VectorTyID; } - /// canLosslesslyBitCastTo - Return true if this type could be converted - /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts - /// are valid for types of the same size only where no re-interpretation of + /// canLosslesslyBitCastTo - Return true if this type could be converted + /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts + /// are valid for types of the same size only where no re-interpretation of /// the bits is done. /// @brief Determine if this type could be losslessly bitcast to Ty bool canLosslesslyBitCastTo(Type *Ty) const; @@ -265,7 +258,7 @@ public: /// get the actual size for a particular target, it is reasonable to use the /// DataLayout subsystem to do this. /// - bool isSized(SmallPtrSetImpl<const Type*> *Visited = nullptr) const { + bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const { // If it's a primitive, it is always sized. if (getTypeID() == IntegerTyID || isFloatingPointTy() || getTypeID() == PointerTyID || @@ -304,8 +297,7 @@ public: /// getScalarType - If this is a vector type, return the element type, /// otherwise return 'this'. - const Type *getScalarType() const LLVM_READONLY; - Type *getScalarType() LLVM_READONLY; + Type *getScalarType() const LLVM_READONLY; //===--------------------------------------------------------------------===// // Type Iteration support. @@ -344,30 +336,30 @@ public: // example) is shorthand for cast<VectorType>(Ty)->getNumElements(). This is // only intended to cover the core methods that are frequently used, helper // methods should not be added here. - - unsigned getIntegerBitWidth() const; - Type *getFunctionParamType(unsigned i) const; - unsigned getFunctionNumParams() const; - bool isFunctionVarArg() const; - - StringRef getStructName() const; - unsigned getStructNumElements() const; - Type *getStructElementType(unsigned N) const; - - Type *getSequentialElementType() const; - - uint64_t getArrayNumElements() const; + inline unsigned getIntegerBitWidth() const; + + inline Type *getFunctionParamType(unsigned i) const; + inline unsigned getFunctionNumParams() const; + inline bool isFunctionVarArg() const; + + inline StringRef getStructName() const; + inline unsigned getStructNumElements() const; + inline Type *getStructElementType(unsigned N) const; + + inline Type *getSequentialElementType() const; + + inline uint64_t getArrayNumElements() const; Type *getArrayElementType() const { return getSequentialElementType(); } - unsigned getVectorNumElements() const; + inline unsigned getVectorNumElements() const; Type *getVectorElementType() const { return getSequentialElementType(); } Type *getPointerElementType() const { return getSequentialElementType(); } /// \brief Get the address space of this pointer or pointer vector type. - unsigned getPointerAddressSpace() const; - + inline unsigned getPointerAddressSpace() const; + //===--------------------------------------------------------------------===// // Static members exported by the Type class itself. Useful for getting // instances of Type. @@ -389,6 +381,7 @@ public: static Type *getFP128Ty(LLVMContext &C); static Type *getPPC_FP128Ty(LLVMContext &C); static Type *getX86_MMXTy(LLVMContext &C); + static Type *getTokenTy(LLVMContext &C); static IntegerType *getIntNTy(LLVMContext &C, unsigned N); static IntegerType *getInt1Ty(LLVMContext &C); static IntegerType *getInt8Ty(LLVMContext &C); @@ -396,7 +389,7 @@ public: static IntegerType *getInt32Ty(LLVMContext &C); static IntegerType *getInt64Ty(LLVMContext &C); static IntegerType *getInt128Ty(LLVMContext &C); - + //===--------------------------------------------------------------------===// // Convenience methods for getting pointer types with one of the above builtin // types as pointee. @@ -417,13 +410,13 @@ public: /// getPointerTo - Return a pointer to the current type. This is equivalent /// to PointerType::get(Foo, AddrSpace). - PointerType *getPointerTo(unsigned AddrSpace = 0); + PointerType *getPointerTo(unsigned AddrSpace = 0) const; private: /// isSizedDerivedType - Derived types like structures and arrays are sized /// iff all of the members of the type are sized as well. Since asking for /// their size is relatively uncommon, move this operation out of line. - bool isSizedDerivedType(SmallPtrSetImpl<const Type*> *Visited = nullptr) const; + bool isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited = nullptr) const; }; // Printing of types. @@ -439,13 +432,11 @@ template <> struct isa_impl<PointerType, Type> { } }; - //===----------------------------------------------------------------------===// // Provide specializations of GraphTraits to be able to treat a type as a // graph of sub types. - -template <> struct GraphTraits<Type*> { +template <> struct GraphTraits<Type *> { typedef Type NodeType; typedef Type::subtype_iterator ChildIteratorType; @@ -483,7 +474,7 @@ inline Type **unwrap(LLVMTypeRef* Tys) { inline LLVMTypeRef *wrap(Type **Tys) { return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys)); } - + } // End llvm namespace #endif diff --git a/include/llvm/IR/TypeFinder.h b/include/llvm/IR/TypeFinder.h index 73a63ad0349e..5f3854377c16 100644 --- a/include/llvm/IR/TypeFinder.h +++ b/include/llvm/IR/TypeFinder.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file contains the declaration of the TypeFinder class. +// This file contains the declaration of the TypeFinder class. // //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 160d71b03e7f..a738677f8e5b 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -25,7 +25,6 @@ #ifndef LLVM_IR_USE_H #define LLVM_IR_USE_H -#include "llvm-c/Core.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Compiler.h" diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h index b7c2418d348d..1cabf03d1b00 100644 --- a/include/llvm/IR/UseListOrder.h +++ b/include/llvm/IR/UseListOrder.h @@ -34,7 +34,7 @@ struct UseListOrder { UseListOrder(const Value *V, const Function *F, size_t ShuffleSize) : V(V), F(F), Shuffle(ShuffleSize) {} - UseListOrder() : V(0), F(0) {} + UseListOrder() : V(nullptr), F(nullptr) {} UseListOrder(UseListOrder &&X) : V(X.V), F(X.F), Shuffle(std::move(X.Shuffle)) {} UseListOrder &operator=(UseListOrder &&X) { @@ -53,4 +53,4 @@ typedef std::vector<UseListOrder> UseListOrderStack; } // end namespace llvm -#endif +#endif // LLVM_IR_USELISTORDER_H diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 93614fab5759..885ae197d228 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -19,6 +19,7 @@ #ifndef LLVM_IR_USER_H #define LLVM_IR_USER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Value.h" @@ -39,6 +40,9 @@ class User : public Value { friend struct HungoffOperandTraits; virtual void anchor(); + LLVM_ATTRIBUTE_ALWAYS_INLINE inline static void * + allocateFixedOperandUser(size_t, unsigned, unsigned); + protected: /// Allocate a User with an operand pointer co-allocated. /// @@ -51,7 +55,17 @@ protected: /// This is used for subclasses which have a fixed number of operands. void *operator new(size_t Size, unsigned Us); - User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps) + /// Allocate a User with the operands co-allocated. If DescBytes is non-zero + /// then allocate an additional DescBytes bytes before the operands. These + /// bytes can be accessed by calling getDescriptor. + /// + /// DescBytes needs to be divisible by sizeof(void *). The allocated + /// descriptor, if any, is aligned to sizeof(void *) bytes. + /// + /// This is used for subclasses which have a fixed number of operands. + void *operator new(size_t Size, unsigned Us, unsigned DescBytes); + + User(Type *ty, unsigned vty, Use *, unsigned NumOps) : Value(ty, vty) { assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands"); NumUserOperands = NumOps; @@ -137,6 +151,12 @@ public: unsigned getNumOperands() const { return NumUserOperands; } + /// Returns the descriptor co-allocated with this User instance. + ArrayRef<const uint8_t> getDescriptor() const; + + /// Returns the descriptor co-allocated with this User instance. + MutableArrayRef<uint8_t> getDescriptor(); + /// Set the number of operands on a GlobalVariable. /// /// GlobalVariable always allocates space for a single operands, but @@ -150,19 +170,6 @@ public: NumUserOperands = NumOps; } - /// Set the number of operands on a Function. - /// - /// Function always allocates space for a single operands, but - /// doesn't always use it. - /// - /// FIXME: As that the number of operands is used to find the start of - /// the allocated memory in operator delete, we need to always think we have - /// 1 operand before delete. - void setFunctionNumOperands(unsigned NumOps) { - assert(NumOps <= 1 && "Function can only have 0 or 1 operands"); - NumUserOperands = NumOps; - } - /// \brief Subclasses with hung off uses need to manage the operand count /// themselves. In these instances, the operand count isn't used to find the /// OperandList, so there's no issue in having the operand count change. @@ -213,7 +220,7 @@ public: return value_op_iterator(op_end()); } iterator_range<value_op_iterator> operand_values() { - return iterator_range<value_op_iterator>(value_op_begin(), value_op_end()); + return make_range(value_op_begin(), value_op_end()); } /// \brief Drop all references to operands. diff --git a/include/llvm/IR/Value.def b/include/llvm/IR/Value.def index c2a0639603ed..4c5d452fc3c3 100644 --- a/include/llvm/IR/Value.def +++ b/include/llvm/IR/Value.def @@ -70,6 +70,7 @@ HANDLE_CONSTANT(ConstantArray) HANDLE_CONSTANT(ConstantStruct) HANDLE_CONSTANT(ConstantVector) HANDLE_CONSTANT(ConstantPointerNull) +HANDLE_CONSTANT(ConstantTokenNone) HANDLE_METADATA_VALUE(MetadataAsValue) HANDLE_INLINE_ASM_VALUE(InlineAsm) @@ -79,7 +80,7 @@ HANDLE_INSTRUCTION(Instruction) // don't add new values here! HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function) -HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantPointerNull) +HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantTokenNone) #undef HANDLE_GLOBAL_VALUE #undef HANDLE_CONSTANT diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 17a80c82d1bc..bb7ff278fdef 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -14,7 +14,6 @@ #ifndef LLVM_IR_VALUE_H #define LLVM_IR_VALUE_H -#include "llvm-c/Core.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Use.h" #include "llvm/Support/CBindingWrapping.h" @@ -104,12 +103,13 @@ protected: /// /// Note, this should *NOT* be used directly by any class other than User. /// User uses this value to find the Use list. - enum : unsigned { NumUserOperandsBits = 29 }; + enum : unsigned { NumUserOperandsBits = 28 }; unsigned NumUserOperands : NumUserOperandsBits; bool IsUsedByMD : 1; bool HasName : 1; bool HasHungOffUses : 1; + bool HasDescriptor : 1; private: template <typename UseT> // UseT == 'Use' or 'const Use' @@ -201,8 +201,9 @@ public: /// \brief Implement operator<< on Value. /// @{ - void print(raw_ostream &O) const; - void print(raw_ostream &O, ModuleSlotTracker &MST) const; + void print(raw_ostream &O, bool IsForDebug = false) const; + void print(raw_ostream &O, ModuleSlotTracker &MST, + bool IsForDebug = false) const; /// @} /// \brief Print the name of this Value out to the specified raw_ostream. @@ -272,36 +273,91 @@ public: //---------------------------------------------------------------------- // Methods for handling the chain of uses of this Value. // - bool use_empty() const { return UseList == nullptr; } + // Materializing a function can introduce new uses, so these methods come in + // two variants: + // The methods that start with materialized_ check the uses that are + // currently known given which functions are materialized. Be very careful + // when using them since you might not get all uses. + // The methods that don't start with materialized_ assert that modules is + // fully materialized. +#ifdef NDEBUG + void assertModuleIsMaterialized() const {} +#else + void assertModuleIsMaterialized() const; +#endif + + bool use_empty() const { + assertModuleIsMaterialized(); + return UseList == nullptr; + } - typedef use_iterator_impl<Use> use_iterator; + typedef use_iterator_impl<Use> use_iterator; typedef use_iterator_impl<const Use> const_use_iterator; - use_iterator use_begin() { return use_iterator(UseList); } - const_use_iterator use_begin() const { return const_use_iterator(UseList); } - use_iterator use_end() { return use_iterator(); } - const_use_iterator use_end() const { return const_use_iterator(); } + use_iterator materialized_use_begin() { return use_iterator(UseList); } + const_use_iterator materialized_use_begin() const { + return const_use_iterator(UseList); + } + use_iterator use_begin() { + assertModuleIsMaterialized(); + return materialized_use_begin(); + } + const_use_iterator use_begin() const { + assertModuleIsMaterialized(); + return materialized_use_begin(); + } + use_iterator use_end() { return use_iterator(); } + const_use_iterator use_end() const { return const_use_iterator(); } + iterator_range<use_iterator> materialized_uses() { + return make_range(materialized_use_begin(), use_end()); + } + iterator_range<const_use_iterator> materialized_uses() const { + return make_range(materialized_use_begin(), use_end()); + } iterator_range<use_iterator> uses() { - return iterator_range<use_iterator>(use_begin(), use_end()); + assertModuleIsMaterialized(); + return materialized_uses(); } iterator_range<const_use_iterator> uses() const { - return iterator_range<const_use_iterator>(use_begin(), use_end()); + assertModuleIsMaterialized(); + return materialized_uses(); } - bool user_empty() const { return UseList == nullptr; } + bool user_empty() const { + assertModuleIsMaterialized(); + return UseList == nullptr; + } - typedef user_iterator_impl<User> user_iterator; + typedef user_iterator_impl<User> user_iterator; typedef user_iterator_impl<const User> const_user_iterator; - user_iterator user_begin() { return user_iterator(UseList); } - const_user_iterator user_begin() const { return const_user_iterator(UseList); } - user_iterator user_end() { return user_iterator(); } - const_user_iterator user_end() const { return const_user_iterator(); } - User *user_back() { return *user_begin(); } - const User *user_back() const { return *user_begin(); } + user_iterator materialized_user_begin() { return user_iterator(UseList); } + const_user_iterator materialized_user_begin() const { + return const_user_iterator(UseList); + } + user_iterator user_begin() { + assertModuleIsMaterialized(); + return materialized_user_begin(); + } + const_user_iterator user_begin() const { + assertModuleIsMaterialized(); + return materialized_user_begin(); + } + user_iterator user_end() { return user_iterator(); } + const_user_iterator user_end() const { return const_user_iterator(); } + User *user_back() { + assertModuleIsMaterialized(); + return *materialized_user_begin(); + } + const User *user_back() const { + assertModuleIsMaterialized(); + return *materialized_user_begin(); + } iterator_range<user_iterator> users() { - return iterator_range<user_iterator>(user_begin(), user_end()); + assertModuleIsMaterialized(); + return make_range(materialized_user_begin(), user_end()); } iterator_range<const_user_iterator> users() const { - return iterator_range<const_user_iterator>(user_begin(), user_end()); + assertModuleIsMaterialized(); + return make_range(materialized_user_begin(), user_end()); } /// \brief Return true if there is exactly one user of this value. @@ -493,7 +549,28 @@ private: template <class Compare> static Use *mergeUseLists(Use *L, Use *R, Compare Cmp) { Use *Merged; - mergeUseListsImpl(L, R, &Merged, Cmp); + Use **Next = &Merged; + + for (;;) { + if (!L) { + *Next = R; + break; + } + if (!R) { + *Next = L; + break; + } + if (Cmp(*R, *L)) { + *Next = R; + Next = &R->Next; + R = R->Next; + } else { + *Next = L; + Next = &L->Next; + L = L->Next; + } + } + return Merged; } @@ -586,25 +663,6 @@ template <class Compare> void Value::sortUseList(Compare Cmp) { } } -template <class Compare> -void Value::mergeUseListsImpl(Use *L, Use *R, Use **Next, Compare Cmp) { - if (!L) { - *Next = R; - return; - } - if (!R) { - *Next = L; - return; - } - if (Cmp(*R, *L)) { - *Next = R; - mergeUseListsImpl(L, R->Next, &R->Next, Cmp); - return; - } - *Next = L; - mergeUseListsImpl(L->Next, R, &L->Next, Cmp); -} - // isa - Provide some specializations of isa so that we don't have to include // the subtype header files to test to see if the value is a subclass... // diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index 53fa80a626aa..3c2805913ef5 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -52,13 +52,21 @@ protected: Weak }; + ValueHandleBase(const ValueHandleBase &RHS) + : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} + + ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) + : PrevPair(nullptr, Kind), Next(nullptr), V(RHS.V) { + if (isValid(V)) + AddToExistingUseList(RHS.getPrevPtr()); + } + private: PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; ValueHandleBase *Next; Value* V; - ValueHandleBase(const ValueHandleBase&) = delete; public: explicit ValueHandleBase(HandleBaseKind Kind) : PrevPair(nullptr, Kind), Next(nullptr), V(nullptr) {} @@ -67,11 +75,7 @@ public: if (isValid(V)) AddToUseList(); } - ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) - : PrevPair(nullptr, Kind), Next(nullptr), V(RHS.V) { - if (isValid(V)) - AddToExistingUseList(RHS.getPrevPtr()); - } + ~ValueHandleBase() { if (isValid(V)) RemoveFromUseList(); @@ -145,6 +149,8 @@ public: WeakVH(const WeakVH &RHS) : ValueHandleBase(Weak, RHS) {} + WeakVH &operator=(const WeakVH &RHS) = default; + Value *operator=(Value *RHS) { return ValueHandleBase::operator=(RHS); } @@ -314,7 +320,6 @@ class TrackingVH : public ValueHandleBase { public: TrackingVH() : ValueHandleBase(Tracking) {} TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {} - TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {} operator ValueTy*() const { return getValPtr(); @@ -324,10 +329,6 @@ public: setValPtr(RHS); return getValPtr(); } - ValueTy *operator=(const TrackingVH<ValueTy> &RHS) { - setValPtr(RHS.getValPtr()); - return getValPtr(); - } ValueTy *operator->() const { return getValPtr(); } ValueTy &operator*() const { return *getValPtr(); } @@ -339,15 +340,13 @@ public: /// when the underlying Value has RAUW called on it or is destroyed. This /// class can be used as the key of a map, as long as the user takes it out of /// the map before calling setValPtr() (since the map has to rearrange itself -/// when the pointer changes). Unlike ValueHandleBase, this class has a vtable -/// and a virtual destructor. +/// when the pointer changes). Unlike ValueHandleBase, this class has a vtable. class CallbackVH : public ValueHandleBase { virtual void anchor(); protected: - CallbackVH(const CallbackVH &RHS) - : ValueHandleBase(Callback, RHS) {} - - virtual ~CallbackVH() {} + ~CallbackVH() = default; + CallbackVH(const CallbackVH &) = default; + CallbackVH &operator=(const CallbackVH &) = default; void setValPtr(Value *P) { ValueHandleBase::operator=(P); diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h index 4d00b637609c..ad518ac053b2 100644 --- a/include/llvm/IR/ValueMap.h +++ b/include/llvm/IR/ValueMap.h @@ -214,8 +214,8 @@ private: // This CallbackVH updates its ValueMap when the contained Value changes, // according to the user's preferences expressed through the Config object. -template<typename KeyT, typename ValueT, typename Config> -class ValueMapCallbackVH : public CallbackVH { +template <typename KeyT, typename ValueT, typename Config> +class ValueMapCallbackVH final : public CallbackVH { friend class ValueMap<KeyT, ValueT, Config>; friend struct DenseMapInfo<ValueMapCallbackVH>; typedef ValueMap<KeyT, ValueT, Config> ValueMapT; diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h index bf1fade1ccef..65bd7fc2fec1 100644 --- a/include/llvm/IR/ValueSymbolTable.h +++ b/include/llvm/IR/ValueSymbolTable.h @@ -14,13 +14,13 @@ #ifndef LLVM_IR_VALUESYMBOLTABLE_H #define LLVM_IR_VALUESYMBOLTABLE_H +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Value.h" #include "llvm/Support/DataTypes.h" namespace llvm { - template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; + template <typename ValueSubClass> class SymbolTableListTraits; class BasicBlock; class Function; class NamedMDNode; @@ -33,12 +33,12 @@ namespace llvm { /// class ValueSymbolTable { friend class Value; - friend class SymbolTableListTraits<Argument, Function>; - friend class SymbolTableListTraits<BasicBlock, Function>; - friend class SymbolTableListTraits<Instruction, BasicBlock>; - friend class SymbolTableListTraits<Function, Module>; - friend class SymbolTableListTraits<GlobalVariable, Module>; - friend class SymbolTableListTraits<GlobalAlias, Module>; + friend class SymbolTableListTraits<Argument>; + friend class SymbolTableListTraits<BasicBlock>; + friend class SymbolTableListTraits<Instruction>; + friend class SymbolTableListTraits<Function>; + friend class SymbolTableListTraits<GlobalVariable>; + friend class SymbolTableListTraits<GlobalAlias>; /// @name Types /// @{ public: @@ -55,7 +55,6 @@ public: /// @name Constructors /// @{ public: - ValueSymbolTable() : vmap(0), LastUnique(0) {} ~ValueSymbolTable(); @@ -63,9 +62,8 @@ public: /// @name Accessors /// @{ public: - /// This method finds the value with the given \p Name in the - /// the symbol table. + /// the symbol table. /// @returns the value associated with the \p Name /// @brief Lookup a named Value. Value *lookup(StringRef Name) const { return vmap.lookup(Name); } @@ -97,30 +95,32 @@ public: /// @brief Get a const_iterator to the end of the symbol table. inline const_iterator end() const { return vmap.end(); } - -/// @} -/// @name Mutators -/// @{ + + /// @} + /// @name Mutators + /// @{ private: + ValueName *makeUniqueName(Value *V, SmallString<256> &UniqueName); + /// This method adds the provided value \p N to the symbol table. The Value - /// must have a name which is used to place the value in the symbol table. + /// must have a name which is used to place the value in the symbol table. /// If the inserted name conflicts, this renames the value. /// @brief Add a named value to the symbol table void reinsertValue(Value *V); - + /// createValueName - This method attempts to create a value name and insert /// it into the symbol table with the specified name. If it conflicts, it /// auto-renames the name and returns that instead. ValueName *createValueName(StringRef Name, Value *V); - + /// This method removes a value from the symbol table. It leaves the /// ValueName attached to the value, but it is no longer inserted in the /// symtab. void removeValueName(ValueName *V); - -/// @} -/// @name Internal Data -/// @{ + + /// @} + /// @name Internal Data + /// @{ private: ValueMap vmap; ///< The map that holds the symbol table. mutable uint32_t LastUnique; ///< Counter for tracking unique names |
