diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /include/llvm/IR | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Notes
Diffstat (limited to 'include/llvm/IR')
102 files changed, 4953 insertions, 2863 deletions
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index 497dca44547c..5f514b9c47d2 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -1,9 +1,8 @@ //===-- llvm/Argument.h - Definition of the Argument class ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -79,6 +78,9 @@ public: /// If this is a byval or inalloca argument, return its alignment. unsigned getParamAlignment() const; + /// If this is a byval argument, return its type. + Type *getParamByValType() const; + /// Return true if this argument has the nest attribute. bool hasNestAttr() const; @@ -91,6 +93,9 @@ public: /// Return true if this argument has the sret attribute. bool hasStructRetAttr() const; + /// Return true if this argument has the inreg attribute. + bool hasInRegAttr() const; + /// Return true if this argument has the returned attribute. bool hasReturnedAttr() const; @@ -119,6 +124,8 @@ public: /// Check if an argument has a given attribute. bool hasAttribute(Attribute::AttrKind Kind) const; + Attribute getAttribute(Attribute::AttrKind Kind) const; + /// Method for support type inquiry through isa, cast, and dyn_cast. static bool classof(const Value *V) { return V->getValueID() == ArgumentVal; diff --git a/include/llvm/IR/AssemblyAnnotationWriter.h b/include/llvm/IR/AssemblyAnnotationWriter.h index 6e1f5c43e12e..3fd3c57a6796 100644 --- a/include/llvm/IR/AssemblyAnnotationWriter.h +++ b/include/llvm/IR/AssemblyAnnotationWriter.h @@ -1,9 +1,8 @@ //===-- AssemblyAnnotationWriter.h - Annotation .ll files -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 9fc4614af010..06cc09e1cfc7 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -1,9 +1,8 @@ //===- llvm/Attributes.h - Container for Attributes -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -91,6 +90,7 @@ public: static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0); static Attribute get(LLVMContext &Context, StringRef Kind, StringRef Val = StringRef()); + static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty); /// Return a uniquified Attribute object that has the specific /// alignment set. @@ -103,6 +103,7 @@ public: static Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional<unsigned> &NumElemsArg); + static Attribute getWithByValType(LLVMContext &Context, Type *Ty); //===--------------------------------------------------------------------===// // Attribute Accessors @@ -118,6 +119,9 @@ public: /// attribute. bool isStringAttribute() const; + /// Return true if the attribute is a type attribute. + bool isTypeAttribute() const; + /// Return true if the attribute is present. bool hasAttribute(AttrKind Val) const; @@ -140,6 +144,10 @@ public: /// attribute to be a string attribute. StringRef getValueAsString() const; + /// Return the attribute's value as a Type. This requires the attribute to be + /// a type attribute. + Type *getValueAsType() const; + /// Returns the alignment field of an attribute as a byte alignment /// value. unsigned getAlignment() const; @@ -280,6 +288,7 @@ public: unsigned getStackAlignment() const; uint64_t getDereferenceableBytes() const; uint64_t getDereferenceableOrNullBytes() const; + Type *getByValType() const; std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; std::string getAsString(bool InAttrGrp = false) const; @@ -599,6 +608,9 @@ public: /// Return the alignment for the specified function parameter. unsigned getParamAlignment(unsigned ArgNo) const; + /// Return the byval type for the specified function parameter. + Type *getParamByValType(unsigned ArgNo) const; + /// Get the stack alignment. unsigned getStackAlignment(unsigned Index) const; @@ -698,6 +710,7 @@ class AttrBuilder { uint64_t DerefBytes = 0; uint64_t DerefOrNullBytes = 0; uint64_t AllocSizeArgs = 0; + Type *ByValType = nullptr; public: AttrBuilder() = default; @@ -773,6 +786,9 @@ public: /// dereferenceable_or_null attribute exists (zero is returned otherwise). uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; } + /// Retrieve the byval type. + Type *getByValType() const { return ByValType; } + /// Retrieve the allocsize args, if the allocsize attribute exists. If it /// doesn't exist, pair(0, 0) is returned. std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; @@ -797,6 +813,9 @@ public: AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg, const Optional<unsigned> &NumElemsArg); + /// This turns a byval type into the form used internally in Attribute. + AttrBuilder &addByValAttr(Type *Ty); + /// Add an allocsize attribute, using the representation returned by /// Attribute.getIntValue(). AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr); diff --git a/include/llvm/IR/Attributes.td b/include/llvm/IR/Attributes.td index e786d85d05a8..153046d2311c 100644 --- a/include/llvm/IR/Attributes.td +++ b/include/llvm/IR/Attributes.td @@ -85,6 +85,9 @@ def NoCapture : EnumAttr<"nocapture">; /// Call cannot be duplicated. def NoDuplicate : EnumAttr<"noduplicate">; +/// Function does not deallocate memory. +def NoFree : EnumAttr<"nofree">; + /// Disable implicit floating point insts. def NoImplicitFloat : EnumAttr<"noimplicitfloat">; @@ -106,6 +109,9 @@ def NoRedZone : EnumAttr<"noredzone">; /// Mark the function as not returning. def NoReturn : EnumAttr<"noreturn">; +/// Function does not synchronize. +def NoSync : EnumAttr<"nosync">; + /// Disable Indirect Branch Tracking. def NoCfCheck : EnumAttr<"nocf_check">; @@ -130,6 +136,9 @@ def ReadOnly : EnumAttr<"readonly">; /// Return value is always equal to this argument. def Returned : EnumAttr<"returned">; +/// Parameter is required to be a trivial constant. +def ImmArg : EnumAttr<"immarg">; + /// Function can return twice. def ReturnsTwice : EnumAttr<"returns_twice">; @@ -176,6 +185,9 @@ def SanitizeMemory : EnumAttr<"sanitize_memory">; /// HWAddressSanitizer is on. def SanitizeHWAddress : EnumAttr<"sanitize_hwaddress">; +/// MemTagSanitizer is on. +def SanitizeMemTag : EnumAttr<"sanitize_memtag">; + /// Speculative Load Hardening is enabled. /// /// Note that this uses the default compatibility (always compatible during @@ -193,6 +205,9 @@ def SwiftSelf : EnumAttr<"swiftself">; /// Function must be in a unwind table. def UWTable : EnumAttr<"uwtable">; +/// Function always comes back to callsite. +def WillReturn : EnumAttr<"willreturn">; + /// Function only writes to memory. def WriteOnly : EnumAttr<"writeonly">; @@ -221,6 +236,7 @@ def : CompatRule<"isEqual<SanitizeAddressAttr>">; def : CompatRule<"isEqual<SanitizeThreadAttr>">; def : CompatRule<"isEqual<SanitizeMemoryAttr>">; def : CompatRule<"isEqual<SanitizeHWAddressAttr>">; +def : CompatRule<"isEqual<SanitizeMemTagAttr>">; def : CompatRule<"isEqual<SafeStackAttr>">; def : CompatRule<"isEqual<ShadowCallStackAttr>">; diff --git a/include/llvm/IR/AutoUpgrade.h b/include/llvm/IR/AutoUpgrade.h index 8cf574c6a138..017ad93d8a2a 100644 --- a/include/llvm/IR/AutoUpgrade.h +++ b/include/llvm/IR/AutoUpgrade.h @@ -1,9 +1,8 @@ //===- AutoUpgrade.h - AutoUpgrade Helpers ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -47,9 +46,9 @@ namespace llvm { /// so that it can update all calls to the old function. void UpgradeCallsToIntrinsic(Function* F); - /// This checks for global variables which should be upgraded. It returns true - /// if it requires upgrading. - bool UpgradeGlobalVariable(GlobalVariable *GV); + /// This checks for global variables which should be upgraded. It it requires + /// upgrading, returns a pointer to the upgraded variable. + GlobalVariable *UpgradeGlobalVariable(GlobalVariable *GV); /// This checks for module flags which should be upgraded. It returns true if /// module is modified. diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 99eac33f742e..69555af50e1f 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -1,9 +1,8 @@ //===- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -363,7 +362,7 @@ public: /// This is actually not used to update the Predecessor list, but is actually /// used to update the PHI nodes that reside in the block. Note that this /// should be called while the predecessor still refers to this block. - void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false); + void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false); bool canSplitPredecessors() const; @@ -391,6 +390,14 @@ public: /// direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } + /// Update all phi nodes in this basic block to refer to basic block \p New + /// instead of basic block \p Old. + void replacePhiUsesWith(BasicBlock *Old, BasicBlock *New); + + /// Update all phi nodes in this basic block's successors to refer to basic + /// block \p New instead of basic block \p Old. + void replaceSuccessorsPhiUsesWith(BasicBlock *Old, BasicBlock *New); + /// Update all phi nodes in this basic block's successors to refer to basic /// block \p New instead of to it. void replaceSuccessorsPhiUsesWith(BasicBlock *New); diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index 8385c4647e12..55aff7137e86 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -1,9 +1,8 @@ //===- CFG.h ----------------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -238,10 +237,6 @@ public: } }; -template <typename T, typename U> struct isPodLike<SuccIterator<T, U>> { - static const bool value = isPodLike<T>::value; -}; - using succ_iterator = SuccIterator<Instruction, BasicBlock>; using succ_const_iterator = SuccIterator<const Instruction, const BasicBlock>; using succ_range = iterator_range<succ_iterator>; diff --git a/include/llvm/IR/CFGDiff.h b/include/llvm/IR/CFGDiff.h index da4373f7bce2..57b62dd66a47 100644 --- a/include/llvm/IR/CFGDiff.h +++ b/include/llvm/IR/CFGDiff.h @@ -1,9 +1,8 @@ //===- CFGDiff.h - Define a CFG snapshot. -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index a3e78049f4be..b47a96c5d5fa 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -1,15 +1,14 @@ //===- CallSite.h - Abstract Call & Invoke instrs ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the CallSite class, which is a handy wrapper for code that -// wants to treat Call and Invoke instructions in a generic way. When in non- -// mutation context (e.g. an analysis) ImmutableCallSite should be used. +// wants to treat Call, Invoke and CallBr instructions in a generic way. When +// in non-mutation context (e.g. an analysis) ImmutableCallSite should be used. // Finally, when some degree of customization is necessary between these two // extremes, CallSiteBase<> can be supplied with fine-tuned parameters. // @@ -18,7 +17,7 @@ // They are efficiently copyable, assignable and constructable, with cost // equivalent to copying a pointer (notice that they have only a single data // member). The internal representation carries a flag which indicates which of -// the two variants is enclosed. This allows for cheaper checks when various +// the three variants is enclosed. This allows for cheaper checks when various // accessors of CallSite are employed. // //===----------------------------------------------------------------------===// @@ -49,45 +48,50 @@ namespace Intrinsic { enum ID : unsigned; } -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, +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, + typename CallBrTy = const CallBrInst, typename IterTy = User::const_op_iterator> class CallSiteBase { protected: - PointerIntPair<InstrTy*, 1, bool> I; + PointerIntPair<InstrTy *, 2, int> I; CallSiteBase() = default; - CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); } - CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); } + CallSiteBase(CallTy *CI) : I(CI, 1) { assert(CI); } + CallSiteBase(InvokeTy *II) : I(II, 0) { assert(II); } + CallSiteBase(CallBrTy *CBI) : I(CBI, 2) { assert(CBI); } explicit CallSiteBase(ValTy *II) { *this = get(II); } private: /// This static method is like a constructor. It will create an appropriate - /// call site for a Call or Invoke instruction, but it can also create a null - /// initialized CallSiteBase object for something which is NOT a call site. + /// call site for a Call, Invoke or CallBr instruction, but it can also create + /// a null initialized CallSiteBase object for something which is NOT a call + /// site. static CallSiteBase get(ValTy *V) { if (InstrTy *II = dyn_cast<InstrTy>(V)) { if (II->getOpcode() == Instruction::Call) return CallSiteBase(static_cast<CallTy*>(II)); - else if (II->getOpcode() == Instruction::Invoke) + if (II->getOpcode() == Instruction::Invoke) return CallSiteBase(static_cast<InvokeTy*>(II)); + if (II->getOpcode() == Instruction::CallBr) + return CallSiteBase(static_cast<CallBrTy *>(II)); } return CallSiteBase(); } public: - /// Return true if a CallInst is enclosed. Note that !isCall() does not mean - /// an InvokeInst is enclosed. It may also signify a NULL instruction pointer. - bool isCall() const { return I.getInt(); } + /// Return true if a CallInst is enclosed. + bool isCall() const { return I.getInt() == 1; } + + /// Return true if a InvokeInst is enclosed. !I.getInt() may also signify a + /// NULL instruction pointer, so check that. + bool isInvoke() const { return getInstruction() && I.getInt() == 0; } - /// Return true if a InvokeInst is enclosed. - bool isInvoke() const { return getInstruction() && !I.getInt(); } + /// Return true if a CallBrInst is enclosed. + bool isCallBr() const { return I.getInt() == 2; } InstrTy *getInstruction() const { return I.getPointer(); } InstrTy *operator->() const { return I.getPointer(); } @@ -98,7 +102,7 @@ public: /// Return the pointer to function that is being called. ValTy *getCalledValue() const { - assert(getInstruction() && "Not a call or invoke instruction!"); + assert(getInstruction() && "Not a call, invoke or callbr instruction!"); return *getCallee(); } @@ -115,16 +119,19 @@ public: return false; if (isa<FunTy>(V) || isa<Constant>(V)) return false; - if (const CallInst *CI = dyn_cast<CallInst>(getInstruction())) { - if (CI->isInlineAsm()) + if (const CallBase *CB = dyn_cast<CallBase>(getInstruction())) + if (CB->isInlineAsm()) return false; - } return true; } - /// Set the callee to the specified value. + /// Set the callee to the specified value. Unlike the function of the same + /// name on CallBase, does not modify the type! void setCalledFunction(Value *V) { - assert(getInstruction() && "Not a call or invoke instruction!"); + assert(getInstruction() && "Not a call, callbr, or invoke instruction!"); + assert(cast<PointerType>(V->getType())->getElementType() == + cast<CallBase>(getInstruction())->getFunctionType() && + "New callee type does not match FunctionType on call"); *getCallee() = V; } @@ -189,7 +196,7 @@ public: } void setArgument(unsigned ArgNo, Value* newVal) { - assert(getInstruction() && "Not a call or invoke instruction!"); + assert(getInstruction() && "Not a call, invoke or callbr instruction!"); assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); getInstruction()->setOperand(ArgNo, newVal); } @@ -203,7 +210,7 @@ public: /// Given a use for an argument, get the argument number that corresponds to /// it. unsigned getArgumentNo(const Use *U) const { - assert(getInstruction() && "Not a call or invoke instruction!"); + assert(getInstruction() && "Not a call, invoke or callbr instruction!"); assert(isArgOperand(U) && "Argument # out of range!"); return U - arg_begin(); } @@ -227,7 +234,7 @@ public: /// 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(getInstruction() && "Not a call, invoke or callbr instruction!"); assert(isDataOperand(U) && "Data operand # out of range!"); return U - data_operands_begin(); } @@ -237,18 +244,19 @@ public: using data_operand_iterator = IterTy; /// 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. + /// the call / invoke / callbr argument list and bundle operands. For invokes, + /// this is the set of instruction operands except the invoke target and the + /// two successor blocks; for calls this is the set of instruction operands + /// except the call target; for callbrs the number of labels to skip must be + /// determined first. IterTy data_operands_begin() const { assert(getInstruction() && "Not a call or invoke instruction!"); - return (*this)->op_begin(); + return cast<CallBase>(getInstruction())->data_operands_begin(); } IterTy data_operands_end() const { assert(getInstruction() && "Not a call or invoke instruction!"); - return (*this)->op_end() - (isCall() ? 1 : 3); + return cast<CallBase>(getInstruction())->data_operands_end(); } iterator_range<IterTy> data_ops() const { return make_range(data_operands_begin(), data_operands_end()); @@ -277,17 +285,19 @@ public: return isCall() && cast<CallInst>(getInstruction())->isTailCall(); } -#define CALLSITE_DELEGATE_GETTER(METHOD) \ - InstrTy *II = getInstruction(); \ - return isCall() \ - ? cast<CallInst>(II)->METHOD \ - : cast<InvokeInst>(II)->METHOD +#define CALLSITE_DELEGATE_GETTER(METHOD) \ + InstrTy *II = getInstruction(); \ + return isCall() ? cast<CallInst>(II)->METHOD \ + : isCallBr() ? cast<CallBrInst>(II)->METHOD \ + : cast<InvokeInst>(II)->METHOD -#define CALLSITE_DELEGATE_SETTER(METHOD) \ - InstrTy *II = getInstruction(); \ - if (isCall()) \ - cast<CallInst>(II)->METHOD; \ - else \ +#define CALLSITE_DELEGATE_SETTER(METHOD) \ + InstrTy *II = getInstruction(); \ + if (isCall()) \ + cast<CallInst>(II)->METHOD; \ + else if (isCallBr()) \ + cast<CallBrInst>(II)->METHOD; \ + else \ cast<InvokeInst>(II)->METHOD unsigned getNumArgOperands() const { @@ -303,9 +313,7 @@ public: } bool isInlineAsm() const { - if (isCall()) - return cast<CallInst>(getInstruction())->isInlineAsm(); - return false; + return cast<CallBase>(getInstruction())->isInlineAsm(); } /// Get the calling convention of the call. @@ -389,10 +397,10 @@ public: /// 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. + /// Normal call, invoke or callbr 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 Kind) const { CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, Kind)); } @@ -407,6 +415,11 @@ public: CALLSITE_DELEGATE_GETTER(getParamAlignment(ArgNo)); } + /// Extract the byval type for a call or parameter (nullptr=unknown). + Type *getParamByValType(unsigned ArgNo) const { + CALLSITE_DELEGATE_GETTER(getParamByValType(ArgNo)); + } + /// Extract the number of dereferenceable bytes for a call or parameter /// (0=unknown). uint64_t getDereferenceableBytes(unsigned i) const { @@ -580,13 +593,9 @@ public: #undef CALLSITE_DELEGATE_SETTER 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); + cast<CallBase>(getInstruction())->getOperandBundlesAsDefs(Defs); } /// Determine whether this data operand is not captured. @@ -662,12 +671,13 @@ private: class CallSite : public CallSiteBase<Function, BasicBlock, Value, User, Use, Instruction, CallInst, InvokeInst, - User::op_iterator> { + CallBrInst, User::op_iterator> { public: CallSite() = default; CallSite(CallSiteBase B) : CallSiteBase(B) {} CallSite(CallInst *CI) : CallSiteBase(CI) {} CallSite(InvokeInst *II) : CallSiteBase(II) {} + CallSite(CallBrInst *CBI) : CallSiteBase(CBI) {} explicit CallSite(Instruction *II) : CallSiteBase(II) {} explicit CallSite(Value *V) : CallSiteBase(V) {} @@ -683,6 +693,182 @@ private: User::op_iterator getCallee() const; }; +/// AbstractCallSite +/// +/// An abstract call site is a wrapper that allows to treat direct, +/// indirect, and callback calls the same. If an abstract call site +/// represents a direct or indirect call site it behaves like a stripped +/// down version of a normal call site object. The abstract call site can +/// also represent a callback call, thus the fact that the initially +/// called function (=broker) may invoke a third one (=callback callee). +/// In this case, the abstract call site hides the middle man, hence the +/// broker function. The result is a representation of the callback call, +/// inside the broker, but in the context of the original call to the broker. +/// +/// There are up to three functions involved when we talk about callback call +/// sites. The caller (1), which invokes the broker function. The broker +/// function (2), that will invoke the callee zero or more times. And finally +/// the callee (3), which is the target of the callback call. +/// +/// The abstract call site will handle the mapping from parameters to arguments +/// depending on the semantic of the broker function. However, it is important +/// to note that the mapping is often partial. Thus, some arguments of the +/// call/invoke instruction are mapped to parameters of the callee while others +/// are not. +class AbstractCallSite { +public: + + /// The encoding of a callback with regards to the underlying instruction. + struct CallbackInfo { + + /// For direct/indirect calls the parameter encoding is empty. If it is not, + /// the abstract call site represents a callback. In that case, the first + /// element of the encoding vector represents which argument of the call + /// site CS is the callback callee. The remaining elements map parameters + /// (identified by their position) to the arguments that will be passed + /// through (also identified by position but in the call site instruction). + /// + /// NOTE that we use LLVM argument numbers (starting at 0) and not + /// clang/source argument numbers (starting at 1). The -1 entries represent + /// unknown values that are passed to the callee. + using ParameterEncodingTy = SmallVector<int, 0>; + ParameterEncodingTy ParameterEncoding; + + }; + +private: + + /// The underlying call site: + /// caller -> callee, if this is a direct or indirect call site + /// caller -> broker function, if this is a callback call site + CallSite CS; + + /// The encoding of a callback with regards to the underlying instruction. + CallbackInfo CI; + +public: + /// Sole constructor for abstract call sites (ACS). + /// + /// An abstract call site can only be constructed through a llvm::Use because + /// each operand (=use) of an instruction could potentially be a different + /// abstract call site. Furthermore, even if the value of the llvm::Use is the + /// same, and the user is as well, the abstract call sites might not be. + /// + /// If a use is not associated with an abstract call site the constructed ACS + /// will evaluate to false if converted to a boolean. + /// + /// If the use is the callee use of a call or invoke instruction, the + /// constructed abstract call site will behave as a llvm::CallSite would. + /// + /// If the use is not a callee use of a call or invoke instruction, the + /// callback metadata is used to determine the argument <-> parameter mapping + /// as well as the callee of the abstract call site. + AbstractCallSite(const Use *U); + + /// Conversion operator to conveniently check for a valid/initialized ACS. + explicit operator bool() const { return (bool)CS; } + + /// Return the underlying instruction. + Instruction *getInstruction() const { return CS.getInstruction(); } + + /// Return the call site abstraction for the underlying instruction. + CallSite getCallSite() const { return CS; } + + /// Return true if this ACS represents a direct call. + bool isDirectCall() const { + return !isCallbackCall() && !CS.isIndirectCall(); + } + + /// Return true if this ACS represents an indirect call. + bool isIndirectCall() const { + return !isCallbackCall() && CS.isIndirectCall(); + } + + /// Return true if this ACS represents a callback call. + bool isCallbackCall() const { + // For a callback call site the callee is ALWAYS stored first in the + // transitive values vector. Thus, a non-empty vector indicates a callback. + return !CI.ParameterEncoding.empty(); + } + + /// Return true if @p UI is the use that defines the callee of this ACS. + bool isCallee(Value::const_user_iterator UI) const { + return isCallee(&UI.getUse()); + } + + /// Return true if @p U is the use that defines the callee of this ACS. + bool isCallee(const Use *U) const { + if (isDirectCall()) + return CS.isCallee(U); + + assert(!CI.ParameterEncoding.empty() && + "Callback without parameter encoding!"); + + return (int)CS.getArgumentNo(U) == CI.ParameterEncoding[0]; + } + + /// Return the number of parameters of the callee. + unsigned getNumArgOperands() const { + if (isDirectCall()) + return CS.getNumArgOperands(); + // Subtract 1 for the callee encoding. + return CI.ParameterEncoding.size() - 1; + } + + /// Return the operand index of the underlying instruction associated with @p + /// Arg. + int getCallArgOperandNo(Argument &Arg) const { + return getCallArgOperandNo(Arg.getArgNo()); + } + + /// Return the operand index of the underlying instruction associated with + /// the function parameter number @p ArgNo or -1 if there is none. + int getCallArgOperandNo(unsigned ArgNo) const { + if (isDirectCall()) + return ArgNo; + // Add 1 for the callee encoding. + return CI.ParameterEncoding[ArgNo + 1]; + } + + /// Return the operand of the underlying instruction associated with @p Arg. + Value *getCallArgOperand(Argument &Arg) const { + return getCallArgOperand(Arg.getArgNo()); + } + + /// Return the operand of the underlying instruction associated with the + /// function parameter number @p ArgNo or nullptr if there is none. + Value *getCallArgOperand(unsigned ArgNo) const { + if (isDirectCall()) + return CS.getArgOperand(ArgNo); + // Add 1 for the callee encoding. + return CI.ParameterEncoding[ArgNo + 1] >= 0 + ? CS.getArgOperand(CI.ParameterEncoding[ArgNo + 1]) + : nullptr; + } + + /// Return the operand index of the underlying instruction associated with the + /// callee of this ACS. Only valid for callback calls! + int getCallArgOperandNoForCallee() const { + assert(isCallbackCall()); + assert(CI.ParameterEncoding.size() && CI.ParameterEncoding[0] > 0); + return CI.ParameterEncoding[0]; + } + + /// Return the pointer to function that is being called. + Value *getCalledValue() const { + if (isDirectCall()) + return CS.getCalledValue(); + return CS.getArgOperand(getCallArgOperandNoForCallee()); + } + + /// Return the function being called if this is a direct call, otherwise + /// return null (if it's an indirect call). + Function *getCalledFunction() const { + Value *V = getCalledValue(); + return V ? dyn_cast<Function>(V->stripPointerCasts()) : nullptr; + } +}; + template <> struct DenseMapInfo<CallSite> { using BaseInfo = DenseMapInfo<decltype(CallSite::I)>; @@ -713,6 +899,7 @@ public: ImmutableCallSite() = default; ImmutableCallSite(const CallInst *CI) : CallSiteBase(CI) {} ImmutableCallSite(const InvokeInst *II) : CallSiteBase(II) {} + ImmutableCallSite(const CallBrInst *CBI) : CallSiteBase(CBI) {} explicit ImmutableCallSite(const Instruction *II) : CallSiteBase(II) {} explicit ImmutableCallSite(const Value *V) : CallSiteBase(V) {} ImmutableCallSite(CallSite CS) : CallSiteBase(CS.getInstruction()) {} diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 49c3be960373..399c6ad521fa 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -1,9 +1,8 @@ //===- llvm/CallingConv.h - LLVM Calling Conventions ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h index 555121e928f7..f712a16dd318 100644 --- a/include/llvm/IR/Comdat.h +++ b/include/llvm/IR/Comdat.h @@ -1,9 +1,8 @@ //===- llvm/IR/Comdat.h - Comdat definitions --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 98437f8eff1f..931576651224 100644 --- a/include/llvm/IR/Constant.h +++ b/include/llvm/IR/Constant.h @@ -1,9 +1,8 @@ //===-- llvm/Constant.h - Constant class definition -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -91,6 +90,10 @@ public: /// elements. bool containsUndefElement() const; + /// Return true if this is a vector constant that includes any constant + /// expressions. + bool containsConstantExpression() const; + /// Return true if evaluation of this constant could trap. This is true for /// things like constant expressions that could divide by zero. bool canTrap() const; diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h index da5bba7ba141..5a5cabfd0206 100644 --- a/include/llvm/IR/ConstantFolder.h +++ b/include/llvm/IR/ConstantFolder.h @@ -1,9 +1,8 @@ //===- ConstantFolder.h - Constant folding helper ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -135,6 +134,10 @@ public: return ConstantExpr::getNot(C); } + Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return ConstantExpr::get(Opc, C); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 1adda3269abc..91f3f31abe17 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -1,9 +1,8 @@ //===- ConstantRange.h - Represent a range ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -42,14 +41,25 @@ namespace llvm { class MDNode; class raw_ostream; +struct KnownBits; /// This class represents a range of values. class LLVM_NODISCARD ConstantRange { APInt Lower, Upper; + /// Create empty constant range with same bitwidth. + ConstantRange getEmpty() const { + return ConstantRange(getBitWidth(), false); + } + + /// Create full constant range with same bitwidth. + ConstantRange getFull() const { + return ConstantRange(getBitWidth(), true); + } + public: - /// Initialize a full (the default) or empty set for the specified bit width. - explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true); + /// Initialize a full or empty set for the specified bit width. + explicit ConstantRange(uint32_t BitWidth, bool isFullSet); /// Initialize a range to hold the single specified value. ConstantRange(APInt Value); @@ -59,6 +69,29 @@ public: /// assert out if the two APInt's are not the same bit width. ConstantRange(APInt Lower, APInt Upper); + /// Create empty constant range with the given bit width. + static ConstantRange getEmpty(uint32_t BitWidth) { + return ConstantRange(BitWidth, false); + } + + /// Create full constant range with the given bit width. + static ConstantRange getFull(uint32_t BitWidth) { + return ConstantRange(BitWidth, true); + } + + /// Create non-empty constant range with the given bounds. If Lower and + /// Upper are the same, a full range is returned. + static ConstantRange getNonEmpty(APInt Lower, APInt Upper) { + if (Lower == Upper) + return getFull(Lower.getBitWidth()); + return ConstantRange(std::move(Lower), std::move(Upper)); + } + + /// Initialize a range based on a known bits constraint. The IsSigned flag + /// indicates whether the constant range should not wrap in the signed or + /// unsigned domain. + static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned); + /// Produce the smallest range such that all values that may satisfy the given /// predicate with any value contained within Other is contained in the /// returned range. Formally, this returns a superset of @@ -91,14 +124,12 @@ public: static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other); - /// Return the largest range containing all X such that "X BinOpC Y" is - /// guaranteed not to wrap (overflow) for all Y in Other. + /// Produce the largest range containing all X such that "X BinOp Y" is + /// guaranteed not to wrap (overflow) for *all* Y in Other. However, there may + /// be *some* Y in Other for which additional X not contained in the result + /// also do not overflow. /// - /// NB! The returned set does *not* contain **all** possible values of X for - /// which "X BinOpC Y" does not wrap -- some viable values of X may be - /// missing, so you cannot use this to constrain X's range. E.g. in the - /// fourth example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), - /// but (-2) is not in the set returned. + /// NoWrapKind must be one of OBO::NoUnsignedWrap or OBO::NoSignedWrap. /// /// Examples: /// typedef OverflowingBinaryOperator OBO; @@ -106,17 +137,19 @@ public: /// MGNR(Add, [i8 1, 2), OBO::NoSignedWrap) == [-128, 127) /// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap) == [0, -1) /// MGNR(Add, [i8 0, 1), OBO::NoUnsignedWrap) == Full Set - /// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap | OBO::NoSignedWrap) - /// == [0,INT_MAX) /// MGNR(Add, [i8 -1, 6), OBO::NoSignedWrap) == [INT_MIN+1, INT_MAX-4) /// MGNR(Sub, [i8 1, 2), OBO::NoSignedWrap) == [-127, 128) /// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap) == [1, 0) - /// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap | OBO::NoSignedWrap) - /// == [1,INT_MAX) static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind); + /// Produce the range that contains X if and only if "X BinOp Other" does + /// not wrap. + static ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, + const APInt &Other, + unsigned NoWrapKind); + /// Set up \p Pred and \p RHS such that /// ConstantRange::makeExactICmpRegion(Pred, RHS) == *this. Return true if /// successful. @@ -138,14 +171,32 @@ public: /// Return true if this set contains no members. bool isEmptySet() const; - /// Return true if this set wraps around the top of the range. - /// For example: [100, 8). + /// Return true if this set wraps around the unsigned domain. Special cases: + /// * Empty set: Not wrapped. + /// * Full set: Not wrapped. + /// * [X, 0) == [X, Max]: Not wrapped. bool isWrappedSet() const; - /// Return true if this set wraps around the INT_MIN of - /// its bitwidth. For example: i8 [120, 140). + /// Return true if the exclusive upper bound wraps around the unsigned + /// domain. Special cases: + /// * Empty set: Not wrapped. + /// * Full set: Not wrapped. + /// * [X, 0): Wrapped. + bool isUpperWrapped() const; + + /// Return true if this set wraps around the signed domain. Special cases: + /// * Empty set: Not wrapped. + /// * Full set: Not wrapped. + /// * [X, SignedMin) == [X, SignedMax]: Not wrapped. bool isSignWrappedSet() const; + /// Return true if the (exclusive) upper bound wraps around the signed + /// domain. Special cases: + /// * Empty set: Not wrapped. + /// * Full set: Not wrapped. + /// * [X, SignedMin): Wrapped. + bool isUpperSignWrapped() const; + /// Return true if the specified value is in the set. bool contains(const APInt &Val) const; @@ -170,15 +221,18 @@ public: /// Return true if this set contains exactly one member. bool isSingleElement() const { return getSingleElement() != nullptr; } - /// Return the number of elements in this set. - APInt getSetSize() const; - /// Compare set size of this range with the range CR. bool isSizeStrictlySmallerThan(const ConstantRange &CR) const; - // Compare set size of this range with Value. + /// Compare set size of this range with Value. bool isSizeLargerThan(uint64_t MaxSize) const; + /// Return true if all values in this range are negative. + bool isAllNegative() const; + + /// Return true if all values in this range are non-negative. + bool isAllNonNegative() const; + /// Return the largest unsigned value contained in the ConstantRange. APInt getUnsignedMax() const; @@ -206,20 +260,30 @@ public: /// the sets). ConstantRange difference(const ConstantRange &CR) const; - /// Return the range that results from the intersection of - /// this range with another range. The resultant range is guaranteed to - /// include all elements contained in both input ranges, and to have the - /// smallest possible set size that does so. Because there may be two - /// intersections with the same set size, A.intersectWith(B) might not - /// be equal to B.intersectWith(A). - ConstantRange intersectWith(const ConstantRange &CR) const; + /// If represented precisely, the result of some range operations may consist + /// of multiple disjoint ranges. As only a single range may be returned, any + /// range covering these disjoint ranges constitutes a valid result, but some + /// may be more useful than others depending on context. The preferred range + /// type specifies whether a range that is non-wrapping in the unsigned or + /// signed domain, or has the smallest size, is preferred. If a signedness is + /// preferred but all ranges are non-wrapping or all wrapping, then the + /// smallest set size is preferred. If there are multiple smallest sets, any + /// one of them may be returned. + enum PreferredRangeType { Smallest, Unsigned, Signed }; + + /// Return the range that results from the intersection of this range with + /// another range. If the intersection is disjoint, such that two results + /// are possible, the preferred range is determined by the PreferredRangeType. + ConstantRange intersectWith(const ConstantRange &CR, + PreferredRangeType Type = Smallest) const; /// Return the range that results from the union of this range /// with another range. The resultant range is guaranteed to include the /// elements of both sets, but may contain more. For example, [3, 9) union /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included /// in either set before. - ConstantRange unionWith(const ConstantRange &CR) const; + ConstantRange unionWith(const ConstantRange &CR, + PreferredRangeType Type = Smallest) const; /// Return a new range representing the possible values resulting /// from an application of the specified cast operator to this range. \p @@ -301,6 +365,23 @@ public: ConstantRange udiv(const ConstantRange &Other) const; /// Return a new range representing the possible values resulting + /// from a signed division of a value in this range and a value in + /// \p Other. Division by zero and division of SignedMin by -1 are considered + /// undefined behavior, in line with IR, and do not contribute towards the + /// result. + ConstantRange sdiv(const ConstantRange &Other) const; + + /// Return a new range representing the possible values resulting + /// from an unsigned remainder operation of a value in this range and a + /// value in \p Other. + ConstantRange urem(const ConstantRange &Other) const; + + /// Return a new range representing the possible values resulting + /// from a signed remainder operation of a value in this range and a + /// value in \p Other. + ConstantRange srem(const ConstantRange &Other) const; + + /// Return a new range representing the possible values resulting /// from a binary-and of a value in this range by a value in \p Other. ConstantRange binaryAnd(const ConstantRange &Other) const; @@ -321,9 +402,53 @@ public: /// arithmetic right shift of a value in this range and a value in \p Other. ConstantRange ashr(const ConstantRange &Other) const; + /// Perform an unsigned saturating addition of two constant ranges. + ConstantRange uadd_sat(const ConstantRange &Other) const; + + /// Perform a signed saturating addition of two constant ranges. + ConstantRange sadd_sat(const ConstantRange &Other) const; + + /// Perform an unsigned saturating subtraction of two constant ranges. + ConstantRange usub_sat(const ConstantRange &Other) const; + + /// Perform a signed saturating subtraction of two constant ranges. + ConstantRange ssub_sat(const ConstantRange &Other) const; + /// Return a new range that is the logical not of the current set. ConstantRange inverse() const; + /// Calculate absolute value range. If the original range contains signed + /// min, then the resulting range will also contain signed min. + ConstantRange abs() const; + + /// Represents whether an operation on the given constant range is known to + /// always or never overflow. + enum class OverflowResult { + /// Always overflows in the direction of signed/unsigned min value. + AlwaysOverflowsLow, + /// Always overflows in the direction of signed/unsigned max value. + AlwaysOverflowsHigh, + /// May or may not overflow. + MayOverflow, + /// Never overflows. + NeverOverflows, + }; + + /// Return whether unsigned add of the two ranges always/never overflows. + OverflowResult unsignedAddMayOverflow(const ConstantRange &Other) const; + + /// Return whether signed add of the two ranges always/never overflows. + OverflowResult signedAddMayOverflow(const ConstantRange &Other) const; + + /// Return whether unsigned sub of the two ranges always/never overflows. + OverflowResult unsignedSubMayOverflow(const ConstantRange &Other) const; + + /// Return whether signed sub of the two ranges always/never overflows. + OverflowResult signedSubMayOverflow(const ConstantRange &Other) const; + + /// Return whether unsigned mul of the two ranges always/never overflows. + OverflowResult unsignedMulMayOverflow(const ConstantRange &Other) 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 afc93cd61d47..ca56e8b9328c 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -1,9 +1,8 @@ //===-- llvm/Constants.h - Constant class subclass definitions --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index 443332b1b23c..ad9a35b55414 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -1,9 +1,8 @@ //===- DIBuilder.h - Debug Information Builder ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -707,6 +706,16 @@ namespace llvm { DITemplateParameterArray TParams = nullptr, DITypeArray ThrownTypes = nullptr); + /// Create common block entry for a Fortran common block. + /// \param Scope Scope of this common block. + /// \param decl Global variable declaration. + /// \param Name The name of this common block. + /// \param File The file this common block is defined. + /// \param LineNo Line number. + DICommonBlock *createCommonBlock(DIScope *Scope, DIGlobalVariable *decl, + StringRef Name, DIFile *File, + unsigned LineNo); + /// This creates new descriptor for a namespace with the specified /// parent scope. /// \param Scope Namespace scope diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index c144d1c13c34..ac9770a15120 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -1,9 +1,8 @@ //===- llvm/DataLayout.h - Data size & alignment info -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -109,6 +108,13 @@ struct PointerAlignElem { /// generating LLVM IR is required to generate the right target data for the /// target being codegen'd to. class DataLayout { +public: + enum class FunctionPtrAlignType { + /// The function pointer alignment is independent of the function alignment. + Independent, + /// The function pointer alignment is a multiple of the function alignment. + MultipleOfFunctionAlign, + }; private: /// Defaults to false. bool BigEndian; @@ -117,6 +123,9 @@ private: unsigned StackNaturalAlign; unsigned ProgramAddrSpace; + unsigned FunctionPtrAlign; + FunctionPtrAlignType TheFunctionPtrAlignType; + enum ManglingModeT { MM_None, MM_ELF, @@ -200,6 +209,8 @@ public: BigEndian = DL.isBigEndian(); AllocaAddrSpace = DL.AllocaAddrSpace; StackNaturalAlign = DL.StackNaturalAlign; + FunctionPtrAlign = DL.FunctionPtrAlign; + TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType; ProgramAddrSpace = DL.ProgramAddrSpace; ManglingMode = DL.ManglingMode; LegalIntWidths = DL.LegalIntWidths; @@ -257,6 +268,17 @@ public: unsigned getStackAlignment() const { return StackNaturalAlign; } unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; } + /// Returns the alignment of function pointers, which may or may not be + /// related to the alignment of functions. + /// \see getFunctionPtrAlignType + unsigned getFunctionPtrAlign() const { return FunctionPtrAlign; } + + /// Return the type of function pointer alignment. + /// \see getFunctionPtrAlign + FunctionPtrAlignType getFunctionPtrAlignType() const { + return TheFunctionPtrAlignType; + } + unsigned getProgramAddressSpace() const { return ProgramAddrSpace; } bool hasMicrosoftFastStdCallMangling() const { @@ -346,10 +368,13 @@ public: return NonIntegralAddressSpaces; } - bool isNonIntegralPointerType(PointerType *PT) const { + bool isNonIntegralAddressSpace(unsigned AddrSpace) const { ArrayRef<unsigned> NonIntegralSpaces = getNonIntegralAddressSpaces(); - return find(NonIntegralSpaces, PT->getAddressSpace()) != - NonIntegralSpaces.end(); + return find(NonIntegralSpaces, AddrSpace) != NonIntegralSpaces.end(); + } + + bool isNonIntegralPointerType(PointerType *PT) const { + return isNonIntegralAddressSpace(PT->getAddressSpace()); } bool isNonIntegralPointerType(Type *Ty) const { @@ -428,6 +453,14 @@ public: return 8 * getTypeStoreSize(Ty); } + /// Returns true if no extra padding bits are needed when storing the + /// specified type. + /// + /// For example, returns false for i19 that has a 24-bit store size. + bool typeSizeEqualsStoreSize(Type *Ty) const { + return getTypeSizeInBits(Ty) == getTypeStoreSizeInBits(Ty); + } + /// Returns the offset in bytes between successive objects of the /// specified type, including alignment padding. /// diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 01178af3c9ff..171e1621889f 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -1,9 +1,8 @@ //===- DebugInfo.h - Debug Information Helpers ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/DebugInfoFlags.def b/include/llvm/IR/DebugInfoFlags.def index ce117aa452aa..07e3d6bdc9e5 100644 --- a/include/llvm/IR/DebugInfoFlags.def +++ b/include/llvm/IR/DebugInfoFlags.def @@ -1,9 +1,8 @@ //===- llvm/IR/DebugInfoFlags.def - Debug info flag definitions -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -51,12 +50,12 @@ HANDLE_DI_FLAG((3 << 16), VirtualInheritance) HANDLE_DI_FLAG((1 << 18), IntroducedVirtual) HANDLE_DI_FLAG((1 << 19), BitField) HANDLE_DI_FLAG((1 << 20), NoReturn) -HANDLE_DI_FLAG((1 << 21), MainSubprogram) +HANDLE_DI_FLAG((1 << 21), ArgumentNotModified) HANDLE_DI_FLAG((1 << 22), TypePassByValue) HANDLE_DI_FLAG((1 << 23), TypePassByReference) HANDLE_DI_FLAG((1 << 24), EnumClass) HANDLE_DI_FLAG((1 << 25), Thunk) -HANDLE_DI_FLAG((1 << 26), Trivial) +HANDLE_DI_FLAG((1 << 26), NonTrivial) HANDLE_DI_FLAG((1 << 27), BigEndian) HANDLE_DI_FLAG((1 << 28), LittleEndian) HANDLE_DI_FLAG((1 << 29), AllCallsDescribed) @@ -85,11 +84,15 @@ HANDLE_DISP_FLAG(2u, PureVirtual) HANDLE_DISP_FLAG((1u << 2), LocalToUnit) HANDLE_DISP_FLAG((1u << 3), Definition) HANDLE_DISP_FLAG((1u << 4), Optimized) +HANDLE_DISP_FLAG((1u << 5), Pure) +HANDLE_DISP_FLAG((1u << 6), Elemental) +HANDLE_DISP_FLAG((1u << 7), Recursive) +HANDLE_DISP_FLAG((1u << 8), MainSubprogram) #ifdef DISP_FLAG_LARGEST_NEEDED // Intended to be used with ADT/BitmaskEnum.h. // NOTE: Always must be equal to largest flag, check this when adding new flags. -HANDLE_DISP_FLAG((1 << 4), Largest) +HANDLE_DISP_FLAG((1 << 8), Largest) #undef DISP_FLAG_LARGEST_NEEDED #endif diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index a461d1bd4fe8..9dc6dfbb0f68 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -1,9 +1,8 @@ //===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -61,44 +60,6 @@ namespace llvm { -/// Holds a subclass of DINode. -/// -/// FIXME: This class doesn't currently make much sense. Previously it was a -/// union beteen MDString (for ODR-uniqued types) and things like DIType. To -/// support CodeView work, it wasn't deleted outright when MDString-based type -/// references were deleted; we'll soon need a similar concept for CodeView -/// DITypeIndex. -template <class T> class TypedDINodeRef { - const Metadata *MD = nullptr; - -public: - TypedDINodeRef() = default; - TypedDINodeRef(std::nullptr_t) {} - TypedDINodeRef(const T *MD) : MD(MD) {} - - explicit TypedDINodeRef(const Metadata *MD) : MD(MD) { - assert((!MD || isa<T>(MD)) && "Expected valid type ref"); - } - - template <class U> - TypedDINodeRef( - const TypedDINodeRef<U> &X, - typename std::enable_if<std::is_convertible<U *, T *>::value>::type * = - nullptr) - : MD(X) {} - - operator Metadata *() const { return const_cast<Metadata *>(MD); } - - T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); } - - bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; } - bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; } -}; - -using DINodeRef = TypedDINodeRef<DINode>; -using DIScopeRef = TypedDINodeRef<DIScope>; -using DITypeRef = TypedDINodeRef<DIType>; - class DITypeRefArray { const MDTuple *N = nullptr; @@ -115,17 +76,19 @@ public: // FIXME: Fix callers and remove condition on N. unsigned size() const { return N ? N->getNumOperands() : 0u; } - DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); } + DIType *operator[](unsigned I) const { + return cast_or_null<DIType>(N->getOperand(I)); + } - class iterator : std::iterator<std::input_iterator_tag, DITypeRef, - std::ptrdiff_t, void, DITypeRef> { + class iterator : std::iterator<std::input_iterator_tag, DIType *, + std::ptrdiff_t, void, DIType *> { MDNode::op_iterator I = nullptr; public: iterator() = default; explicit iterator(MDNode::op_iterator I) : I(I) {} - DITypeRef operator*() const { return DITypeRef(*I); } + DIType *operator*() const { return cast_or_null<DIType>(*I); } iterator &operator++() { ++I; @@ -228,6 +191,7 @@ public: case DILexicalBlockKind: case DILexicalBlockFileKind: case DINamespaceKind: + case DICommonBlockKind: case DITemplateTypeParameterKind: case DITemplateValueParameterKind: case DIGlobalVariableKind: @@ -241,18 +205,6 @@ public: } }; -template <class T> struct simplify_type<const TypedDINodeRef<T>> { - using SimpleType = Metadata *; - - static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) { - return MD; - } -}; - -template <class T> -struct simplify_type<TypedDINodeRef<T>> - : simplify_type<const TypedDINodeRef<T>> {}; - /// Generic tagged DWARF-like metadata node. /// /// An un-specialized DWARF-like metadata node. The first operand is a @@ -459,7 +411,7 @@ public: inline Optional<StringRef> getSource() const; StringRef getName() const; - DIScopeRef getScope() const; + DIScope *getScope() const; /// Return the raw underlying file. /// @@ -486,6 +438,7 @@ public: case DILexicalBlockKind: case DILexicalBlockFileKind: case DINamespaceKind: + case DICommonBlockKind: case DIModuleKind: return true; } @@ -672,7 +625,7 @@ public: uint64_t getOffsetInBits() const { return OffsetInBits; } DIFlags getFlags() const { return Flags; } - DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } + DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } StringRef getName() const { return getStringOperand(2); } @@ -817,14 +770,12 @@ class DIDerivedType : public DIType { DWARFAddressSpace(DWARFAddressSpace) {} ~DIDerivedType() = default; - static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag, - StringRef Name, DIFile *File, unsigned Line, - DIScopeRef Scope, DITypeRef BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, - Optional<unsigned> DWARFAddressSpace, - DIFlags Flags, Metadata *ExtraData, - StorageType Storage, bool ShouldCreate = true) { + static DIDerivedType * + getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, + unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + Optional<unsigned> DWARFAddressSpace, DIFlags Flags, + Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate); @@ -858,7 +809,7 @@ public: ExtraData)) DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, - DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits, + DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData = nullptr), @@ -869,7 +820,7 @@ public: TempDIDerivedType clone() const { return cloneImpl(); } /// Get the base type this is derived from. - DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } + DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); } Metadata *getRawBaseType() const { return getOperand(3); } /// \returns The DWARF address space of the memory pointed to or referenced by @@ -889,9 +840,9 @@ public: /// Get casted version of extra data. /// @{ - DITypeRef getClassType() const { + DIType *getClassType() const { assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); - return DITypeRef(getExtraData()); + return cast_or_null<DIType>(getExtraData()); } DIObjCProperty *getObjCProperty() const { @@ -963,12 +914,12 @@ class DICompositeType : public DIType { static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, - unsigned Line, DIScopeRef Scope, DITypeRef BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang, - DITypeRef VTableHolder, DITemplateParameterArray TemplateParams, - StringRef Identifier, DIDerivedType *Discriminator, - StorageType Storage, bool ShouldCreate = true) { + unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, + DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, + DITemplateParameterArray TemplateParams, StringRef Identifier, + DIDerivedType *Discriminator, StorageType Storage, + bool ShouldCreate = true) { return getImpl( Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), @@ -995,12 +946,13 @@ class DICompositeType : public DIType { public: DEFINE_MDNODE_GET(DICompositeType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, - DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang, - DITypeRef VTableHolder, + DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, + DINodeArray Elements, unsigned RuntimeLang, + DIType *VTableHolder, DITemplateParameterArray TemplateParams = nullptr, - StringRef Identifier = "", DIDerivedType *Discriminator = nullptr), + StringRef Identifier = "", + DIDerivedType *Discriminator = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator)) @@ -1053,11 +1005,13 @@ public: unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator); - DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } + DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); } DINodeArray getElements() const { return cast_or_null<MDTuple>(getRawElements()); } - DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); } + DIType *getVTableHolder() const { + return cast_or_null<DIType>(getRawVTableHolder()); + } DITemplateParameterArray getTemplateParams() const { return cast_or_null<MDTuple>(getRawTemplateParams()); } @@ -1087,7 +1041,7 @@ public: replaceOperandWith(4, Elements.get()); } - void replaceVTableHolder(DITypeRef VTableHolder) { + void replaceVTableHolder(DIType *VTableHolder) { replaceOperandWith(5, VTableHolder); } @@ -1541,9 +1495,6 @@ public: /// /// For precise control over the data being encoded in the discriminator, /// use encodeDiscriminator/decodeDiscriminator. - /// - /// Use {get|set}BaseDiscriminator and cloneWithDuplicationFactor after reading - /// their documentation, as their behavior has side-effects. inline unsigned getDiscriminator() const; @@ -1554,7 +1505,7 @@ public: /// base discriminator is set in the new DILocation, the other encoded values /// are elided. /// If the discriminator cannot be encoded, the function returns None. - inline Optional<const DILocation *> setBaseDiscriminator(unsigned BD) const; + inline Optional<const DILocation *> cloneWithBaseDiscriminator(unsigned BD) const; /// Returns the duplication factor stored in the discriminator, or 1 if no /// duplication factor (or 0) is encoded. @@ -1570,7 +1521,7 @@ public: /// duplication factor encoded in the discriminator. The current duplication /// factor is as defined by getDuplicationFactor(). /// Returns None if encoding failed. - inline Optional<const DILocation *> cloneWithDuplicationFactor(unsigned DF) const; + inline Optional<const DILocation *> cloneByMultiplyingDuplicationFactor(unsigned DF) const; /// When two instructions are combined into a single instruction we also /// need to combine the original locations into a single location. @@ -1594,10 +1545,11 @@ public: return getUnsignedFromPrefixEncoding(D); } - /// Raw encoding of the discriminator. APIs such as setBaseDiscriminator or - /// cloneWithDuplicationFactor have certain side-effects. This API, in - /// conjunction with cloneWithDiscriminator, may be used to encode precisely - /// the values provided. \p BD: base discriminator \p DF: duplication factor + /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor + /// have certain special case behavior (e.g. treating empty duplication factor + /// as the value '1'). + /// This API, in conjunction with cloneWithDiscriminator, may be used to encode + /// the raw values provided. \p BD: base discriminator \p DF: duplication factor /// \p CI: copy index /// The return is None if the values cannot be encoded in 32 bits - for /// example, values for BD or DF larger than 12 bits. Otherwise, the return @@ -1638,9 +1590,6 @@ public: }; /// Subprogram description. -/// -/// TODO: Remove DisplayName. It's always equal to Name. -/// TODO: Split up flags. class DISubprogram : public DILocalScope { friend class LLVMContextImpl; friend class MDNode; @@ -1678,7 +1627,8 @@ public: // Helper for converting old bitfields to new flags word. static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, - unsigned Virtuality = SPFlagNonvirtual) { + unsigned Virtuality = SPFlagNonvirtual, + bool IsMainSubprogram = false) { // We're assuming virtuality is the low-order field. static_assert( int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) && @@ -1688,7 +1638,8 @@ public: (Virtuality & SPFlagVirtuality) | (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) | (IsDefinition ? SPFlagDefinition : SPFlagZero) | - (IsOptimized ? SPFlagOptimized : SPFlagZero)); + (IsOptimized ? SPFlagOptimized : SPFlagZero) | + (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero)); } private: @@ -1707,9 +1658,9 @@ private: ~DISubprogram() = default; static DISubprogram * - getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name, + getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, - DISubroutineType *Type, unsigned ScopeLine, DITypeRef ContainingType, + DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, @@ -1744,9 +1695,9 @@ private: public: DEFINE_MDNODE_GET( DISubprogram, - (DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File, + (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DISubroutineType *Type, unsigned ScopeLine, - DITypeRef ContainingType, unsigned VirtualIndex, int ThisAdjustment, + DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr, @@ -1787,6 +1738,7 @@ public: bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; } bool isDefinition() const { return getSPFlags() & SPFlagDefinition; } bool isOptimized() const { return getSPFlags() & SPFlagOptimized; } + bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; } bool isArtificial() const { return getFlags() & FlagArtificial; } bool isPrivate() const { @@ -1803,7 +1755,9 @@ public: bool areAllCallsDescribed() const { return getFlags() & FlagAllCallsDescribed; } - bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; } + bool isPure() const { return getSPFlags() & SPFlagPure; } + bool isElemental() const { return getSPFlags() & SPFlagElemental; } + bool isRecursive() const { return getSPFlags() & SPFlagRecursive; } /// Check if this is reference-qualified. /// @@ -1827,7 +1781,7 @@ public: // Returns true if this subprogram is a thunk generated by the compiler. bool isThunk() const { return getFlags() & FlagThunk; } - DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } + DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } StringRef getName() const { return getStringOperand(2); } StringRef getLinkageName() const { return getStringOperand(3); } @@ -1835,8 +1789,8 @@ public: DISubroutineType *getType() const { return cast_or_null<DISubroutineType>(getRawType()); } - DITypeRef getContainingType() const { - return DITypeRef(getRawContainingType()); + DIType *getContainingType() const { + return cast_or_null<DIType>(getRawContainingType()); } DICompileUnit *getUnit() const { @@ -2039,15 +1993,17 @@ unsigned DILocation::getCopyIdentifier() const { return getCopyIdentifierFromDiscriminator(getDiscriminator()); } -Optional<const DILocation *> DILocation::setBaseDiscriminator(unsigned D) const { - if (D == 0) +Optional<const DILocation *> DILocation::cloneWithBaseDiscriminator(unsigned D) const { + unsigned BD, DF, CI; + decodeDiscriminator(getDiscriminator(), BD, DF, CI); + if (D == BD) return this; - if (D > 0xfff) - return None; - return cloneWithDiscriminator(encodeComponent(D)); + if (Optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI)) + return cloneWithDiscriminator(*Encoded); + return None; } -Optional<const DILocation *> DILocation::cloneWithDuplicationFactor(unsigned DF) const { +Optional<const DILocation *> DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const { DF *= getDuplicationFactor(); if (DF <= 1) return this; @@ -2179,7 +2135,7 @@ protected: public: StringRef getName() const { return getStringOperand(0); } - DITypeRef getType() const { return DITypeRef(getRawType()); } + DIType *getType() const { return cast_or_null<DIType>(getRawType()); } MDString *getRawName() const { return getOperandAs<MDString>(0); } Metadata *getRawType() const { return getOperand(1); } @@ -2201,7 +2157,7 @@ class DITemplateTypeParameter : public DITemplateParameter { ~DITemplateTypeParameter() = default; static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name, - DITypeRef Type, StorageType Storage, + DIType *Type, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage, ShouldCreate); @@ -2215,7 +2171,7 @@ class DITemplateTypeParameter : public DITemplateParameter { } public: - DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type), + DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DIType *Type), (Name, Type)) DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type), (Name, Type)) @@ -2238,7 +2194,7 @@ class DITemplateValueParameter : public DITemplateParameter { ~DITemplateValueParameter() = default; static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag, - StringRef Name, DITypeRef Type, + StringRef Name, DIType *Type, Metadata *Value, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type, @@ -2255,8 +2211,9 @@ class DITemplateValueParameter : public DITemplateParameter { } public: - DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name, - DITypeRef Type, Metadata *Value), + DEFINE_MDNODE_GET(DITemplateValueParameter, + (unsigned Tag, StringRef Name, DIType *Type, + Metadata *Value), (Tag, Name, Type, Value)) DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name, Metadata *Type, Metadata *Value), @@ -2288,7 +2245,7 @@ public: DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } StringRef getName() const { return getStringOperand(1); } DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } - DITypeRef getType() const { return DITypeRef(getRawType()); } + DIType *getType() const { return cast_or_null<DIType>(getRawType()); } uint32_t getAlignInBits() const { return AlignInBits; } uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } /// Determines the size of the variable's type. @@ -2297,7 +2254,7 @@ public: /// Return the signedness of this variable's type, or None if this type is /// neither signed nor unsigned. Optional<DIBasicType::Signedness> getSignedness() const { - if (auto *BT = dyn_cast<DIBasicType>(getType().resolve())) + if (auto *BT = dyn_cast<DIBasicType>(getType())) return BT->getSignedness(); return None; } @@ -2504,6 +2461,13 @@ public: /// Return whether this is a piece of an aggregate variable. bool isFragment() const { return getFragmentInfo().hasValue(); } + /// Return whether this is an implicit location description. + bool isImplicit() const; + + /// Return whether the location is computed on the expression stack, meaning + /// it cannot be a simple register location. + bool isComplex() const; + /// Append \p Ops with operations to apply the \p Offset. static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset); @@ -2511,20 +2475,32 @@ public: /// return true with an offset of zero. bool extractIfOffset(int64_t &Offset) const; - /// Constants for DIExpression::prepend. - enum { NoDeref = false, WithDeref = true, WithStackValue = true }; + /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF + /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address + /// Space>. + static const DIExpression *extractAddressClass(const DIExpression *Expr, + unsigned &AddrClass); + + /// Used for DIExpression::prepend. + enum PrependOps : uint8_t { + ApplyOffset = 0, + DerefBefore = 1 << 0, + DerefAfter = 1 << 1, + StackValue = 1 << 2, + EntryValue = 1 << 3 + }; /// Prepend \p DIExpr with a deref and offset operation and optionally turn it - /// into a stack value. - static DIExpression *prepend(const DIExpression *Expr, bool DerefBefore, - int64_t Offset = 0, bool DerefAfter = false, - bool StackValue = false); + /// into a stack value or/and an entry value. + static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags, + int64_t Offset = 0); /// Prepend \p DIExpr with the given opcodes and optionally turn it into a /// stack value. static DIExpression *prependOpcodes(const DIExpression *Expr, SmallVectorImpl<uint64_t> &Ops, - bool StackValue = false); + bool StackValue = false, + bool EntryValue = false); /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the /// returned expression is a stack value only if \p DIExpr is a stack value. @@ -2553,17 +2529,14 @@ public: createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits); - /// Determine the relative position of the fragments described by this - /// DIExpression and \p Other. + /// Determine the relative position of the fragments passed in. /// Returns -1 if this is entirely before Other, 0 if this and Other overlap, /// 1 if this is entirely after Other. - int fragmentCmp(const DIExpression *Other) const { - auto Fragment1 = *getFragmentInfo(); - auto Fragment2 = *Other->getFragmentInfo(); - unsigned l1 = Fragment1.OffsetInBits; - unsigned l2 = Fragment2.OffsetInBits; - unsigned r1 = l1 + Fragment1.SizeInBits; - unsigned r2 = l2 + Fragment2.SizeInBits; + static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) { + uint64_t l1 = A.OffsetInBits; + uint64_t l2 = B.OffsetInBits; + uint64_t r1 = l1 + A.SizeInBits; + uint64_t r2 = l2 + B.SizeInBits; if (r1 <= l2) return -1; else if (r2 <= l1) @@ -2572,12 +2545,59 @@ public: return 0; } + /// Check if fragments overlap between a pair of FragmentInfos. + static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) { + return fragmentCmp(A, B) == 0; + } + + /// Determine the relative position of the fragments described by this + /// DIExpression and \p Other. Calls static fragmentCmp implementation. + int fragmentCmp(const DIExpression *Other) const { + auto Fragment1 = *getFragmentInfo(); + auto Fragment2 = *Other->getFragmentInfo(); + return fragmentCmp(Fragment1, Fragment2); + } + /// Check if fragments overlap between this DIExpression and \p Other. bool fragmentsOverlap(const DIExpression *Other) const { if (!isFragment() || !Other->isFragment()) return true; return fragmentCmp(Other) == 0; } + + /// Check if the expression consists of exactly one entry value operand. + /// (This is the only configuration of entry values that is supported.) + bool isEntryValue() const { + return getNumElements() > 0 && + getElement(0) == dwarf::DW_OP_entry_value; + } +}; + +inline bool operator==(const DIExpression::FragmentInfo &A, + const DIExpression::FragmentInfo &B) { + return std::tie(A.SizeInBits, A.OffsetInBits) == + std::tie(B.SizeInBits, B.OffsetInBits); +} + +inline bool operator<(const DIExpression::FragmentInfo &A, + const DIExpression::FragmentInfo &B) { + return std::tie(A.SizeInBits, A.OffsetInBits) < + std::tie(B.SizeInBits, B.OffsetInBits); +} + +template <> struct DenseMapInfo<DIExpression::FragmentInfo> { + using FragInfo = DIExpression::FragmentInfo; + static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max(); + + static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; } + + static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; } + + static unsigned getHashValue(const FragInfo &Frag) { + return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff); + } + + static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; } }; /// Global variables. @@ -2599,7 +2619,7 @@ class DIGlobalVariable : public DIVariable { static DIGlobalVariable * getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name, - StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type, + StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) { @@ -2626,7 +2646,7 @@ class DIGlobalVariable : public DIVariable { public: DEFINE_MDNODE_GET(DIGlobalVariable, (DIScope * Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned Line, DITypeRef Type, + DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, uint32_t AlignInBits), @@ -2663,6 +2683,65 @@ public: } }; +class DICommonBlock : public DIScope { + unsigned LineNo; + + friend class LLVMContextImpl; + friend class MDNode; + + DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo, + ArrayRef<Metadata *> Ops) + : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block, + Ops), LineNo(LineNo) {} + + static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope, + DIGlobalVariable *Decl, StringRef Name, + DIFile *File, unsigned LineNo, + StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name), + File, LineNo, Storage, ShouldCreate); + } + static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope, + Metadata *Decl, MDString *Name, Metadata *File, + unsigned LineNo, + StorageType Storage, bool ShouldCreate = true); + + TempDICommonBlock cloneImpl() const { + return getTemporary(getContext(), getScope(), getDecl(), getName(), + getFile(), getLineNo()); + } + +public: + DEFINE_MDNODE_GET(DICommonBlock, + (DIScope *Scope, DIGlobalVariable *Decl, StringRef Name, + DIFile *File, unsigned LineNo), + (Scope, Decl, Name, File, LineNo)) + DEFINE_MDNODE_GET(DICommonBlock, + (Metadata *Scope, Metadata *Decl, MDString *Name, + Metadata *File, unsigned LineNo), + (Scope, Decl, Name, File, LineNo)) + + TempDICommonBlock clone() const { return cloneImpl(); } + + DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } + DIGlobalVariable *getDecl() const { + return cast_or_null<DIGlobalVariable>(getRawDecl()); + } + StringRef getName() const { return getStringOperand(2); } + DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } + unsigned getLineNo() const { return LineNo; } + + Metadata *getRawScope() const { return getOperand(0); } + Metadata *getRawDecl() const { return getOperand(1); } + MDString *getRawName() const { return getOperandAs<MDString>(2); } + Metadata *getRawFile() const { return getOperand(3); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DICommonBlockKind; + } +}; + /// Local variable. /// /// TODO: Split up flags. @@ -2684,7 +2763,7 @@ class DILocalVariable : public DIVariable { static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name, DIFile *File, unsigned Line, - DITypeRef Type, unsigned Arg, DIFlags Flags, + DIType *Type, unsigned Arg, DIFlags Flags, uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File, @@ -2705,8 +2784,8 @@ class DILocalVariable : public DIVariable { public: DEFINE_MDNODE_GET(DILocalVariable, (DILocalScope * Scope, StringRef Name, DIFile *File, - unsigned Line, DITypeRef Type, unsigned Arg, - DIFlags Flags, uint32_t AlignInBits), + unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags, + uint32_t AlignInBits), (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits)) DEFINE_MDNODE_GET(DILocalVariable, (Metadata * Scope, MDString *Name, Metadata *File, @@ -2730,6 +2809,11 @@ public: bool isArtificial() const { return getFlags() & FlagArtificial; } bool isObjectPointer() const { return getFlags() & FlagObjectPointer; } + /// Check that an argument is unmodified. + bool isNotModified() const { return getFlags() & FlagArgumentNotModified; } + /// Set the flag if an argument is unmodified. + void setIsNotModified() { Flags |= FlagArgumentNotModified; } + /// Check that a location is valid for this variable. /// /// Check that \c DL exists, is in the same subprogram, and has the same @@ -2831,7 +2915,7 @@ class DIObjCProperty : public DINode { static DIObjCProperty * getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line, StringRef GetterName, StringRef SetterName, unsigned Attributes, - DITypeRef Type, StorageType Storage, bool ShouldCreate = true) { + DIType *Type, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, getCanonicalMDString(Context, Name), File, Line, getCanonicalMDString(Context, GetterName), getCanonicalMDString(Context, SetterName), Attributes, Type, @@ -2853,7 +2937,7 @@ public: DEFINE_MDNODE_GET(DIObjCProperty, (StringRef Name, DIFile *File, unsigned Line, StringRef GetterName, StringRef SetterName, - unsigned Attributes, DITypeRef Type), + unsigned Attributes, DIType *Type), (Name, File, Line, GetterName, SetterName, Attributes, Type)) DEFINE_MDNODE_GET(DIObjCProperty, @@ -2871,7 +2955,7 @@ public: DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } StringRef getGetterName() const { return getStringOperand(2); } StringRef getSetterName() const { return getStringOperand(3); } - DITypeRef getType() const { return DITypeRef(getRawType()); } + DIType *getType() const { return cast_or_null<DIType>(getRawType()); } StringRef getFilename() const { if (auto *F = getFile()) @@ -2915,8 +2999,8 @@ class DIImportedEntity : public DINode { ~DIImportedEntity() = default; static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag, - DIScope *Scope, DINodeRef Entity, - DIFile *File, unsigned Line, StringRef Name, + DIScope *Scope, DINode *Entity, DIFile *File, + unsigned Line, StringRef Name, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, Scope, Entity, File, Line, @@ -2935,8 +3019,8 @@ class DIImportedEntity : public DINode { public: DEFINE_MDNODE_GET(DIImportedEntity, - (unsigned Tag, DIScope *Scope, DINodeRef Entity, - DIFile *File, unsigned Line, StringRef Name = ""), + (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File, + unsigned Line, StringRef Name = ""), (Tag, Scope, Entity, File, Line, Name)) DEFINE_MDNODE_GET(DIImportedEntity, (unsigned Tag, Metadata *Scope, Metadata *Entity, @@ -2947,7 +3031,7 @@ public: unsigned getLine() const { return Line; } DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } - DINodeRef getEntity() const { return DINodeRef(getRawEntity()); } + DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); } StringRef getName() const { return getStringOperand(2); } DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h index 4f0d7f51b5f9..780d17a33661 100644 --- a/include/llvm/IR/DebugLoc.h +++ b/include/llvm/IR/DebugLoc.h @@ -1,9 +1,8 @@ //===- DebugLoc.h - Debug Location Information ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 9526d6287d2f..3c1d4278905f 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -1,9 +1,8 @@ //===- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -24,6 +23,7 @@ #include "llvm/IR/Type.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ScalableSize.h" #include <cassert> #include <cstdint> @@ -158,6 +158,38 @@ unsigned Type::getFunctionNumParams() const { return cast<FunctionType>(this)->getNumParams(); } +/// A handy container for a FunctionType+Callee-pointer pair, which can be +/// passed around as a single entity. This assists in replacing the use of +/// PointerType::getElementType() to access the function's type, since that's +/// slated for removal as part of the [opaque pointer types] project. +class FunctionCallee { +public: + // Allow implicit conversion from types which have a getFunctionType member + // (e.g. Function and InlineAsm). + template <typename T, typename U = decltype(&T::getFunctionType)> + FunctionCallee(T *Fn) + : FnTy(Fn ? Fn->getFunctionType() : nullptr), Callee(Fn) {} + + FunctionCallee(FunctionType *FnTy, Value *Callee) + : FnTy(FnTy), Callee(Callee) { + assert((FnTy == nullptr) == (Callee == nullptr)); + } + + FunctionCallee(std::nullptr_t) {} + + FunctionCallee() = default; + + FunctionType *getFunctionType() { return FnTy; } + + Value *getCallee() { return Callee; } + + explicit operator bool() { return Callee; } + +private: + FunctionType *FnTy = nullptr; + Value *Callee = nullptr; +}; + /// Common super class of ArrayType, StructType and VectorType. class CompositeType : public Type { protected: @@ -356,6 +388,8 @@ public: SequentialType(const SequentialType &) = delete; SequentialType &operator=(const SequentialType &) = delete; + /// For scalable vectors, this will return the minimum number of elements + /// in the vector. uint64_t getNumElements() const { return NumElements; } Type *getElementType() const { return ContainedType; } @@ -391,14 +425,37 @@ uint64_t Type::getArrayNumElements() const { /// Class to represent vector types. class VectorType : public SequentialType { - VectorType(Type *ElType, unsigned NumEl); + /// A fully specified VectorType is of the form <vscale x n x Ty>. 'n' is the + /// minimum number of elements of type Ty contained within the vector, and + /// 'vscale x' indicates that the total element count is an integer multiple + /// of 'n', where the multiple is either guaranteed to be one, or is + /// statically unknown at compile time. + /// + /// If the multiple is known to be 1, then the extra term is discarded in + /// textual IR: + /// + /// <4 x i32> - a vector containing 4 i32s + /// <vscale x 4 x i32> - a vector containing an unknown integer multiple + /// of 4 i32s + + VectorType(Type *ElType, unsigned NumEl, bool Scalable = false); + VectorType(Type *ElType, ElementCount EC); + + // If true, the total number of elements is an unknown multiple of the + // minimum 'NumElements' from SequentialType. Otherwise the total number + // of elements is exactly equal to 'NumElements'. + bool Scalable; public: VectorType(const VectorType &) = delete; VectorType &operator=(const VectorType &) = delete; /// This static method is the primary way to construct an VectorType. - static VectorType *get(Type *ElementType, unsigned NumElements); + static VectorType *get(Type *ElementType, ElementCount EC); + static VectorType *get(Type *ElementType, unsigned NumElements, + bool Scalable = false) { + return VectorType::get(ElementType, {NumElements, Scalable}); + } /// This static method gets a VectorType with the same number of elements as /// the input type, and the element type is an integer type of the same width @@ -407,7 +464,7 @@ public: unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); assert(EltBits && "Element size must be of a non-zero size"); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); - return VectorType::get(EltTy, VTy->getNumElements()); + return VectorType::get(EltTy, VTy->getElementCount()); } /// This static method is like getInteger except that the element types are @@ -415,7 +472,7 @@ public: static VectorType *getExtendedElementVectorType(VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); - return VectorType::get(EltTy, VTy->getNumElements()); + return VectorType::get(EltTy, VTy->getElementCount()); } /// This static method is like getInteger except that the element types are @@ -425,29 +482,45 @@ public: assert((EltBits & 1) == 0 && "Cannot truncate vector element with odd bit-width"); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2); - return VectorType::get(EltTy, VTy->getNumElements()); + return VectorType::get(EltTy, VTy->getElementCount()); } /// This static method returns a VectorType with half as many elements as the /// input type and the same element type. static VectorType *getHalfElementsVectorType(VectorType *VTy) { - unsigned NumElts = VTy->getNumElements(); - assert ((NumElts & 1) == 0 && + auto EltCnt = VTy->getElementCount(); + assert ((EltCnt.Min & 1) == 0 && "Cannot halve vector with odd number of elements."); - return VectorType::get(VTy->getElementType(), NumElts/2); + return VectorType::get(VTy->getElementType(), EltCnt/2); } /// This static method returns a VectorType with twice as many elements as the /// input type and the same element type. static VectorType *getDoubleElementsVectorType(VectorType *VTy) { - unsigned NumElts = VTy->getNumElements(); - return VectorType::get(VTy->getElementType(), NumElts*2); + auto EltCnt = VTy->getElementCount(); + assert((VTy->getNumElements() * 2ull) <= UINT_MAX && + "Too many elements in vector"); + return VectorType::get(VTy->getElementType(), EltCnt*2); } /// Return true if the specified type is valid as a element type. static bool isValidElementType(Type *ElemTy); - /// Return the number of bits in the Vector type. + /// Return an ElementCount instance to represent the (possibly scalable) + /// number of elements in the vector. + ElementCount getElementCount() const { + uint64_t MinimumEltCnt = getNumElements(); + assert(MinimumEltCnt <= UINT_MAX && "Too many elements in vector"); + return { (unsigned)MinimumEltCnt, Scalable }; + } + + /// Returns whether or not this is a scalable vector (meaning the total + /// element count is a multiple of the minimum). + bool isScalable() const { + return Scalable; + } + + /// Return the minimum number of bits in the Vector type. /// Returns zero when the vector is a vector of pointers. unsigned getBitWidth() const { return getNumElements() * getElementType()->getPrimitiveSizeInBits(); @@ -463,6 +536,10 @@ unsigned Type::getVectorNumElements() const { return cast<VectorType>(this)->getNumElements(); } +bool Type::getVectorIsScalable() const { + return cast<VectorType>(this)->isScalable(); +} + /// Class to represent pointers. class PointerType : public Type { explicit PointerType(Type *ElType, unsigned AddrSpace); diff --git a/include/llvm/IR/DerivedUser.h b/include/llvm/IR/DerivedUser.h index 67c483d3c497..a25d316c2d60 100644 --- a/include/llvm/IR/DerivedUser.h +++ b/include/llvm/IR/DerivedUser.h @@ -1,9 +1,8 @@ //===- DerivedUser.h - Base for non-IR Users --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/DiagnosticHandler.h b/include/llvm/IR/DiagnosticHandler.h index 51873bea3d41..55e5e5975808 100644 --- a/include/llvm/IR/DiagnosticHandler.h +++ b/include/llvm/IR/DiagnosticHandler.h @@ -1,9 +1,8 @@ -//===- DiagnosticHandler.h - DiagnosticHandler class for LLVM -*- C++ ---*-===// +//===- DiagnosticHandler.h - DiagnosticHandler class for LLVM ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // Base DiagnosticHandler class declaration. Derive from this class to provide diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index 3a55a7dca7f4..373663289dbd 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -1,9 +1,8 @@ //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -466,12 +465,15 @@ public: virtual bool isEnabled() const = 0; StringRef getPassName() const { return PassName; } + StringRef getRemarkName() const { return RemarkName; } std::string getMsg() const; Optional<uint64_t> getHotness() const { return Hotness; } void setHotness(Optional<uint64_t> H) { Hotness = H; } bool isVerbose() const { return IsVerbose; } + ArrayRef<Argument> getArgs() const { return Args; } + static bool classof(const DiagnosticInfo *DI) { return (DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark) || @@ -501,7 +503,7 @@ protected: const char *PassName; /// Textual identifier for the remark (single-word, camel-case). Can be used - /// by external tools reading the YAML output file for optimization remarks to + /// by external tools reading the output file for optimization remarks to /// identify the remark. StringRef RemarkName; @@ -519,8 +521,6 @@ protected: /// the optimization records and not in the remark printed in the compiler /// output. int FirstExtraArgIndex = -1; - - friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>; }; /// Allow the insertion operator to return the actual remark type rather than a @@ -1002,12 +1002,6 @@ public: void print(DiagnosticPrinter &DP) const override; }; -namespace yaml { -template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> { - static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag); -}; -} // namespace yaml - } // end namespace llvm #endif // LLVM_IR_DIAGNOSTICINFO_H diff --git a/include/llvm/IR/DiagnosticPrinter.h b/include/llvm/IR/DiagnosticPrinter.h index 25c47cdd1a12..102932ceefa5 100644 --- a/include/llvm/IR/DiagnosticPrinter.h +++ b/include/llvm/IR/DiagnosticPrinter.h @@ -1,9 +1,8 @@ //===- llvm/Support/DiagnosticPrinter.h - Diagnostic Printer ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/DomTreeUpdater.h b/include/llvm/IR/DomTreeUpdater.h deleted file mode 100644 index e5bb092d21ca..000000000000 --- a/include/llvm/IR/DomTreeUpdater.h +++ /dev/null @@ -1,257 +0,0 @@ -//===- DomTreeUpdater.h - DomTree/Post DomTree Updater ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the DomTreeUpdater class, which provides a uniform way to -// update dominator tree related data structures. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DOMTREEUPDATER_H -#define LLVM_DOMTREEUPDATER_H - -#include "llvm/Analysis/PostDominators.h" -#include "llvm/IR/Dominators.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/ValueHandle.h" -#include "llvm/Support/GenericDomTree.h" -#include <functional> -#include <vector> - -namespace llvm { -class DomTreeUpdater { -public: - enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 }; - - explicit DomTreeUpdater(UpdateStrategy Strategy_) : Strategy(Strategy_) {} - DomTreeUpdater(DominatorTree &DT_, UpdateStrategy Strategy_) - : DT(&DT_), Strategy(Strategy_) {} - DomTreeUpdater(DominatorTree *DT_, UpdateStrategy Strategy_) - : DT(DT_), Strategy(Strategy_) {} - DomTreeUpdater(PostDominatorTree &PDT_, UpdateStrategy Strategy_) - : PDT(&PDT_), Strategy(Strategy_) {} - DomTreeUpdater(PostDominatorTree *PDT_, UpdateStrategy Strategy_) - : PDT(PDT_), Strategy(Strategy_) {} - DomTreeUpdater(DominatorTree &DT_, PostDominatorTree &PDT_, - UpdateStrategy Strategy_) - : DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {} - DomTreeUpdater(DominatorTree *DT_, PostDominatorTree *PDT_, - UpdateStrategy Strategy_) - : DT(DT_), PDT(PDT_), Strategy(Strategy_) {} - - ~DomTreeUpdater() { flush(); } - - /// Returns true if the current strategy is Lazy. - bool isLazy() const { return Strategy == UpdateStrategy::Lazy; }; - - /// Returns true if the current strategy is Eager. - bool isEager() const { return Strategy == UpdateStrategy::Eager; }; - - /// Returns true if it holds a DominatorTree. - bool hasDomTree() const { return DT != nullptr; } - - /// Returns true if it holds a PostDominatorTree. - bool hasPostDomTree() const { return PDT != nullptr; } - - /// Returns true if there is BasicBlock awaiting deletion. - /// The deletion will only happen until a flush event and - /// all available trees are up-to-date. - /// Returns false under Eager UpdateStrategy. - bool hasPendingDeletedBB() const { return !DeletedBBs.empty(); } - - /// Returns true if DelBB is awaiting deletion. - /// Returns false under Eager UpdateStrategy. - bool isBBPendingDeletion(BasicBlock *DelBB) const; - - /// Returns true if either of DT or PDT is valid and the tree has at - /// least one update pending. If DT or PDT is nullptr it is treated - /// as having no pending updates. This function does not check - /// whether there is BasicBlock awaiting deletion. - /// Returns false under Eager UpdateStrategy. - bool hasPendingUpdates() const; - - /// Returns true if there are DominatorTree updates queued. - /// Returns false under Eager UpdateStrategy or DT is nullptr. - bool hasPendingDomTreeUpdates() const; - - /// Returns true if there are PostDominatorTree updates queued. - /// Returns false under Eager UpdateStrategy or PDT is nullptr. - bool hasPendingPostDomTreeUpdates() const; - - /// Apply updates on all available trees. Under Eager UpdateStrategy with - /// ForceRemoveDuplicates enabled or under Lazy UpdateStrategy, it will - /// discard duplicated updates and self-dominance updates. If both DT and PDT - /// are nullptrs, this function discards all updates. The Eager Strategy - /// applies the updates immediately while the Lazy Strategy queues the - /// updates. It is required for the state of the LLVM IR to be updated - /// *before* applying the Updates because the internal update routine will - /// analyze the current state of the relationship between a pair of (From, To) - /// BasicBlocks to determine whether a single update needs to be discarded. - void applyUpdates(ArrayRef<DominatorTree::UpdateType> Updates, - bool ForceRemoveDuplicates = false); - - /// Notify all available trees on an edge insertion. If both DT and PDT are - /// nullptrs, this function discards the update. Under either Strategy, - /// self-dominance update will be removed. The Eager Strategy applies - /// the update immediately while the Lazy Strategy queues the update. - /// It is recommended to only use this method when you have exactly one - /// insertion (and no deletions). It is recommended to use applyUpdates() in - /// all other cases. This function has to be called *after* making the update - /// on the actual CFG. An internal functions checks if the edge exists in the - /// CFG in DEBUG mode. - void insertEdge(BasicBlock *From, BasicBlock *To); - - /// Notify all available trees on an edge insertion. - /// Under either Strategy, the following updates will be discard silently - /// 1. Invalid - Inserting an edge that does not exist in the CFG. - /// 2. Self-dominance update. - /// 3. Both DT and PDT are nullptrs. - /// The Eager Strategy applies the update immediately while the Lazy Strategy - /// queues the update. It is recommended to only use this method when you have - /// exactly one insertion (and no deletions) and want to discard an invalid - /// update. - void insertEdgeRelaxed(BasicBlock *From, BasicBlock *To); - - /// Notify all available trees on an edge deletion. If both DT and PDT are - /// nullptrs, this function discards the update. Under either Strategy, - /// self-dominance update will be removed. The Eager Strategy applies - /// the update immediately while the Lazy Strategy queues the update. - /// It is recommended to only use this method when you have exactly one - /// deletion (and no insertions). It is recommended to use applyUpdates() in - /// all other cases. This function has to be called *after* making the update - /// on the actual CFG. An internal functions checks if the edge doesn't exist - /// in the CFG in DEBUG mode. - void deleteEdge(BasicBlock *From, BasicBlock *To); - - /// Notify all available trees on an edge deletion. - /// Under either Strategy, the following updates will be discard silently - /// 1. Invalid - Deleting an edge that still exists in the CFG. - /// 2. Self-dominance update. - /// 3. Both DT and PDT are nullptrs. - /// The Eager Strategy applies the update immediately while the Lazy Strategy - /// queues the update. It is recommended to only use this method when you have - /// exactly one deletion (and no insertions) and want to discard an invalid - /// update. - void deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To); - - /// Delete DelBB. DelBB will be removed from its Parent and - /// erased from available trees if it exists and finally get deleted. - /// Under Eager UpdateStrategy, DelBB will be processed immediately. - /// Under Lazy UpdateStrategy, DelBB will be queued until a flush event and - /// all available trees are up-to-date. Assert if any instruction of DelBB is - /// modified while awaiting deletion. When both DT and PDT are nullptrs, DelBB - /// will be queued until flush() is called. - void deleteBB(BasicBlock *DelBB); - - /// Delete DelBB. DelBB will be removed from its Parent and - /// erased from available trees if it exists. Then the callback will - /// be called. Finally, DelBB will be deleted. - /// Under Eager UpdateStrategy, DelBB will be processed immediately. - /// Under Lazy UpdateStrategy, DelBB will be queued until a flush event and - /// all available trees are up-to-date. Assert if any instruction of DelBB is - /// modified while awaiting deletion. Multiple callbacks can be queued for one - /// DelBB under Lazy UpdateStrategy. - void callbackDeleteBB(BasicBlock *DelBB, - std::function<void(BasicBlock *)> Callback); - - /// Recalculate all available trees and flush all BasicBlocks - /// awaiting deletion immediately. - void recalculate(Function &F); - - /// Flush DomTree updates and return DomTree. - /// It also flush out of date updates applied by all available trees - /// and flush Deleted BBs if both trees are up-to-date. - /// It must only be called when it has a DomTree. - DominatorTree &getDomTree(); - - /// Flush PostDomTree updates and return PostDomTree. - /// It also flush out of date updates applied by all available trees - /// and flush Deleted BBs if both trees are up-to-date. - /// It must only be called when it has a PostDomTree. - PostDominatorTree &getPostDomTree(); - - /// Apply all pending updates to available trees and flush all BasicBlocks - /// awaiting deletion. - /// Does nothing under Eager UpdateStrategy. - void flush(); - - /// Debug method to help view the internal state of this class. - LLVM_DUMP_METHOD void dump() const; - -private: - class CallBackOnDeletion final : public CallbackVH { - public: - CallBackOnDeletion(BasicBlock *V, - std::function<void(BasicBlock *)> Callback) - : CallbackVH(V), DelBB(V), Callback_(Callback) {} - - private: - BasicBlock *DelBB = nullptr; - std::function<void(BasicBlock *)> Callback_; - - void deleted() override { - Callback_(DelBB); - CallbackVH::deleted(); - } - }; - - SmallVector<DominatorTree::UpdateType, 16> PendUpdates; - size_t PendDTUpdateIndex = 0; - size_t PendPDTUpdateIndex = 0; - DominatorTree *DT = nullptr; - PostDominatorTree *PDT = nullptr; - const UpdateStrategy Strategy; - SmallPtrSet<BasicBlock *, 8> DeletedBBs; - std::vector<CallBackOnDeletion> Callbacks; - bool IsRecalculatingDomTree = false; - bool IsRecalculatingPostDomTree = false; - - /// First remove all the instructions of DelBB and then make sure DelBB has a - /// valid terminator instruction which is necessary to have when DelBB still - /// has to be inside of its parent Function while awaiting deletion under Lazy - /// UpdateStrategy to prevent other routines from asserting the state of the - /// IR is inconsistent. Assert if DelBB is nullptr or has predecessors. - void validateDeleteBB(BasicBlock *DelBB); - - /// Returns true if at least one BasicBlock is deleted. - bool forceFlushDeletedBB(); - - /// Deduplicate and remove unnecessary updates (no-ops) when using Lazy - /// UpdateStrategy. Returns true if the update is queued for update. - bool applyLazyUpdate(DominatorTree::UpdateKind Kind, BasicBlock *From, - BasicBlock *To); - - /// Helper function to apply all pending DomTree updates. - void applyDomTreeUpdates(); - - /// Helper function to apply all pending PostDomTree updates. - void applyPostDomTreeUpdates(); - - /// Helper function to flush deleted BasicBlocks if all available - /// trees are up-to-date. - void tryFlushDeletedBB(); - - /// Drop all updates applied by all available trees and delete BasicBlocks if - /// all available trees are up-to-date. - void dropOutOfDateUpdates(); - - /// Erase Basic Block node that has been unlinked from Function - /// in the DomTree and PostDomTree. - void eraseDelBBNode(BasicBlock *DelBB); - - /// Returns true if the update appears in the LLVM IR. - /// It is used to check whether an update is valid in - /// insertEdge/deleteEdge or is unnecessary in the batch update. - bool isUpdateValid(DominatorTree::UpdateType Update) const; - - /// Returns true if the update is self dominance. - bool isSelfDominance(DominatorTree::UpdateType Update) const; -}; -} // namespace llvm - -#endif // LLVM_DOMTREEUPDATER_H diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index f7da47d07663..fef1c6abf8c2 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -1,9 +1,8 @@ //===- Dominators.h - Dominator Info Calculation ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index 630f47e8bb57..7fa61e12f431 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -1,9 +1,8 @@ //===- llvm/Function.h - Class to represent a single function ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -297,15 +296,18 @@ public: /// Get the entry count for this function. /// - /// Entry count is the number of times the function was executed based on - /// pgo data. - ProfileCount getEntryCount() const; + /// Entry count is the number of times the function was executed. + /// When AllowSynthetic is false, only pgo_data will be returned. + ProfileCount getEntryCount(bool AllowSynthetic = false) const; /// Return true if the function is annotated with profile data. /// /// Presence of entry counts from a profile run implies the function has - /// profile annotations. - bool hasProfileData() const { return getEntryCount().hasValue(); } + /// profile annotations. If IncludeSynthetic is false, only return true + /// when the profile data is real. + bool hasProfileData(bool IncludeSynthetic = false) const { + return getEntryCount(IncludeSynthetic).hasValue(); + } /// Returns the set of GUIDs that needs to be imported to the function for /// sample PGO, to enable the same inlines as the profiled optimized binary. @@ -399,6 +401,11 @@ public: return getAttributes().hasParamAttribute(ArgNo, Kind); } + /// gets the specified attribute from the list of attributes. + Attribute getParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const { + return getAttributes().getParamAttr(ArgNo, Kind); + } + /// gets the attribute from the list of attributes. Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const { return AttributeSets.getAttribute(i, Kind); @@ -429,6 +436,12 @@ public: return AttributeSets.getParamAlignment(ArgNo); } + /// Extract the byval type for a parameter. + Type *getParamByValType(unsigned ArgNo) const { + Type *Ty = AttributeSets.getParamByValType(ArgNo); + return Ty ? Ty : (arg_begin() + ArgNo)->getType()->getPointerElementType(); + } + /// Extract the number of dereferenceable bytes for a call or /// parameter (0=unknown). /// @param i AttributeList index, referring to a return value or argument. @@ -551,6 +564,14 @@ public: addFnAttr(Attribute::Speculatable); } + /// Determine if the call might deallocate memory. + bool doesNotFreeMemory() const { + return onlyReadsMemory() || hasFnAttribute(Attribute::NoFree); + } + void setDoesNotFreeMemory() { + addFnAttr(Attribute::NoFree); + } + /// Determine if the function is known not to recurse, directly or /// indirectly. bool doesNotRecurse() const { @@ -591,12 +612,15 @@ public: addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); } + /// Do not optimize this function (-O0). + bool hasOptNone() const { return hasFnAttribute(Attribute::OptimizeNone); } + /// Optimize this function for minimum size (-Oz). - bool optForMinSize() const { return hasFnAttribute(Attribute::MinSize); } + bool hasMinSize() const { return hasFnAttribute(Attribute::MinSize); } /// Optimize this function for size (-Os) or minimum size (-Oz). - bool optForSize() const { - return hasFnAttribute(Attribute::OptimizeForSize) || optForMinSize(); + bool hasOptSize() const { + return hasFnAttribute(Attribute::OptimizeForSize) || hasMinSize(); } /// copyAttributesFrom - copy all additional attributes (those not needed to diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h index 675abeb6ec3a..d62da41ebc29 100644 --- a/include/llvm/IR/GVMaterializer.h +++ b/include/llvm/IR/GVMaterializer.h @@ -1,9 +1,8 @@ //===- GVMaterializer.h - Interface for GV materializers --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h index 3c143ea5f703..9b257abc7c1f 100644 --- a/include/llvm/IR/GetElementPtrTypeIterator.h +++ b/include/llvm/IR/GetElementPtrTypeIterator.h @@ -1,9 +1,8 @@ //===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index 450583baaa3c..3cd405701300 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -1,9 +1,8 @@ //===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/GlobalIFunc.h b/include/llvm/IR/GlobalIFunc.h index ef51315a6f5d..bc0d3c053cce 100644 --- a/include/llvm/IR/GlobalIFunc.h +++ b/include/llvm/IR/GlobalIFunc.h @@ -1,9 +1,8 @@ //===-------- llvm/GlobalIFunc.h - GlobalIFunc class ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/llvm/IR/GlobalIndirectSymbol.h b/include/llvm/IR/GlobalIndirectSymbol.h index 22c00686c549..8bc3f90b94aa 100644 --- a/include/llvm/IR/GlobalIndirectSymbol.h +++ b/include/llvm/IR/GlobalIndirectSymbol.h @@ -1,9 +1,8 @@ //===- llvm/GlobalIndirectSymbol.h - GlobalIndirectSymbol class -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index 1fd3568100c2..b8ab6140ebe7 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -1,9 +1,8 @@ //===-- llvm/GlobalObject.h - Class to represent global objects -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index c07d4051c803..2209881dbda6 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -1,9 +1,8 @@ //===-- llvm/GlobalValue.h - Class to represent a global value --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -80,15 +79,15 @@ protected: ValueType(Ty), Visibility(DefaultVisibility), UnnamedAddrVal(unsigned(UnnamedAddr::None)), DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal), - HasLLVMReservedName(false), IsDSOLocal(false), IntID((Intrinsic::ID)0U), - Parent(nullptr) { + HasLLVMReservedName(false), IsDSOLocal(false), HasPartition(false), + IntID((Intrinsic::ID)0U), Parent(nullptr) { setLinkage(Linkage); setName(Name); } Type *ValueType; - static const unsigned GlobalValueSubClassDataBits = 17; + static const unsigned GlobalValueSubClassDataBits = 16; // All bitfields use unsigned as the underlying type so that MSVC will pack // them. @@ -109,9 +108,13 @@ protected: /// definition cannot be runtime preempted. unsigned IsDSOLocal : 1; + /// True if this symbol has a partition name assigned (see + /// https://lld.llvm.org/Partitions.html). + unsigned HasPartition : 1; + private: // Give subclasses access to what otherwise would be wasted padding. - // (17 + 4 + 2 + 2 + 2 + 3 + 1 + 1) == 32. + // (16 + 4 + 2 + 2 + 2 + 3 + 1 + 1 + 1) == 32. unsigned SubClassData : GlobalValueSubClassDataBits; friend class Constant; @@ -281,6 +284,12 @@ public: return IsDSOLocal; } + bool hasPartition() const { + return HasPartition; + } + StringRef getPartition() const; + void setPartition(StringRef Part); + static LinkageTypes getLinkOnceLinkage(bool ODR) { return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; } diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index 03b9ec46ebb4..2e2c8c477913 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -1,9 +1,8 @@ //===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index fac2ff46c453..a74364dffb2e 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -1,9 +1,8 @@ //===- llvm/IRBuilder.h - Builder for LLVM Instructions ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -32,7 +31,7 @@ #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" @@ -97,12 +96,18 @@ protected: MDNode *DefaultFPMathTag; FastMathFlags FMF; + bool IsFPConstrained; + ConstrainedFPIntrinsic::ExceptionBehavior DefaultConstrainedExcept; + ConstrainedFPIntrinsic::RoundingMode DefaultConstrainedRounding; + ArrayRef<OperandBundleDef> DefaultOperandBundles; public: IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr, ArrayRef<OperandBundleDef> OpBundles = None) - : Context(context), DefaultFPMathTag(FPMathTag), + : Context(context), DefaultFPMathTag(FPMathTag), IsFPConstrained(false), + DefaultConstrainedExcept(ConstrainedFPIntrinsic::ebStrict), + DefaultConstrainedRounding(ConstrainedFPIntrinsic::rmDynamic), DefaultOperandBundles(OpBundles) { ClearInsertionPoint(); } @@ -219,6 +224,37 @@ public: /// Set the fast-math flags to be used with generated fp-math operators void setFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } + /// Enable/Disable use of constrained floating point math. When + /// enabled the CreateF<op>() calls instead create constrained + /// floating point intrinsic calls. Fast math flags are unaffected + /// by this setting. + void setIsFPConstrained(bool IsCon) { IsFPConstrained = IsCon; } + + /// Query for the use of constrained floating point math + bool getIsFPConstrained() { return IsFPConstrained; } + + /// Set the exception handling to be used with constrained floating point + void setDefaultConstrainedExcept( + ConstrainedFPIntrinsic::ExceptionBehavior NewExcept) { + DefaultConstrainedExcept = NewExcept; + } + + /// Set the rounding mode handling to be used with constrained floating point + void setDefaultConstrainedRounding( + ConstrainedFPIntrinsic::RoundingMode NewRounding) { + DefaultConstrainedRounding = NewRounding; + } + + /// Get the exception handling used with constrained floating point + ConstrainedFPIntrinsic::ExceptionBehavior getDefaultConstrainedExcept() { + return DefaultConstrainedExcept; + } + + /// Get the rounding mode handling used with constrained floating point + ConstrainedFPIntrinsic::RoundingMode getDefaultConstrainedRounding() { + return DefaultConstrainedRounding; + } + //===--------------------------------------------------------------------===// // RAII helpers. //===--------------------------------------------------------------------===// @@ -906,20 +942,20 @@ public: Name); } - InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest, + InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> OpBundles, const Twine &Name = "") { - return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest, - UnwindDest, Args, OpBundles, Name); + return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(), + NormalDest, UnwindDest, Args, OpBundles, Name); } - InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest, + InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Value *> Args = None, const Twine &Name = "") { - return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest, - UnwindDest, Args, Name); + return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(), + NormalDest, UnwindDest, Args, Name); } // Deprecated [opaque pointer types] @@ -944,6 +980,42 @@ public: Callee, NormalDest, UnwindDest, Args, Name); } + /// \brief Create a callbr instruction. + CallBrInst *CreateCallBr(FunctionType *Ty, Value *Callee, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args = None, + const Twine &Name = "") { + return Insert(CallBrInst::Create(Ty, Callee, DefaultDest, IndirectDests, + Args), Name); + } + CallBrInst *CreateCallBr(FunctionType *Ty, Value *Callee, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> OpBundles, + const Twine &Name = "") { + return Insert( + CallBrInst::Create(Ty, Callee, DefaultDest, IndirectDests, Args, + OpBundles), Name); + } + + CallBrInst *CreateCallBr(FunctionCallee Callee, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args = None, + const Twine &Name = "") { + return CreateCallBr(Callee.getFunctionType(), Callee.getCallee(), + DefaultDest, IndirectDests, Args, Name); + } + CallBrInst *CreateCallBr(FunctionCallee Callee, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> OpBundles, + const Twine &Name = "") { + return CreateCallBr(Callee.getFunctionType(), Callee.getCallee(), + DefaultDest, IndirectDests, Args, Name); + } + ResumeInst *CreateResume(Value *Exn) { return Insert(ResumeInst::Create(Exn)); } @@ -1004,12 +1076,44 @@ private: } Value *foldConstant(Instruction::BinaryOps Opc, Value *L, - Value *R, const Twine &Name = nullptr) const { + Value *R, const Twine &Name) const { auto *LC = dyn_cast<Constant>(L); auto *RC = dyn_cast<Constant>(R); return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr; } + Value *getConstrainedFPRounding( + Optional<ConstrainedFPIntrinsic::RoundingMode> Rounding) { + ConstrainedFPIntrinsic::RoundingMode UseRounding = + DefaultConstrainedRounding; + + if (Rounding.hasValue()) + UseRounding = Rounding.getValue(); + + Optional<StringRef> RoundingStr = + ConstrainedFPIntrinsic::RoundingModeToStr(UseRounding); + assert(RoundingStr.hasValue() && "Garbage strict rounding mode!"); + auto *RoundingMDS = MDString::get(Context, RoundingStr.getValue()); + + return MetadataAsValue::get(Context, RoundingMDS); + } + + Value *getConstrainedFPExcept( + Optional<ConstrainedFPIntrinsic::ExceptionBehavior> Except) { + ConstrainedFPIntrinsic::ExceptionBehavior UseExcept = + DefaultConstrainedExcept; + + if (Except.hasValue()) + UseExcept = Except.getValue(); + + Optional<StringRef> ExceptStr = + ConstrainedFPIntrinsic::ExceptionBehaviorToStr(UseExcept); + assert(ExceptStr.hasValue() && "Garbage strict exception behavior!"); + auto *ExceptMDS = MDString::get(Context, ExceptStr.getValue()); + + return MetadataAsValue::get(Context, ExceptMDS); + } + public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -1179,6 +1283,14 @@ public: return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } + Value *CreateAnd(ArrayRef<Value*> Ops) { + assert(!Ops.empty()); + Value *Accum = Ops[0]; + for (unsigned i = 1; i < Ops.size(); i++) + Accum = CreateAnd(Accum, Ops[i]); + return Accum; + } + Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { if (auto *RC = dyn_cast<Constant>(RHS)) { if (RC->isNullValue()) @@ -1197,6 +1309,14 @@ public: return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } + Value *CreateOr(ArrayRef<Value*> Ops) { + assert(!Ops.empty()); + Value *Accum = Ops[0]; + for (unsigned i = 1; i < Ops.size(); i++) + Accum = CreateOr(Accum, Ops[i]); + return Accum; + } + Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::Xor, LHS, RHS, Name)) return V; return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); @@ -1212,6 +1332,10 @@ public: Value *CreateFAdd(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd, + L, R, nullptr, Name, FPMD); + if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD, FMF); return Insert(I, Name); @@ -1221,6 +1345,10 @@ public: /// default FMF. Value *CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd, + L, R, FMFSource, Name); + if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), nullptr, FMFSource->getFastMathFlags()); @@ -1229,6 +1357,10 @@ public: Value *CreateFSub(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub, + L, R, nullptr, Name, FPMD); + if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD, FMF); return Insert(I, Name); @@ -1238,6 +1370,10 @@ public: /// default FMF. Value *CreateFSubFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub, + L, R, FMFSource, Name); + if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), nullptr, FMFSource->getFastMathFlags()); @@ -1246,6 +1382,10 @@ public: Value *CreateFMul(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul, + L, R, nullptr, Name, FPMD); + if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD, FMF); return Insert(I, Name); @@ -1255,6 +1395,10 @@ public: /// default FMF. Value *CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul, + L, R, FMFSource, Name); + if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), nullptr, FMFSource->getFastMathFlags()); @@ -1263,6 +1407,10 @@ public: Value *CreateFDiv(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv, + L, R, nullptr, Name, FPMD); + if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD, FMF); return Insert(I, Name); @@ -1272,6 +1420,10 @@ public: /// default FMF. Value *CreateFDivFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv, + L, R, FMFSource, Name); + if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), nullptr, FMFSource->getFastMathFlags()); @@ -1280,6 +1432,10 @@ public: Value *CreateFRem(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem, + L, R, nullptr, Name, FPMD); + if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD, FMF); return Insert(I, Name); @@ -1289,6 +1445,10 @@ public: /// default FMF. Value *CreateFRemFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem, + L, R, FMFSource, Name); + if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), nullptr, FMFSource->getFastMathFlags()); @@ -1305,6 +1465,23 @@ public: return Insert(BinOp, Name); } + CallInst *CreateConstrainedFPBinOp( + Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr, + const Twine &Name = "", MDNode *FPMathTag = nullptr, + Optional<ConstrainedFPIntrinsic::RoundingMode> Rounding = None, + Optional<ConstrainedFPIntrinsic::ExceptionBehavior> Except = None) { + Value *RoundingV = getConstrainedFPRounding(Rounding); + Value *ExceptV = getConstrainedFPExcept(Except); + + FastMathFlags UseFMF = FMF; + if (FMFSource) + UseFMF = FMFSource->getFastMathFlags(); + + CallInst *C = CreateIntrinsic(ID, {L->getType()}, + {L, R, RoundingV, ExceptV}, nullptr, Name); + return cast<CallInst>(setFPAttrs(C, FPMathTag, UseFMF)); + } + Value *CreateNeg(Value *V, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { if (auto *VC = dyn_cast<Constant>(V)) @@ -1331,12 +1508,54 @@ public: Name); } + /// Copy fast-math-flags from an instruction rather than using the builder's + /// default FMF. + Value *CreateFNegFMF(Value *V, Instruction *FMFSource, + const Twine &Name = "") { + if (auto *VC = dyn_cast<Constant>(V)) + return Insert(Folder.CreateFNeg(VC), Name); + // TODO: This should return UnaryOperator::CreateFNeg(...) once we are + // confident that they are optimized sufficiently. + return Insert(setFPAttrs(BinaryOperator::CreateFNeg(V), nullptr, + FMFSource->getFastMathFlags()), + Name); + } + Value *CreateNot(Value *V, const Twine &Name = "") { if (auto *VC = dyn_cast<Constant>(V)) return Insert(Folder.CreateNot(VC), Name); return Insert(BinaryOperator::CreateNot(V), Name); } + Value *CreateUnOp(Instruction::UnaryOps Opc, + Value *V, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + if (auto *VC = dyn_cast<Constant>(V)) + return Insert(Folder.CreateUnOp(Opc, VC), Name); + Instruction *UnOp = UnaryOperator::Create(Opc, V); + if (isa<FPMathOperator>(UnOp)) + UnOp = setFPAttrs(UnOp, FPMathTag, FMF); + return Insert(UnOp, Name); + } + + /// Create either a UnaryOperator or BinaryOperator depending on \p Opc. + /// Correct number of operands must be passed accordingly. + Value *CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops, + const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + if (Instruction::isBinaryOp(Opc)) { + assert(Ops.size() == 2 && "Invalid number of operands!"); + return CreateBinOp(static_cast<Instruction::BinaryOps>(Opc), + Ops[0], Ops[1], Name, FPMathTag); + } + if (Instruction::isUnaryOp(Opc)) { + assert(Ops.size() == 1 && "Invalid number of operands!"); + return CreateUnOp(static_cast<Instruction::UnaryOps>(Opc), + Ops[0], Name, FPMathTag); + } + llvm_unreachable("Unexpected opcode!"); + } + //===--------------------------------------------------------------------===// // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// @@ -1989,16 +2208,17 @@ public: return Insert(CI, Name); } - CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args = None, + CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = None, const Twine &Name = "", MDNode *FPMathTag = nullptr) { - return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag); + return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, Name, + FPMathTag); } - CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args, + CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> OpBundles, const Twine &Name = "", MDNode *FPMathTag = nullptr) { - return CreateCall(Callee->getFunctionType(), Callee, Args, OpBundles, Name, - FPMathTag); + return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, + OpBundles, Name, FPMathTag); } // Deprecated [opaque pointer types] @@ -2031,6 +2251,8 @@ public: MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable); Sel = addBranchMetadata(Sel, Prof, Unpred); } + if (isa<FPMathOperator>(Sel)) + Sel = cast<SelectInst>(setFPAttrs(Sel, nullptr /* MDNode* */, FMF)); return Insert(Sel, Name); } @@ -2231,6 +2453,74 @@ public: return V; } + Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension, + unsigned LastIndex) { + assert(isa<PointerType>(Base->getType()) && + "Invalid Base ptr type for preserve.array.access.index."); + auto *BaseType = Base->getType(); + + Value *LastIndexV = getInt32(LastIndex); + Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); + SmallVector<Value *, 4> IdxList; + for (unsigned I = 0; I < Dimension; ++I) + IdxList.push_back(Zero); + IdxList.push_back(LastIndexV); + + Type *ResultType = + GetElementPtrInst::getGEPReturnType(Base, IdxList); + + Module *M = BB->getParent()->getParent(); + Function *FnPreserveArrayAccessIndex = Intrinsic::getDeclaration( + M, Intrinsic::preserve_array_access_index, {ResultType, BaseType}); + + Value *DimV = getInt32(Dimension); + CallInst *Fn = + CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV}); + + return Fn; + } + + Value *CreatePreserveUnionAccessIndex(Value *Base, unsigned FieldIndex, + MDNode *DbgInfo) { + assert(isa<PointerType>(Base->getType()) && + "Invalid Base ptr type for preserve.union.access.index."); + auto *BaseType = Base->getType(); + + Module *M = BB->getParent()->getParent(); + Function *FnPreserveUnionAccessIndex = Intrinsic::getDeclaration( + M, Intrinsic::preserve_union_access_index, {BaseType, BaseType}); + + Value *DIIndex = getInt32(FieldIndex); + CallInst *Fn = + CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex}); + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); + + return Fn; + } + + Value *CreatePreserveStructAccessIndex(Value *Base, unsigned Index, + unsigned FieldIndex, MDNode *DbgInfo) { + assert(isa<PointerType>(Base->getType()) && + "Invalid Base ptr type for preserve.struct.access.index."); + auto *BaseType = Base->getType(); + + Value *GEPIndex = getInt32(Index); + Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); + Type *ResultType = + GetElementPtrInst::getGEPReturnType(Base, {Zero, GEPIndex}); + + Module *M = BB->getParent()->getParent(); + Function *FnPreserveStructAccessIndex = Intrinsic::getDeclaration( + M, Intrinsic::preserve_struct_access_index, {ResultType, BaseType}); + + Value *DIIndex = getInt32(FieldIndex); + CallInst *Fn = CreateCall(FnPreserveStructAccessIndex, + {Base, GEPIndex, DIIndex}); + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); + + return Fn; + } + private: /// Helper function that creates an assume intrinsic call that /// represents an alignment assumption on the provided Ptr, Mask, Type @@ -2280,10 +2570,11 @@ public: Value **TheCheck = nullptr) { assert(isa<PointerType>(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?"); + assert(Alignment != 0 && "Invalid Alignment"); auto *PtrTy = cast<PointerType>(PtrValue->getType()); Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); - Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0); + Value *Mask = ConstantInt::get(IntPtrTy, Alignment - 1); return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, OffsetValue, TheCheck); } @@ -2310,15 +2601,10 @@ public: Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); if (Alignment->getType() != IntPtrTy) - Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ true, + Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ false, "alignmentcast"); - Value *IsPositive = - CreateICmp(CmpInst::ICMP_SGT, Alignment, - ConstantInt::get(Alignment->getType(), 0), "ispositive"); - Value *PositiveMask = - CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "positivemask"); - Value *Mask = CreateSelect(IsPositive, PositiveMask, - ConstantInt::get(IntPtrTy, 0), "mask"); + + Value *Mask = CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "mask"); return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, OffsetValue, TheCheck); diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h index 75f80567dbd5..3be9449c1a93 100644 --- a/include/llvm/IR/IRPrintingPasses.h +++ b/include/llvm/IR/IRPrintingPasses.h @@ -1,9 +1,8 @@ //===- IRPrintingPasses.h - Passes to print out IR constructs ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 1519a45d59e9..2aac807623a9 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -1,9 +1,8 @@ //===- llvm/InlineAsm.h - Class to represent inline asm strings -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h index 2988fc935dd5..054fe4e9cbe9 100644 --- a/include/llvm/IR/InstIterator.h +++ b/include/llvm/IR/InstIterator.h @@ -1,9 +1,8 @@ //===- InstIterator.h - Classes for inst iteration --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/InstVisitor.h b/include/llvm/IR/InstVisitor.h index c5b4c6f71d7d..fbeb2caf14e6 100644 --- a/include/llvm/IR/InstVisitor.h +++ b/include/llvm/IR/InstVisitor.h @@ -1,9 +1,8 @@ //===- InstVisitor.h - Instruction visitor templates ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -218,14 +217,17 @@ public: RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); } RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); } - // Call and Invoke are slightly different as they delegate first through - // a generic CallSite visitor. + // Call, Invoke and CallBr are slightly different as they delegate first + // through a generic CallSite visitor. RetTy visitCallInst(CallInst &I) { return static_cast<SubClass*>(this)->visitCallSite(&I); } RetTy visitInvokeInst(InvokeInst &I) { return static_cast<SubClass*>(this)->visitCallSite(&I); } + RetTy visitCallBrInst(CallBrInst &I) { + return static_cast<SubClass *>(this)->visitCallSite(&I); + } // While terminators don't have a distinct type modeling them, we support // intercepting them with dedicated a visitor callback. @@ -271,14 +273,14 @@ public: // The next level delegation for `CallBase` is slightly more complex in order // to support visiting cases where the call is also a terminator. RetTy visitCallBase(CallBase &I) { - if (isa<InvokeInst>(I)) + if (isa<InvokeInst>(I) || isa<CallBrInst>(I)) return static_cast<SubClass *>(this)->visitTerminator(I); DELEGATE(Instruction); } - // Provide a legacy visitor for a 'callsite' that visits both calls and - // invokes. + // Provide a legacy visitor for a 'callsite' that visits calls, invokes, + // and calbrs. // // Prefer overriding the type system based `CallBase` instead. RetTy visitCallSite(CallSite CS) { diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 3f384a6ee40c..ca419b50da6b 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -1,9 +1,8 @@ //===- llvm/InstrTypes.h - Important Instruction subclasses -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -28,6 +27,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/OperandTraits.h" @@ -77,7 +77,8 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::Alloca || + return I->isUnaryOp() || + I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || I->getOpcode() == Instruction::ExtractValue || @@ -96,6 +97,91 @@ struct OperandTraits<UnaryInstruction> : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) //===----------------------------------------------------------------------===// +// UnaryOperator Class +//===----------------------------------------------------------------------===// + +class UnaryOperator : public UnaryInstruction { + void AssertOK(); + +protected: + UnaryOperator(UnaryOps iType, Value *S, Type *Ty, + const Twine &Name, Instruction *InsertBefore); + UnaryOperator(UnaryOps iType, Value *S, Type *Ty, + const Twine &Name, BasicBlock *InsertAtEnd); + + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + + UnaryOperator *cloneImpl() const; + +public: + + /// Construct a unary instruction, given the opcode and an operand. + /// Optionally (if InstBefore is specified) insert the instruction + /// into a BasicBlock right before the specified instruction. The specified + /// Instruction is allowed to be a dereferenced end iterator. + /// + static UnaryOperator *Create(UnaryOps Op, Value *S, + const Twine &Name = Twine(), + Instruction *InsertBefore = nullptr); + + /// Construct a unary instruction, given the opcode and an operand. + /// Also automatically insert this instruction to the end of the + /// BasicBlock specified. + /// + static UnaryOperator *Create(UnaryOps Op, Value *S, + const Twine &Name, + BasicBlock *InsertAtEnd); + + /// These methods just forward to Create, and are useful when you + /// statically know what type of instruction you're going to create. These + /// helpers just save some typing. +#define HANDLE_UNARY_INST(N, OPC, CLASS) \ + static UnaryOperator *Create##OPC(Value *V, const Twine &Name = "") {\ + return Create(Instruction::OPC, V, Name);\ + } +#include "llvm/IR/Instruction.def" +#define HANDLE_UNARY_INST(N, OPC, CLASS) \ + static UnaryOperator *Create##OPC(Value *V, const Twine &Name, \ + BasicBlock *BB) {\ + return Create(Instruction::OPC, V, Name, BB);\ + } +#include "llvm/IR/Instruction.def" +#define HANDLE_UNARY_INST(N, OPC, CLASS) \ + static UnaryOperator *Create##OPC(Value *V, const Twine &Name, \ + Instruction *I) {\ + return Create(Instruction::OPC, V, Name, I);\ + } +#include "llvm/IR/Instruction.def" + + static UnaryOperator *CreateWithCopiedFlags(UnaryOps Opc, + Value *V, + Instruction *CopyO, + const Twine &Name = "") { + UnaryOperator *UO = Create(Opc, V, Name); + UO->copyIRFlags(CopyO); + return UO; + } + + static UnaryOperator *CreateFNegFMF(Value *Op, Instruction *FMFSource, + const Twine &Name = "") { + return CreateWithCopiedFlags(Instruction::FNeg, Op, FMFSource, Name); + } + + UnaryOps getOpcode() const { + return static_cast<UnaryOps>(Instruction::getOpcode()); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Instruction *I) { + return I->isUnaryOp(); + } + static bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -162,42 +248,42 @@ public: static BinaryOperator *CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, - BinaryOperator *CopyBO, + Instruction *CopyO, const Twine &Name = "") { BinaryOperator *BO = Create(Opc, V1, V2, Name); - BO->copyIRFlags(CopyBO); + BO->copyIRFlags(CopyO); return BO; } static BinaryOperator *CreateFAddFMF(Value *V1, Value *V2, - BinaryOperator *FMFSource, + Instruction *FMFSource, const Twine &Name = "") { return CreateWithCopiedFlags(Instruction::FAdd, V1, V2, FMFSource, Name); } static BinaryOperator *CreateFSubFMF(Value *V1, Value *V2, - BinaryOperator *FMFSource, + Instruction *FMFSource, const Twine &Name = "") { return CreateWithCopiedFlags(Instruction::FSub, V1, V2, FMFSource, Name); } static BinaryOperator *CreateFMulFMF(Value *V1, Value *V2, - BinaryOperator *FMFSource, + Instruction *FMFSource, const Twine &Name = "") { return CreateWithCopiedFlags(Instruction::FMul, V1, V2, FMFSource, Name); } static BinaryOperator *CreateFDivFMF(Value *V1, Value *V2, - BinaryOperator *FMFSource, + Instruction *FMFSource, const Twine &Name = "") { return CreateWithCopiedFlags(Instruction::FDiv, V1, V2, FMFSource, Name); } static BinaryOperator *CreateFRemFMF(Value *V1, Value *V2, - BinaryOperator *FMFSource, + Instruction *FMFSource, const Twine &Name = "") { return CreateWithCopiedFlags(Instruction::FRem, V1, V2, FMFSource, Name); } - static BinaryOperator *CreateFNegFMF(Value *Op, BinaryOperator *FMFSource, + static BinaryOperator *CreateFNegFMF(Value *Op, Instruction *FMFSource, const Twine &Name = "") { Value *Zero = ConstantFP::getNegativeZero(Op->getType()); - return CreateWithCopiedFlags(Instruction::FSub, Zero, Op, FMFSource); + return CreateWithCopiedFlags(Instruction::FSub, Zero, Op, FMFSource, Name); } static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2, @@ -1033,16 +1119,23 @@ protected: return 0; case Instruction::Invoke: return 2; + case Instruction::CallBr: + return getNumSubclassExtraOperandsDynamic(); } llvm_unreachable("Invalid opcode!"); } + /// Get the number of extra operands for instructions that don't have a fixed + /// number of extra operands. + unsigned getNumSubclassExtraOperandsDynamic() const; + public: using Instruction::getContext; static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call || - I->getOpcode() == Instruction::Invoke; + I->getOpcode() == Instruction::Invoke || + I->getOpcode() == Instruction::CallBr; } static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); @@ -1096,6 +1189,19 @@ public: return isDataOperand(&UI.getUse()); } + /// Given a value use iterator, return the data operand corresponding 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(isDataOperand(U) && "Data operand # out of range!"); + return U - data_operands_begin(); + } + /// Return the iterator pointing to the beginning of the argument list. User::op_iterator arg_begin() { return op_begin(); } User::const_op_iterator arg_begin() const { @@ -1199,6 +1305,13 @@ public: return const_cast<CallBase *>(this)->getCaller(); } + /// Tests if this call site must be tail call optimized. Only a CallInst can + /// be tail call optimized. + bool isMustTailCall() const; + + /// Tests if this call site is marked as a tail call. + bool isTailCall() const; + /// Returns the intrinsic ID of the intrinsic called or /// Intrinsic::not_intrinsic if the called function is not an intrinsic, or if /// this is an indirect call. @@ -1207,10 +1320,13 @@ public: void setCalledOperand(Value *V) { Op<CalledOperandOpEndIdx>() = V; } /// Sets the function called, including updating the function type. - void setCalledFunction(Value *Fn) { - setCalledFunction( - cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()), - Fn); + void setCalledFunction(Function *Fn) { + setCalledFunction(Fn->getFunctionType(), Fn); + } + + /// Sets the function called, including updating the function type. + void setCalledFunction(FunctionCallee Fn) { + setCalledFunction(Fn.getFunctionType(), Fn.getCallee()); } /// Sets the function called, including updating to the specified function @@ -1219,6 +1335,9 @@ public: this->FTy = FTy; assert(FTy == cast<FunctionType>( cast<PointerType>(Fn->getType())->getElementType())); + // This function doesn't mutate the return type, only the function + // type. Seems broken, but I'm just gonna stick an assert in for now. + assert(getType() == FTy->getReturnType()); setCalledOperand(Fn); } @@ -1233,6 +1352,9 @@ public: (ID << 2)); } + /// Check if this call is an inline asm statement. + bool isInlineAsm() const { return isa<InlineAsm>(getCalledOperand()); } + /// \name Attribute API /// /// These methods access and modify attributes on this call (including @@ -1452,6 +1574,12 @@ public: return Attrs.getParamAlignment(ArgNo); } + /// Extract the byval type for a call or parameter. + Type *getParamByValType(unsigned ArgNo) const { + Type *Ty = Attrs.getParamByValType(ArgNo); + return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); + } + /// Extract the number of dereferenceable bytes for a call or /// parameter (0=unknown). uint64_t getDereferenceableBytes(unsigned i) const { diff --git a/include/llvm/IR/Instruction.def b/include/llvm/IR/Instruction.def index 58e4e2e1d6cc..41cdf613ad64 100644 --- a/include/llvm/IR/Instruction.def +++ b/include/llvm/IR/Instruction.def @@ -1,9 +1,8 @@ //===-- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -135,89 +134,90 @@ 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) +HANDLE_TERM_INST (11, CallBr , CallBrInst) // A call-site terminator + LAST_TERM_INST (11) // Standard unary operators... - FIRST_UNARY_INST(11) -HANDLE_UNARY_INST(11, FNeg , UnaryOperator) - LAST_UNARY_INST(11) + FIRST_UNARY_INST(12) +HANDLE_UNARY_INST(12, FNeg , UnaryOperator) + LAST_UNARY_INST(12) // Standard binary operators... - FIRST_BINARY_INST(12) -HANDLE_BINARY_INST(12, Add , BinaryOperator) -HANDLE_BINARY_INST(13, FAdd , BinaryOperator) -HANDLE_BINARY_INST(14, Sub , BinaryOperator) -HANDLE_BINARY_INST(15, FSub , BinaryOperator) -HANDLE_BINARY_INST(16, Mul , BinaryOperator) -HANDLE_BINARY_INST(17, FMul , BinaryOperator) -HANDLE_BINARY_INST(18, UDiv , BinaryOperator) -HANDLE_BINARY_INST(19, SDiv , BinaryOperator) -HANDLE_BINARY_INST(20, FDiv , BinaryOperator) -HANDLE_BINARY_INST(21, URem , BinaryOperator) -HANDLE_BINARY_INST(22, SRem , BinaryOperator) -HANDLE_BINARY_INST(23, FRem , BinaryOperator) + FIRST_BINARY_INST(13) +HANDLE_BINARY_INST(13, Add , BinaryOperator) +HANDLE_BINARY_INST(14, FAdd , BinaryOperator) +HANDLE_BINARY_INST(15, Sub , BinaryOperator) +HANDLE_BINARY_INST(16, FSub , BinaryOperator) +HANDLE_BINARY_INST(17, Mul , BinaryOperator) +HANDLE_BINARY_INST(18, FMul , BinaryOperator) +HANDLE_BINARY_INST(19, UDiv , BinaryOperator) +HANDLE_BINARY_INST(20, SDiv , BinaryOperator) +HANDLE_BINARY_INST(21, FDiv , BinaryOperator) +HANDLE_BINARY_INST(22, URem , BinaryOperator) +HANDLE_BINARY_INST(23, SRem , BinaryOperator) +HANDLE_BINARY_INST(24, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(24, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(25, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(26, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(27, And , BinaryOperator) -HANDLE_BINARY_INST(28, Or , BinaryOperator) -HANDLE_BINARY_INST(29, Xor , BinaryOperator) - LAST_BINARY_INST(29) +HANDLE_BINARY_INST(25, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(26, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(27, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(28, And , BinaryOperator) +HANDLE_BINARY_INST(29, Or , BinaryOperator) +HANDLE_BINARY_INST(30, Xor , BinaryOperator) + LAST_BINARY_INST(30) // Memory operators... - FIRST_MEMORY_INST(30) -HANDLE_MEMORY_INST(30, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(31, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(32, Store , StoreInst ) -HANDLE_MEMORY_INST(33, GetElementPtr, GetElementPtrInst) -HANDLE_MEMORY_INST(34, Fence , FenceInst ) -HANDLE_MEMORY_INST(35, AtomicCmpXchg , AtomicCmpXchgInst ) -HANDLE_MEMORY_INST(36, AtomicRMW , AtomicRMWInst ) - LAST_MEMORY_INST(36) + FIRST_MEMORY_INST(31) +HANDLE_MEMORY_INST(31, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(32, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(33, Store , StoreInst ) +HANDLE_MEMORY_INST(34, GetElementPtr, GetElementPtrInst) +HANDLE_MEMORY_INST(35, Fence , FenceInst ) +HANDLE_MEMORY_INST(36, AtomicCmpXchg , AtomicCmpXchgInst ) +HANDLE_MEMORY_INST(37, AtomicRMW , AtomicRMWInst ) + LAST_MEMORY_INST(37) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(37) -HANDLE_CAST_INST(37, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(38, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(39, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(40, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(41, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(42, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(43, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(44, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(45, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(46, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(47, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(48, BitCast , BitCastInst ) // Type cast -HANDLE_CAST_INST(49, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast - LAST_CAST_INST(49) - - FIRST_FUNCLETPAD_INST(50) -HANDLE_FUNCLETPAD_INST(50, CleanupPad, CleanupPadInst) -HANDLE_FUNCLETPAD_INST(51, CatchPad , CatchPadInst) - LAST_FUNCLETPAD_INST(51) + FIRST_CAST_INST(38) +HANDLE_CAST_INST(38, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(39, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(40, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(41, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(42, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(43, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(44, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(45, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(46, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(47, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(48, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(49, BitCast , BitCastInst ) // Type cast +HANDLE_CAST_INST(50, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast + LAST_CAST_INST(50) + + FIRST_FUNCLETPAD_INST(51) +HANDLE_FUNCLETPAD_INST(51, CleanupPad, CleanupPadInst) +HANDLE_FUNCLETPAD_INST(52, CatchPad , CatchPadInst) + LAST_FUNCLETPAD_INST(52) // Other operators... - FIRST_OTHER_INST(52) -HANDLE_OTHER_INST(52, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(53, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(54, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(55, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(56, Select , SelectInst ) // select instruction -HANDLE_USER_INST (57, UserOp1, Instruction) // May be used internally in a pass -HANDLE_USER_INST (58, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(59, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(60, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(61, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(62, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(63, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(64, InsertValue, InsertValueInst) // insert into aggregate -HANDLE_OTHER_INST(65, LandingPad, LandingPadInst) // Landing pad instruction. - LAST_OTHER_INST(65) + FIRST_OTHER_INST(53) +HANDLE_OTHER_INST(53, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(54, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(55, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(56, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(57, Select , SelectInst ) // select instruction +HANDLE_USER_INST (58, UserOp1, Instruction) // May be used internally in a pass +HANDLE_USER_INST (59, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(60, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(61, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(62, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(63, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(64, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(65, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(66, LandingPad, LandingPadInst) // Landing pad instruction. + LAST_OTHER_INST(66) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 5e78cb1edf02..6a9a74bd16f0 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -1,9 +1,8 @@ //===-- llvm/Instruction.h - Instruction class definition -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -136,6 +135,9 @@ public: bool isExceptionalTerminator() const { return isExceptionalTerminator(getOpcode()); } + bool isIndirectTerminator() const { + return isIndirectTerminator(getOpcode()); + } static const char* getOpcodeName(unsigned OpCode); @@ -203,6 +205,17 @@ public: } } + /// Returns true if the OpCode is a terminator with indirect targets. + static inline bool isIndirectTerminator(unsigned OpCode) { + switch (OpCode) { + case Instruction::IndirectBr: + case Instruction::CallBr: + return true; + default: + return false; + } + } + //===--------------------------------------------------------------------===// // Metadata manipulation. //===--------------------------------------------------------------------===// @@ -298,9 +311,6 @@ public: /// Returns false if no metadata was found. bool extractProfTotalWeight(uint64_t &TotalVal) const; - /// Updates branch_weights metadata by scaling it by \p S / \p T. - void updateProfWeight(uint64_t S, uint64_t T); - /// Sets the branch_weights metadata to \p W for CallInst. void setProfWeight(uint64_t W); @@ -655,6 +665,10 @@ public: /// instruction must be a terminator. void setSuccessor(unsigned Idx, BasicBlock *BB); + /// Replace specified successor OldBB to point at the provided block. + /// This instruction must be a terminator. + void replaceSuccessorWith(BasicBlock *OldBB, BasicBlock *NewBB); + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() >= Value::InstructionVal; diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 0ff8f56f213a..215ce45c7b75 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1,9 +1,8 @@ //===- llvm/Instructions.h - Instruction subclass definitions ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -522,9 +521,11 @@ private: // AtomicCmpXchgInst Class //===----------------------------------------------------------------------===// -/// an instruction that atomically checks whether a +/// An instruction that atomically checks whether a /// specified value is in a memory location, and, if it is, stores a new value -/// there. Returns the value that was loaded. +/// there. The value returned by this instruction is a pair containing the +/// original value as first element, and an i1 indicating success (true) or +/// failure (false) as second element. /// class AtomicCmpXchgInst : public Instruction { void Init(Value *Ptr, Value *Cmp, Value *NewVal, @@ -725,8 +726,14 @@ public: /// *p = old <unsigned v ? old : v UMin, + /// *p = old + v + FAdd, + + /// *p = old - v + FSub, + FIRST_BINOP = Xchg, - LAST_BINOP = UMin, + LAST_BINOP = FSub, BAD_BINOP }; @@ -748,6 +755,16 @@ public: static StringRef getOperationName(BinOp Op); + static bool isFPOperation(BinOp Op) { + switch (Op) { + case AtomicRMWInst::FAdd: + case AtomicRMWInst::FSub: + return true; + default: + return false; + } + } + void setOperation(BinOp Operation) { unsigned short SubclassData = getSubclassDataFromInstruction(); setInstructionSubclassData((SubclassData & 31) | @@ -805,6 +822,10 @@ public: return getPointerOperand()->getType()->getPointerAddressSpace(); } + bool isFloatingPointOperation() const { + return isFPOperation(getOperation()); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; @@ -1115,71 +1136,6 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) //===----------------------------------------------------------------------===// -// UnaryOperator Class -//===----------------------------------------------------------------------===// - -/// a unary instruction -class UnaryOperator : public UnaryInstruction { - void AssertOK(); - -protected: - UnaryOperator(UnaryOps iType, Value *S, Type *Ty, - const Twine &Name, Instruction *InsertBefore); - UnaryOperator(UnaryOps iType, Value *S, Type *Ty, - const Twine &Name, BasicBlock *InsertAtEnd); - - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - - UnaryOperator *cloneImpl() const; - -public: - - /// Construct a unary instruction, given the opcode and an operand. - /// Optionally (if InstBefore is specified) insert the instruction - /// into a BasicBlock right before the specified instruction. The specified - /// Instruction is allowed to be a dereferenced end iterator. - /// - static UnaryOperator *Create(UnaryOps Op, Value *S, - const Twine &Name = Twine(), - Instruction *InsertBefore = nullptr); - - /// Construct a unary instruction, given the opcode and an operand. - /// Also automatically insert this instruction to the end of the - /// BasicBlock specified. - /// - static UnaryOperator *Create(UnaryOps Op, Value *S, - const Twine &Name, - BasicBlock *InsertAtEnd); - - /// These methods just forward to Create, and are useful when you - /// statically know what type of instruction you're going to create. These - /// helpers just save some typing. -#define HANDLE_UNARY_INST(N, OPC, CLASS) \ - static UnaryInstruction *Create##OPC(Value *V, \ - const Twine &Name = "") {\ - return Create(Instruction::OPC, V, Name);\ - } -#include "llvm/IR/Instruction.def" -#define HANDLE_UNARY_INST(N, OPC, CLASS) \ - static UnaryInstruction *Create##OPC(Value *V, \ - const Twine &Name, BasicBlock *BB) {\ - return Create(Instruction::OPC, V, Name, BB);\ - } -#include "llvm/IR/Instruction.def" -#define HANDLE_UNARY_INST(N, OPC, CLASS) \ - static UnaryInstruction *Create##OPC(Value *V, \ - const Twine &Name, Instruction *I) {\ - return Create(Instruction::OPC, V, Name, I);\ - } -#include "llvm/IR/Instruction.def" - - UnaryOps getOpcode() const { - return static_cast<UnaryOps>(Instruction::getOpcode()); - } -}; - -//===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// @@ -1524,25 +1480,44 @@ public: CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd); } - static CallInst *Create(Function *Func, const Twine &NameStr = "", + static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), NameStr, + InsertBefore); } - static CallInst *Create(Function *Func, ArrayRef<Value *> Args, + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles, + NameStr, InsertBefore); } - static CallInst *Create(Function *Func, const Twine &NameStr, + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr, + InsertBefore); + } + + static CallInst *Create(FunctionCallee Func, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), NameStr, + InsertAtEnd); } - static CallInst *Create(Function *Func, ArrayRef<Value *> Args, + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr, + InsertAtEnd); + } + + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles, + NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] @@ -1684,9 +1659,6 @@ public: addAttribute(AttributeList::FunctionIndex, Attribute::ReturnsTwice); } - /// Check if this call is an inline asm statement. - bool isInlineAsm() const { return isa<InlineAsm>(getCalledOperand()); } - // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; @@ -1695,6 +1667,9 @@ public: return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + /// Updates profile metadata by scaling it by \p S / \p T. + void updateProfWeight(uint64_t S, uint64_t T); + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -2008,6 +1983,10 @@ public: return User::operator new(s, 3); } + /// Swap the first 2 operands and adjust the mask to preserve the semantics + /// of the instruction. + void commute(); + /// Return true if a shufflevector instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *V1, const Value *V2, @@ -2696,6 +2675,14 @@ public: block_begin()[i] = BB; } + /// Replace every incoming basic block \p Old to basic block \p New. + void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) { + assert(New && Old && "PHI node got a null basic block!"); + for (unsigned Op = 0, NumOps = getNumOperands(); Op != NumOps; ++Op) + if (getIncomingBlock(Op) == Old) + setIncomingBlock(Op, New); + } + /// Add an incoming value to the end of the PHI list /// void addIncoming(Value *V, BasicBlock *BB) { @@ -2739,6 +2726,19 @@ public: return getIncomingValue(Idx); } + /// Set every incoming value(s) for block \p BB to \p V. + void setIncomingValueForBlock(const BasicBlock *BB, Value *V) { + assert(BB && "PHI node got a null basic block!"); + bool Found = false; + for (unsigned Op = 0, NumOps = getNumOperands(); Op != NumOps; ++Op) + if (getIncomingBlock(Op) == BB) { + Found = true; + setIncomingValue(Op, V); + } + (void)Found; + assert(Found && "Invalid basic block argument to set!"); + } + /// If the specified PHI node always merges together the /// same value, return the value, otherwise return null. Value *hasConstantValue() const; @@ -3450,6 +3450,60 @@ public: } }; +/// A wrapper class to simplify modification of SwitchInst cases along with +/// their prof branch_weights metadata. +class SwitchInstProfUpdateWrapper { + SwitchInst &SI; + Optional<SmallVector<uint32_t, 8> > Weights = None; + + // Sticky invalid state is needed to safely ignore operations with prof data + // in cases where SwitchInstProfUpdateWrapper is created from SwitchInst + // with inconsistent prof data. TODO: once we fix all prof data + // inconsistencies we can turn invalid state to assertions. + enum { + Invalid, + Initialized, + Changed + } State = Invalid; + +protected: + static MDNode *getProfBranchWeightsMD(const SwitchInst &SI); + + MDNode *buildProfBranchWeightsMD(); + + void init(); + +public: + using CaseWeightOpt = Optional<uint32_t>; + SwitchInst *operator->() { return &SI; } + SwitchInst &operator*() { return SI; } + operator SwitchInst *() { return &SI; } + + SwitchInstProfUpdateWrapper(SwitchInst &SI) : SI(SI) { init(); } + + ~SwitchInstProfUpdateWrapper() { + if (State == Changed) + SI.setMetadata(LLVMContext::MD_prof, buildProfBranchWeightsMD()); + } + + /// Delegate the call to the underlying SwitchInst::removeCase() and remove + /// correspondent branch weight. + SwitchInst::CaseIt removeCase(SwitchInst::CaseIt I); + + /// Delegate the call to the underlying SwitchInst::addCase() and set the + /// specified branch weight for the added case. + void addCase(ConstantInt *OnVal, BasicBlock *Dest, CaseWeightOpt W); + + /// Delegate the call to the underlying SwitchInst::eraseFromParent() and mark + /// this object to not touch the underlying SwitchInst in destructor. + SymbolTableList<Instruction>::iterator eraseFromParent(); + + void setSuccessorWeight(unsigned idx, CaseWeightOpt W); + CaseWeightOpt getSuccessorWeight(unsigned idx); + + static CaseWeightOpt getSuccessorWeight(const SwitchInst &SI, unsigned idx); +}; + template <> struct OperandTraits<SwitchInst> : public HungoffOperandTraits<2> { }; @@ -3688,36 +3742,36 @@ public: NameStr, InsertAtEnd); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - None, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, None, NameStr, InsertBefore); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - Bundles, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, Bundles, NameStr, InsertBefore); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, NameStr, InsertAtEnd); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - Bundles, NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, Bundles, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] @@ -3852,6 +3906,249 @@ InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, } //===----------------------------------------------------------------------===// +// CallBrInst Class +//===----------------------------------------------------------------------===// + +/// CallBr instruction, tracking function calls that may not return control but +/// instead transfer it to a third location. The SubclassData field is used to +/// hold the calling convention of the call. +/// +class CallBrInst : public CallBase { + + unsigned NumIndirectDests; + + CallBrInst(const CallBrInst &BI); + + /// Construct a CallBrInst given a range of arguments. + /// + /// Construct a CallBrInst from a range of arguments + inline CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, Instruction *InsertBefore); + + inline CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, BasicBlock *InsertAtEnd); + + void init(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr); + + /// Compute the number of operands to allocate. + static int ComputeNumOperands(int NumArgs, int NumIndirectDests, + int NumBundleInputs = 0) { + // We need one operand for the called function, plus our extra operands and + // the input operand counts provided. + return 2 + NumIndirectDests + NumArgs + NumBundleInputs; + } + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + + CallBrInst *cloneImpl() const; + +public: + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size()); + return new (NumOperands) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, None, + NumOperands, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size(), + CountBundleInputs(Bundles)); + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (NumOperands, DescriptorBytes) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, + NumOperands, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + BasicBlock *InsertAtEnd) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size()); + return new (NumOperands) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, None, + NumOperands, NameStr, InsertAtEnd); + } + + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size(), + CountBundleInputs(Bundles)); + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (NumOperands, DescriptorBytes) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, + NumOperands, NameStr, InsertAtEnd); + } + + static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, Bundles, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + BasicBlock *InsertAtEnd) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, NameStr, InsertAtEnd); + } + + static CallBrInst *Create(FunctionCallee Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, Bundles, NameStr, InsertAtEnd); + } + + /// Create a clone of \p CBI with a different set of operand bundles and + /// insert it before \p InsertPt. + /// + /// The returned callbr instruction is identical to \p CBI in every way + /// except that the operand bundles for the new instruction are set to the + /// operand bundles in \p Bundles. + static CallBrInst *Create(CallBrInst *CBI, + ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertPt = nullptr); + + /// Return the number of callbr indirect dest labels. + /// + unsigned getNumIndirectDests() const { return NumIndirectDests; } + + /// getIndirectDestLabel - Return the i-th indirect dest label. + /// + Value *getIndirectDestLabel(unsigned i) const { + assert(i < getNumIndirectDests() && "Out of bounds!"); + return getOperand(i + getNumArgOperands() + getNumTotalBundleOperands() + + 1); + } + + Value *getIndirectDestLabelUse(unsigned i) const { + assert(i < getNumIndirectDests() && "Out of bounds!"); + return getOperandUse(i + getNumArgOperands() + getNumTotalBundleOperands() + + 1); + } + + // Return the destination basic blocks... + BasicBlock *getDefaultDest() const { + return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() - 1)); + } + BasicBlock *getIndirectDest(unsigned i) const { + return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() + i)); + } + SmallVector<BasicBlock *, 16> getIndirectDests() const { + SmallVector<BasicBlock *, 16> IndirectDests; + for (unsigned i = 0, e = getNumIndirectDests(); i < e; ++i) + IndirectDests.push_back(getIndirectDest(i)); + return IndirectDests; + } + void setDefaultDest(BasicBlock *B) { + *(&Op<-1>() - getNumIndirectDests() - 1) = reinterpret_cast<Value *>(B); + } + void setIndirectDest(unsigned i, BasicBlock *B) { + *(&Op<-1>() - getNumIndirectDests() + i) = reinterpret_cast<Value *>(B); + } + + BasicBlock *getSuccessor(unsigned i) const { + assert(i < getNumSuccessors() + 1 && + "Successor # out of range for callbr!"); + return i == 0 ? getDefaultDest() : getIndirectDest(i - 1); + } + + void setSuccessor(unsigned idx, BasicBlock *NewSucc) { + assert(idx < getNumIndirectDests() + 1 && + "Successor # out of range for callbr!"); + *(&Op<-1>() - getNumIndirectDests() -1 + idx) = + reinterpret_cast<Value *>(NewSucc); + } + + unsigned getNumSuccessors() const { return getNumIndirectDests() + 1; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Instruction *I) { + return (I->getOpcode() == Instruction::CallBr); + } + static 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. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, Instruction *InsertBefore) + : CallBase(Ty->getReturnType(), Instruction::CallBr, + OperandTraits<CallBase>::op_end(this) - NumOperands, NumOperands, + InsertBefore) { + init(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, NameStr); +} + +CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, BasicBlock *InsertAtEnd) + : CallBase( + cast<FunctionType>( + cast<PointerType>(Func->getType())->getElementType()) + ->getReturnType(), + Instruction::CallBr, + OperandTraits<CallBase>::op_end(this) - NumOperands, NumOperands, + InsertAtEnd) { + init(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, NameStr); +} + +//===----------------------------------------------------------------------===// // ResumeInst Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index 80a7a7052574..438bdb29b706 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -1,9 +1,8 @@ //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -209,26 +208,47 @@ namespace llvm { /// This is the common base class for constrained floating point intrinsics. class ConstrainedFPIntrinsic : public IntrinsicInst { public: - enum RoundingMode { - rmInvalid, - rmDynamic, - rmToNearest, - rmDownward, - rmUpward, - rmTowardZero + /// Specifies the rounding mode to be assumed. This is only used when + /// when constrained floating point is enabled. See the LLVM Language + /// Reference Manual for details. + enum RoundingMode : uint8_t { + rmDynamic, ///< This corresponds to "fpround.dynamic". + rmToNearest, ///< This corresponds to "fpround.tonearest". + rmDownward, ///< This corresponds to "fpround.downward". + rmUpward, ///< This corresponds to "fpround.upward". + rmTowardZero ///< This corresponds to "fpround.tozero". }; - enum ExceptionBehavior { - ebInvalid, - ebIgnore, - ebMayTrap, - ebStrict + /// Specifies the required exception behavior. This is only used when + /// when constrained floating point is used. See the LLVM Language + /// Reference Manual for details. + enum ExceptionBehavior : uint8_t { + ebIgnore, ///< This corresponds to "fpexcept.ignore". + ebMayTrap, ///< This corresponds to "fpexcept.maytrap". + ebStrict ///< This corresponds to "fpexcept.strict". }; bool isUnaryOp() const; bool isTernaryOp() const; - RoundingMode getRoundingMode() const; - ExceptionBehavior getExceptionBehavior() const; + Optional<RoundingMode> getRoundingMode() const; + Optional<ExceptionBehavior> getExceptionBehavior() const; + + /// Returns a valid RoundingMode enumerator when given a string + /// that is valid as input in constrained intrinsic rounding mode + /// metadata. + static Optional<RoundingMode> StrToRoundingMode(StringRef); + + /// For any RoundingMode enumerator, returns a string valid as input in + /// constrained intrinsic rounding mode metadata. + static Optional<StringRef> RoundingModeToStr(RoundingMode); + + /// Returns a valid ExceptionBehavior enumerator when given a string + /// valid as input in constrained intrinsic exception behavior metadata. + static Optional<ExceptionBehavior> StrToExceptionBehavior(StringRef); + + /// For any ExceptionBehavior enumerator, returns a string valid as + /// input in constrained intrinsic exception behavior metadata. + static Optional<StringRef> ExceptionBehaviorToStr(ExceptionBehavior); // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const IntrinsicInst *I) { @@ -239,6 +259,8 @@ namespace llvm { case Intrinsic::experimental_constrained_fdiv: case Intrinsic::experimental_constrained_frem: case Intrinsic::experimental_constrained_fma: + case Intrinsic::experimental_constrained_fptrunc: + case Intrinsic::experimental_constrained_fpext: case Intrinsic::experimental_constrained_sqrt: case Intrinsic::experimental_constrained_pow: case Intrinsic::experimental_constrained_powi: @@ -266,6 +288,84 @@ namespace llvm { } }; + /// This class represents an intrinsic that is based on a binary operation. + /// This includes op.with.overflow and saturating add/sub intrinsics. + class BinaryOpIntrinsic : public IntrinsicInst { + public: + static bool classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { + case Intrinsic::uadd_with_overflow: + case Intrinsic::sadd_with_overflow: + case Intrinsic::usub_with_overflow: + case Intrinsic::ssub_with_overflow: + case Intrinsic::umul_with_overflow: + case Intrinsic::smul_with_overflow: + case Intrinsic::uadd_sat: + case Intrinsic::sadd_sat: + case Intrinsic::usub_sat: + case Intrinsic::ssub_sat: + return true; + default: + return false; + } + } + static bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + + Value *getLHS() const { return const_cast<Value*>(getArgOperand(0)); } + Value *getRHS() const { return const_cast<Value*>(getArgOperand(1)); } + + /// Returns the binary operation underlying the intrinsic. + Instruction::BinaryOps getBinaryOp() const; + + /// Whether the intrinsic is signed or unsigned. + bool isSigned() const; + + /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap. + unsigned getNoWrapKind() const; + }; + + /// Represents an op.with.overflow intrinsic. + class WithOverflowInst : public BinaryOpIntrinsic { + public: + static bool classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { + case Intrinsic::uadd_with_overflow: + case Intrinsic::sadd_with_overflow: + case Intrinsic::usub_with_overflow: + case Intrinsic::ssub_with_overflow: + case Intrinsic::umul_with_overflow: + case Intrinsic::smul_with_overflow: + return true; + default: + return false; + } + } + static bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + }; + + /// Represents a saturating add/sub intrinsic. + class SaturatingInst : public BinaryOpIntrinsic { + public: + static bool classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { + case Intrinsic::uadd_sat: + case Intrinsic::sadd_sat: + case Intrinsic::usub_sat: + case Intrinsic::ssub_sat: + return true; + default: + return false; + } + } + static bool classof(const Value *V) { + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); + } + }; + /// Common base class for all memory intrinsics. Simply provides /// common methods. /// Written as CRTP to avoid a common base class amongst the diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h index e1e17f983ff8..f38f92022d21 100644 --- a/include/llvm/IR/Intrinsics.h +++ b/include/llvm/IR/Intrinsics.h @@ -1,9 +1,8 @@ -//===-- llvm/Instrinsics.h - LLVM Intrinsic Function Handling ---*- C++ -*-===// +//===- Intrinsics.h - LLVM Intrinsic Function Handling ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -100,7 +99,8 @@ namespace Intrinsic { Void, VarArg, MMX, Token, Metadata, Half, Float, Double, Quad, Integer, Vector, Pointer, Struct, Argument, ExtendArgument, TruncArgument, HalfVecArgument, - SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt + SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt, + VecElementArgument } Kind; union { @@ -117,20 +117,22 @@ namespace Intrinsic { AK_AnyInteger, AK_AnyFloat, AK_AnyVector, - AK_AnyPointer + AK_AnyPointer, + AK_MatchType = 7 }; unsigned getArgumentNumber() const { assert(Kind == Argument || Kind == ExtendArgument || Kind == TruncArgument || Kind == HalfVecArgument || Kind == SameVecWidthArgument || Kind == PtrToArgument || - Kind == PtrToElt); + Kind == PtrToElt || Kind == VecElementArgument); return Argument_Info >> 3; } ArgKind getArgumentKind() const { assert(Kind == Argument || Kind == ExtendArgument || Kind == TruncArgument || Kind == HalfVecArgument || - Kind == SameVecWidthArgument || Kind == PtrToArgument); + Kind == SameVecWidthArgument || Kind == PtrToArgument || + Kind == VecElementArgument); return (ArgKind)(Argument_Info & 7); } @@ -162,14 +164,21 @@ namespace Intrinsic { /// of IITDescriptors. void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T); - /// Match the specified type (which comes from an intrinsic argument or return - /// value) with the type constraints specified by the .td file. If the given - /// type is an overloaded type it is pushed to the ArgTys vector. + enum MatchIntrinsicTypesResult { + MatchIntrinsicTypes_Match = 0, + MatchIntrinsicTypes_NoMatchRet = 1, + MatchIntrinsicTypes_NoMatchArg = 2, + }; + + /// Match the specified function type with the type constraints specified by + /// the .td file. If the given type is an overloaded type it is pushed to the + /// ArgTys vector. /// /// Returns false if the given type matches with the constraints, true /// otherwise. - bool matchIntrinsicType(Type *Ty, ArrayRef<IITDescriptor> &Infos, - SmallVectorImpl<Type*> &ArgTys); + MatchIntrinsicTypesResult + matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos, + SmallVectorImpl<Type *> &ArgTys); /// Verify if the intrinsic has variable arguments. This method is intended to /// be called after all the fixed arguments have been matched first. diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 64603d8ea030..d660f8278437 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -1,9 +1,8 @@ //===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -70,6 +69,11 @@ class Returned<int argNo> : IntrinsicProperty { int ArgNo = argNo; } +// ImmArg - The specified argument must be an immediate. +class ImmArg<int argNo> : IntrinsicProperty { + int ArgNo = argNo; +} + // ReadOnly - The specified argument pointer is not written to through the // pointer by the intrinsic. class ReadOnly<int argNo> : IntrinsicProperty { @@ -90,6 +94,8 @@ class ReadNone<int argNo> : IntrinsicProperty { def IntrNoReturn : IntrinsicProperty; +def IntrWillReturn : IntrinsicProperty; + // IntrCold - Calls to this intrinsic are cold. // Parallels the cold attribute on LLVM IR functions. def IntrCold : IntrinsicProperty; @@ -157,13 +163,19 @@ class LLVMMatchType<int num> // the intrinsic is overloaded, so the matched type should be declared as iAny. class LLVMExtendedType<int num> : LLVMMatchType<num>; class LLVMTruncatedType<int num> : LLVMMatchType<num>; -class LLVMVectorSameWidth<int num, LLVMType elty> - : LLVMMatchType<num> { + +// Match the scalar/vector of another intrinsic parameter but with a different +// element type. Either both are scalars or both are vectors with the same +// number of elements. +class LLVMScalarOrSameVectorWidth<int idx, LLVMType elty> + : LLVMMatchType<idx> { ValueType ElTy = elty.VT; } + class LLVMPointerTo<int num> : LLVMMatchType<num>; class LLVMPointerToElt<int num> : LLVMMatchType<num>; class LLVMVectorOfAnyPointersToElt<int num> : LLVMMatchType<num>; +class LLVMVectorElementType<int num> : LLVMMatchType<num>; // Match the type of another intrinsic parameter that is expected to be a // vector type, but change the element count to be half as many @@ -251,6 +263,7 @@ def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float def llvm_v16f32_ty : LLVMType<v16f32>; // 16 x float +def llvm_v32f32_ty : LLVMType<v32f32>; // 32 x float def llvm_v1f64_ty : LLVMType<v1f64>; // 1 x double def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double @@ -393,9 +406,9 @@ def int_objc_arc_annotation_bottomup_bbend : Intrinsic<[], //===--------------------- Code Generator Intrinsics ----------------------===// // -def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; +def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; def int_addressofreturnaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; -def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; +def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; def int_sponentry : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty], [IntrReadMem], "llvm.read_register">; @@ -413,7 +426,7 @@ def int_localescape : Intrinsic<[], [llvm_vararg_ty]>; // to an escaped allocation indicated by the index. def int_localrecover : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; // Given the frame pointer passed into an SEH filter function, returns a // pointer to the local variable area suitable for use with llvm.localrecover. @@ -439,7 +452,8 @@ def int_thread_pointer : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>, // memory while not impeding optimization. def int_prefetch : Intrinsic<[], [ llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ], - [ IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0> ]>; + [ IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0>, + ImmArg<1>, ImmArg<2>]>; def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>; def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>; @@ -480,16 +494,17 @@ def int_memcpy : Intrinsic<[], [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i1_ty], [IntrArgMemOnly, NoCapture<0>, NoCapture<1>, - WriteOnly<0>, ReadOnly<1>]>; + WriteOnly<0>, ReadOnly<1>, ImmArg<3>]>; def int_memmove : Intrinsic<[], [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i1_ty], [IntrArgMemOnly, NoCapture<0>, NoCapture<1>, - ReadOnly<1>]>; + ReadOnly<1>, ImmArg<3>]>; def int_memset : Intrinsic<[], [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i1_ty], - [IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>; + [IntrArgMemOnly, NoCapture<0>, WriteOnly<0>, + ImmArg<3>]>; // FIXME: Add version of these floating point intrinsics which allow non-default // rounding modes and FP exception handling. @@ -527,6 +542,11 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + + def int_lround : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_llround : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_lrint : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_llrint : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; } def int_minnum : Intrinsic<[llvm_anyfloat_ty], @@ -554,8 +574,9 @@ def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>; // Internal interface for object size checking def int_objectsize : Intrinsic<[llvm_anyint_ty], - [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty], - [IntrNoMem, IntrSpeculatable]>, + [llvm_anyptr_ty, llvm_i1_ty, + llvm_i1_ty, llvm_i1_ty], + [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>, ImmArg<3>]>, GCCBuiltin<"__builtin_object_size">; //===--------------- Constrained Floating Point Intrinsics ----------------===// @@ -595,6 +616,15 @@ let IntrProperties = [IntrInaccessibleMemOnly] in { llvm_metadata_ty, llvm_metadata_ty ]>; + def int_experimental_constrained_fptrunc : Intrinsic<[ llvm_anyfloat_ty ], + [ llvm_anyfloat_ty, + llvm_metadata_ty, + llvm_metadata_ty ]>; + + def int_experimental_constrained_fpext : Intrinsic<[ llvm_anyfloat_ty ], + [ llvm_anyfloat_ty, + llvm_metadata_ty ]>; + // These intrinsics are sensitive to the rounding mode so we need constrained // versions of each of them. When strict rounding and exception control are // not required the non-constrained versions of these intrinsics should be @@ -676,14 +706,12 @@ let IntrProperties = [IntrInaccessibleMemOnly] in { llvm_metadata_ty, llvm_metadata_ty ]>; } -// FIXME: Add intrinsics for fcmp, fptrunc, fpext, fptoui and fptosi. -// FIXME: Add intrinsics for fabs and copysign? - +// FIXME: Add intrinsics for fcmp, fptoui and fptosi. //===------------------------- Expect Intrinsics --------------------------===// // -def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, - LLVMMatchType<0>], [IntrNoMem]>; +def int_expect : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; //===-------------------- Bit Manipulation Intrinsics ---------------------===// // @@ -692,8 +720,6 @@ def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, let IntrProperties = [IntrNoMem, IntrSpeculatable] in { def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; 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>]>; def int_fshl : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; @@ -701,6 +727,11 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; } +let IntrProperties = [IntrNoMem, IntrSpeculatable, ImmArg<1>] in { + def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>; + def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>; +} + //===------------------------ Debugger Intrinsics -------------------------===// // @@ -797,24 +828,30 @@ def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], // // Expose the carry flag from add operations on two integrals. -def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; @@ -837,23 +874,33 @@ def int_usub_sat : Intrinsic<[llvm_anyint_ty], // def int_smul_fix : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable, Commutative]>; + [IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>; + +def int_umul_fix : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>; + +//===------------------- Fixed Point Saturation Arithmetic Intrinsics ----------------===// +// +def int_smul_fix_sat : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>; //===------------------------- Memory Use Markers -------------------------===// // def int_lifetime_start : Intrinsic<[], [llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<1>]>; + [IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>; def int_lifetime_end : Intrinsic<[], [llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<1>]>; + [IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>; def int_invariant_start : Intrinsic<[llvm_descriptor_ty], [llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<1>]>; + [IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>; def int_invariant_end : Intrinsic<[], [llvm_descriptor_ty, llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<2>]>; + [IntrArgMemOnly, NoCapture<2>, ImmArg<1>]>; // launder.invariant.group can't be marked with 'readnone' (IntrNoMem), // because it would cause CSE of two barriers with the same argument. @@ -900,13 +947,13 @@ 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]>; + [Throws, ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>]>; def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_token_ty], [IntrReadMem]>; def int_experimental_gc_relocate : Intrinsic<[llvm_any_ty], [llvm_token_ty, llvm_i32_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadMem, ImmArg<1>, ImmArg<2>]>; //===------------------------ Coroutine Intrinsics ---------------===// // These are documented in docs/Coroutines.rst @@ -996,41 +1043,41 @@ def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], // Intrinsic to detect whether its argument is a constant. def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem], "llvm.is.constant">; - //===-------------------------- Masked Intrinsics -------------------------===// // def int_masked_store : Intrinsic<[], [llvm_anyvector_ty, LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_ty>], - [IntrArgMemOnly]>; + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], + [IntrArgMemOnly, ImmArg<2>]>; def int_masked_load : Intrinsic<[llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_ty>, LLVMMatchType<0>], - [IntrReadMem, IntrArgMemOnly]>; + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>], + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_masked_gather: Intrinsic<[llvm_anyvector_ty], [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_ty>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>], - [IntrReadMem]>; + [IntrReadMem, ImmArg<1>]>; def int_masked_scatter: Intrinsic<[], [llvm_anyvector_ty, LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_ty>]>; + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], + [ImmArg<2>]>; def int_masked_expandload: Intrinsic<[llvm_anyvector_ty], [LLVMPointerToElt<0>, - LLVMVectorSameWidth<0, llvm_i1_ty>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>], [IntrReadMem]>; def int_masked_compressstore: Intrinsic<[], [llvm_anyvector_ty, LLVMPointerToElt<0>, - LLVMVectorSameWidth<0, llvm_i1_ty>], + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [IntrArgMemOnly]>; // Test whether a pointer is associated with a type metadata identifier. @@ -1049,6 +1096,9 @@ def int_icall_branch_funnel : Intrinsic<[], [llvm_vararg_ty], []>; def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty], [IntrReadMem, IntrArgMemOnly]>; +def int_hwasan_check_memaccess : + Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly, ImmArg<2>]>; + // Xray intrinsics //===----------------------------------------------------------------------===// // Custom event logging for x-ray. @@ -1072,7 +1122,7 @@ def int_memcpy_element_unordered_atomic ], [ IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>, - ReadOnly<1> + ReadOnly<1>, ImmArg<3> ]>; // @llvm.memmove.element.unordered.atomic.*(dest, src, length, elementsize) @@ -1083,62 +1133,105 @@ def int_memmove_element_unordered_atomic ], [ IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>, - ReadOnly<1> + ReadOnly<1>, ImmArg<3> ]>; // @llvm.memset.element.unordered.atomic.*(dest, value, length, elementsize) def int_memset_element_unordered_atomic : Intrinsic<[], [ llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty ], - [ IntrArgMemOnly, NoCapture<0>, WriteOnly<0> ]>; + [ IntrArgMemOnly, NoCapture<0>, WriteOnly<0>, ImmArg<3> ]>; //===------------------------ Reduction Intrinsics ------------------------===// // -def int_experimental_vector_reduce_fadd : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyfloat_ty, - llvm_anyvector_ty], - [IntrNoMem]>; -def int_experimental_vector_reduce_fmul : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyfloat_ty, - llvm_anyvector_ty], - [IntrNoMem]>; -def int_experimental_vector_reduce_add : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_v2_fadd : Intrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, + llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_v2_fmul : Intrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, + llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_add : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_mul : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_mul : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_and : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_and : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_or : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_or : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_xor : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_xor : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_smax : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_smax : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_smin : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_smin : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_umax : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_umax : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_umin : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_umin : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_fmax : Intrinsic<[llvm_anyfloat_ty], +def int_experimental_vector_reduce_fmax : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_fmin : Intrinsic<[llvm_anyfloat_ty], +def int_experimental_vector_reduce_fmin : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; +//===---------- Intrinsics to control hardware supported loops ----------===// + +// Specify that the value given is the number of iterations that the next loop +// will execute. +def int_set_loop_iterations : + Intrinsic<[], [llvm_anyint_ty], [IntrNoDuplicate]>; + +// Specify that the value given is the number of iterations that the next loop +// will execute. Also test that the given count is not zero, allowing it to +// control entry to a 'while' loop. +def int_test_set_loop_iterations : + Intrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>; + +// Decrement loop counter by the given argument. Return false if the loop +// should exit. +def int_loop_decrement : + Intrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>; + +// Decrement the first operand (the loop counter) by the second operand (the +// maximum number of elements processed in an iteration). Return the remaining +// number of iterations still to be executed. This is effectively a sub which +// can be used with a phi, icmp and br to control the number of iterations +// executed, as usual. +def int_loop_decrement_reg : + Intrinsic<[llvm_anyint_ty], + [llvm_anyint_ty, llvm_anyint_ty], [IntrNoDuplicate]>; + //===----- Intrinsics that are used to provide predicate information -----===// def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrNoMem, Returned<0>]>; + +//===------- Intrinsics that are used to preserve debug information -------===// + +def int_preserve_array_access_index : Intrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_i32_ty, + llvm_i32_ty], + [IntrNoMem, ImmArg<1>, ImmArg<2>]>; +def int_preserve_union_access_index : Intrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; +def int_preserve_struct_access_index : Intrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_i32_ty, + llvm_i32_ty], + [IntrNoMem, ImmArg<1>, + ImmArg<2>]>; + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td index ff25750fe399..832aca4fd30f 100644 --- a/include/llvm/IR/IntrinsicsAArch64.td +++ b/include/llvm/IR/IntrinsicsAArch64.td @@ -1,9 +1,8 @@ //===- IntrinsicsAARCH64.td - Defines AARCH64 intrinsics ---*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -32,6 +31,8 @@ def int_aarch64_sdiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, def int_aarch64_udiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; +def int_aarch64_fjcvtzs : Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>; + //===----------------------------------------------------------------------===// // HINT @@ -290,6 +291,7 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in { // Pairwise Add def int_aarch64_neon_addp : AdvSIMD_2VectorArg_Intrinsic; + def int_aarch64_neon_faddp : AdvSIMD_2VectorArg_Intrinsic; // Long Pairwise Add // FIXME: In theory, we shouldn't need intrinsics for saddlp or @@ -462,12 +464,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". [IntrArgMemOnly, NoCapture<2>]>; class AdvSIMD_2Vec_Load_Intrinsic - : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], + : Intrinsic<[LLVMMatchType<0>, llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, IntrArgMemOnly]>; class AdvSIMD_2Vec_Load_Lane_Intrinsic - : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], - [LLVMMatchType<0>, LLVMMatchType<0>, + : Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>], + [LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty], [IntrReadMem, IntrArgMemOnly]>; class AdvSIMD_2Vec_Store_Intrinsic @@ -480,12 +482,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". [IntrArgMemOnly, NoCapture<3>]>; class AdvSIMD_3Vec_Load_Intrinsic - : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>], + : Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, IntrArgMemOnly]>; class AdvSIMD_3Vec_Load_Lane_Intrinsic - : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>], - [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, + : Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty], [IntrReadMem, IntrArgMemOnly]>; class AdvSIMD_3Vec_Store_Intrinsic @@ -499,15 +501,15 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". [IntrArgMemOnly, NoCapture<4>]>; class AdvSIMD_4Vec_Load_Intrinsic - : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, - LLVMMatchType<0>, LLVMMatchType<0>], + : Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, + LLVMMatchType<0>, llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, IntrArgMemOnly]>; class AdvSIMD_4Vec_Load_Lane_Intrinsic - : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + : Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>, LLVMMatchType<0>, + LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty], [IntrReadMem, IntrArgMemOnly]>; class AdvSIMD_4Vec_Store_Intrinsic @@ -684,3 +686,50 @@ def int_aarch64_crc32x : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], def int_aarch64_crc32cx : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; } + +//===----------------------------------------------------------------------===// +// Memory Tagging Extensions (MTE) Intrinsics +let TargetPrefix = "aarch64" in { +def int_aarch64_irg : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrInaccessibleMemOnly]>; +def int_aarch64_addg : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrNoMem]>; +def int_aarch64_gmi : Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrNoMem]>; +def int_aarch64_ldg : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty], + [IntrReadMem]>; +def int_aarch64_stg : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], + [IntrWriteMem]>; +def int_aarch64_subp : Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_ptr_ty], + [IntrNoMem]>; + +// The following are codegen-only intrinsics for stack instrumentation. + +// Generate a randomly tagged stack base pointer. +def int_aarch64_irg_sp : Intrinsic<[llvm_ptr_ty], [llvm_i64_ty], + [IntrInaccessibleMemOnly]>; + +// Transfer pointer tag with offset. +// ptr1 = tagp(ptr0, baseptr, tag_offset) returns a pointer where +// * address is the address in ptr0 +// * tag is a function of (tag in baseptr, tag_offset). +// Address bits in baseptr and tag bits in ptr0 are ignored. +// When offset between ptr0 and baseptr is a compile time constant, this can be emitted as +// ADDG ptr1, baseptr, (ptr0 - baseptr), tag_offset +// It is intended that ptr0 is an alloca address, and baseptr is the direct output of llvm.aarch64.irg.sp. +def int_aarch64_tagp : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_ptr_ty, llvm_i64_ty], + [IntrNoMem, ImmArg<2>]>; + +// Update allocation tags for the memory range to match the tag in the pointer argument. +def int_aarch64_settag : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty], + [IntrWriteMem, IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>; + +// Update allocation tags for the memory range to match the tag in the pointer argument, +// and set memory contents to zero. +def int_aarch64_settag_zero : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty], + [IntrWriteMem, IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>; + +// Update allocation tags for 16-aligned, 16-sized memory region, and store a pair 8-byte values. +def int_aarch64_stgp : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty, llvm_i64_ty], + [IntrWriteMem, IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>; +} diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index 7913ce828fbc..3982444b5401 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -1,9 +1,8 @@ //===- IntrinsicsAMDGPU.td - Defines AMDGPU intrinsics -----*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -178,7 +177,7 @@ def int_amdgcn_implicit_buffer_ptr : // This is always moved to the beginning of the basic block. def int_amdgcn_init_exec : Intrinsic<[], [llvm_i64_ty], // 64-bit literal constant - [IntrConvergent]>; + [IntrConvergent, ImmArg<0>]>; // Set EXEC according to a thread count packed in an SGPR input: // thread_count = (input >> bitoffset) & 0x7f; @@ -188,6 +187,10 @@ def int_amdgcn_init_exec_from_input : Intrinsic<[], llvm_i32_ty], // bit offset of the thread count [IntrConvergent]>; +def int_amdgcn_wavefrontsize : + GCCBuiltin<"__builtin_amdgcn_wavefrontsize">, + Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>; + //===----------------------------------------------------------------------===// // Instruction Intrinsics @@ -196,9 +199,9 @@ def int_amdgcn_init_exec_from_input : Intrinsic<[], // The first parameter is s_sendmsg immediate (i16), // the second one is copied to m0 def int_amdgcn_s_sendmsg : GCCBuiltin<"__builtin_amdgcn_s_sendmsg">, - Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], []>; + Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, IntrInaccessibleMemOnly]>; def int_amdgcn_s_sendmsghalt : GCCBuiltin<"__builtin_amdgcn_s_sendmsghalt">, - Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], []>; + Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, IntrInaccessibleMemOnly]>; def int_amdgcn_s_barrier : GCCBuiltin<"__builtin_amdgcn_s_barrier">, Intrinsic<[], [], [IntrConvergent]>; @@ -207,7 +210,7 @@ def int_amdgcn_wave_barrier : GCCBuiltin<"__builtin_amdgcn_wave_barrier">, Intrinsic<[], [], [IntrConvergent]>; def int_amdgcn_s_waitcnt : GCCBuiltin<"__builtin_amdgcn_s_waitcnt">, - Intrinsic<[], [llvm_i32_ty], []>; + Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]>; def int_amdgcn_div_scale : Intrinsic< // 1st parameter: Numerator @@ -216,7 +219,7 @@ def int_amdgcn_div_scale : Intrinsic< // second. (0 = first, 1 = second). [llvm_anyfloat_ty, llvm_i1_ty], [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<2>] >; def int_amdgcn_div_fmas : Intrinsic<[llvm_anyfloat_ty], @@ -293,29 +296,33 @@ def int_amdgcn_fract : Intrinsic< [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; -def int_amdgcn_cvt_pkrtz : Intrinsic< - [llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty], - [IntrNoMem, IntrSpeculatable] +def int_amdgcn_cvt_pkrtz : GCCBuiltin<"__builtin_amdgcn_cvt_pkrtz">, + Intrinsic<[llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; -def int_amdgcn_cvt_pknorm_i16 : Intrinsic< - [llvm_v2i16_ty], [llvm_float_ty, llvm_float_ty], - [IntrNoMem, IntrSpeculatable] +def int_amdgcn_cvt_pknorm_i16 : + GCCBuiltin<"__builtin_amdgcn_cvt_pknorm_i16">, + Intrinsic<[llvm_v2i16_ty], [llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; -def int_amdgcn_cvt_pknorm_u16 : Intrinsic< - [llvm_v2i16_ty], [llvm_float_ty, llvm_float_ty], - [IntrNoMem, IntrSpeculatable] +def int_amdgcn_cvt_pknorm_u16 : + GCCBuiltin<"__builtin_amdgcn_cvt_pknorm_u16">, + Intrinsic<[llvm_v2i16_ty], [llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; -def int_amdgcn_cvt_pk_i16 : Intrinsic< +def int_amdgcn_cvt_pk_i16 : + GCCBuiltin<"__builtin_amdgcn_cvt_pk_i16">, + Intrinsic< [llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrSpeculatable] >; -def int_amdgcn_cvt_pk_u16 : Intrinsic< - [llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable] +def int_amdgcn_cvt_pk_u16 : GCCBuiltin<"__builtin_amdgcn_cvt_pk_u16">, + Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_class : Intrinsic< @@ -374,7 +381,7 @@ class AMDGPUAtomicIncIntrin : Intrinsic<[llvm_anyint_ty], llvm_i32_ty, // ordering llvm_i32_ty, // scope llvm_i1_ty], // isVolatile - [IntrArgMemOnly, NoCapture<0>], "", + [IntrArgMemOnly, NoCapture<0>, ImmArg<2>, ImmArg<3>, ImmArg<4>], "", [SDNPMemOperand] >; @@ -389,9 +396,45 @@ class AMDGPULDSF32Intrin<string clang_builtin> : llvm_i32_ty, // ordering llvm_i32_ty, // scope llvm_i1_ty], // isVolatile - [IntrArgMemOnly, NoCapture<0>] + [IntrArgMemOnly, NoCapture<0>, ImmArg<2>, ImmArg<3>, ImmArg<4>] +>; + +// FIXME: The m0 argument should be moved after the normal arguments +class AMDGPUDSOrderedIntrinsic : Intrinsic< + [llvm_i32_ty], + // M0 = {hi16:address, lo16:waveID}. Allow passing M0 as a pointer, so that + // the bit packing can be optimized at the IR level. + [LLVMQualPointerType<llvm_i32_ty, 2>, // IntToPtr(M0) + llvm_i32_ty, // value to add or swap + llvm_i32_ty, // ordering + llvm_i32_ty, // scope + llvm_i1_ty, // isVolatile + llvm_i32_ty, // ordered count index (OA index), also added to the address + // gfx10: bits 24-27 indicate the number of active threads/dwords + llvm_i1_ty, // wave release, usually set to 1 + llvm_i1_ty], // wave done, set to 1 for the last ordered instruction + [NoCapture<0>, + ImmArg<2>, ImmArg<3>, ImmArg<4>, + ImmArg<5>, ImmArg<6>, ImmArg<7> + ] +>; + +class AMDGPUDSAppendConsumedIntrinsic : Intrinsic< + [llvm_i32_ty], + [llvm_anyptr_ty, // LDS or GDS ptr + llvm_i1_ty], // isVolatile + [IntrConvergent, IntrArgMemOnly, NoCapture<0>, ImmArg<1>], + "", + [SDNPMemOperand] >; +def int_amdgcn_ds_ordered_add : AMDGPUDSOrderedIntrinsic; +def int_amdgcn_ds_ordered_swap : AMDGPUDSOrderedIntrinsic; + +// The pointer argument is assumed to be dynamically uniform if a VGPR. +def int_amdgcn_ds_append : AMDGPUDSAppendConsumedIntrinsic; +def int_amdgcn_ds_consume : AMDGPUDSAppendConsumedIntrinsic; + def int_amdgcn_ds_fadd : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_faddf">; def int_amdgcn_ds_fmin : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fminf">; def int_amdgcn_ds_fmax : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fmaxf">; @@ -442,9 +485,12 @@ class arglistconcat<list<list<AMDGPUArg>> arglists, int shift = 0> { } // Represent texture/image types / dimensionality. -class AMDGPUDimProps<string name, list<string> coord_names, list<string> slice_names> { +class AMDGPUDimProps<bits<3> enc, string name, string asmsuffix, + list<string> coord_names, list<string> slice_names> { AMDGPUDimProps Dim = !cast<AMDGPUDimProps>(NAME); string Name = name; // e.g. "2darraymsaa" + string AsmSuffix = asmsuffix; // e.g. 2D_MSAA_ARRAY (used in assembly strings) + bits<3> Encoding = enc; bit DA = 0; // DA bit in MIMG encoding list<AMDGPUArg> CoordSliceArgs = @@ -460,17 +506,17 @@ class AMDGPUDimProps<string name, list<string> coord_names, list<string> slice_n bits<8> NumGradients = !size(GradientArgs); } -def AMDGPUDim1D : AMDGPUDimProps<"1d", ["s"], []>; -def AMDGPUDim2D : AMDGPUDimProps<"2d", ["s", "t"], []>; -def AMDGPUDim3D : AMDGPUDimProps<"3d", ["s", "t", "r"], []>; +def AMDGPUDim1D : AMDGPUDimProps<0x0, "1d", "1D", ["s"], []>; +def AMDGPUDim2D : AMDGPUDimProps<0x1, "2d", "2D", ["s", "t"], []>; +def AMDGPUDim3D : AMDGPUDimProps<0x2, "3d", "3D", ["s", "t", "r"], []>; let DA = 1 in { - def AMDGPUDimCube : AMDGPUDimProps<"cube", ["s", "t"], ["face"]>; - def AMDGPUDim1DArray : AMDGPUDimProps<"1darray", ["s"], ["slice"]>; - def AMDGPUDim2DArray : AMDGPUDimProps<"2darray", ["s", "t"], ["slice"]>; + def AMDGPUDimCube : AMDGPUDimProps<0x3, "cube", "CUBE", ["s", "t"], ["face"]>; + def AMDGPUDim1DArray : AMDGPUDimProps<0x4, "1darray", "1D_ARRAY", ["s"], ["slice"]>; + def AMDGPUDim2DArray : AMDGPUDimProps<0x5, "2darray", "2D_ARRAY", ["s", "t"], ["slice"]>; } -def AMDGPUDim2DMsaa : AMDGPUDimProps<"2dmsaa", ["s", "t"], ["fragid"]>; +def AMDGPUDim2DMsaa : AMDGPUDimProps<0x6, "2dmsaa", "2D_MSAA", ["s", "t"], ["fragid"]>; let DA = 1 in { - def AMDGPUDim2DArrayMsaa : AMDGPUDimProps<"2darraymsaa", ["s", "t"], ["slice", "fragid"]>; + def AMDGPUDim2DArrayMsaa : AMDGPUDimProps<0x7, "2darraymsaa", "2D_MSAA_ARRAY", ["s", "t"], ["slice", "fragid"]>; } def AMDGPUDims { @@ -621,6 +667,19 @@ class AMDGPUDimGetResInfoProfile<AMDGPUDimProps dim> : AMDGPUDimProfile<"GET_RES let LodClampMip = "mip"; } +// Helper class for figuring out image intrinsic argument indexes. +class AMDGPUImageDimIntrinsicEval<AMDGPUDimProfile P_> { + int NumDataArgs = !size(P_.DataArgs); + int NumDmaskArgs = !if(P_.IsAtomic, 0, 1); + int NumVAddrArgs = !size(P_.AddrArgs); + int NumRSrcArgs = 1; + int NumSampArgs = !if(P_.IsSample, 2, 0); + int DmaskArgIndex = NumDataArgs; + int UnormArgIndex = !add(NumDataArgs, NumDmaskArgs, NumVAddrArgs, NumRSrcArgs, 1); + int TexFailCtrlArgIndex = !add(NumDataArgs, NumDmaskArgs, NumVAddrArgs, NumRSrcArgs, NumSampArgs); + int CachePolicyArgIndex = !add(TexFailCtrlArgIndex, 1); +} + // All dimension-aware intrinsics are derived from this class. class AMDGPUImageDimIntrinsic<AMDGPUDimProfile P_, list<IntrinsicProperty> props, @@ -634,8 +693,13 @@ class AMDGPUImageDimIntrinsic<AMDGPUDimProfile P_, !if(P_.IsSample, [llvm_v4i32_ty, // samp(SGPR) llvm_i1_ty], []), // unorm(imm) [llvm_i32_ty, // texfailctrl(imm; bit 0 = tfe, bit 1 = lwe) - llvm_i32_ty]), // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - props, "", sdnodeprops>, + llvm_i32_ty]), // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc) + !listconcat(props, + !if(P_.IsAtomic, [], [ImmArg<AMDGPUImageDimIntrinsicEval<P_>.DmaskArgIndex>]), + !if(P_.IsSample, [ImmArg<AMDGPUImageDimIntrinsicEval<P_>.UnormArgIndex>], []), + [ImmArg<AMDGPUImageDimIntrinsicEval<P_>.TexFailCtrlArgIndex>, + ImmArg<AMDGPUImageDimIntrinsicEval<P_>.CachePolicyArgIndex>]), + "", sdnodeprops>, AMDGPURsrcIntrinsic<!add(!size(P_.DataArgs), !size(P_.AddrTypes), !if(P_.IsAtomic, 0, 1)), 1> { AMDGPUDimProfile P = P_; @@ -791,13 +855,13 @@ let TargetPrefix = "amdgcn" in { defset list<AMDGPURsrcIntrinsic> AMDGPUBufferIntrinsics = { class AMDGPUBufferLoad : Intrinsic < - [llvm_anyfloat_ty], + [llvm_any_ty], [llvm_v4i32_ty, // rsrc(SGPR) llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrReadMem], "", [SDNPMemOperand]>, + [IntrReadMem, ImmArg<3>, ImmArg<4>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<0>; def int_amdgcn_buffer_load_format : AMDGPUBufferLoad; def int_amdgcn_buffer_load : AMDGPUBufferLoad; @@ -805,20 +869,20 @@ def int_amdgcn_buffer_load : AMDGPUBufferLoad; def int_amdgcn_s_buffer_load : Intrinsic < [llvm_any_ty], [llvm_v4i32_ty, // rsrc(SGPR) - llvm_i32_ty, // byte offset(SGPR/VGPR/imm) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc) - [IntrNoMem]>, + llvm_i32_ty, // byte offset(SGPR/imm) + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 2 = dlc) + [IntrNoMem, ImmArg<2>]>, AMDGPURsrcIntrinsic<0>; class AMDGPUBufferStore : Intrinsic < [], - [llvm_anyfloat_ty, // vdata(VGPR) -- can currently only select f32, v2f32, v4f32 + [llvm_any_ty, // vdata(VGPR) llvm_v4i32_ty, // rsrc(SGPR) llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrWriteMem], "", [SDNPMemOperand]>, + [IntrWriteMem, ImmArg<4>, ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1>; def int_amdgcn_buffer_store_format : AMDGPUBufferStore; def int_amdgcn_buffer_store : AMDGPUBufferStore; @@ -835,8 +899,8 @@ class AMDGPURawBufferLoad : Intrinsic < [llvm_v4i32_ty, // rsrc(SGPR) llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrReadMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrReadMem, ImmArg<3>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<0>; def int_amdgcn_raw_buffer_load_format : AMDGPURawBufferLoad; def int_amdgcn_raw_buffer_load : AMDGPURawBufferLoad; @@ -847,8 +911,8 @@ class AMDGPUStructBufferLoad : Intrinsic < llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrReadMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrReadMem, ImmArg<4>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<0>; def int_amdgcn_struct_buffer_load_format : AMDGPUStructBufferLoad; def int_amdgcn_struct_buffer_load : AMDGPUStructBufferLoad; @@ -859,8 +923,8 @@ class AMDGPURawBufferStore : Intrinsic < llvm_v4i32_ty, // rsrc(SGPR) llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrWriteMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrWriteMem, ImmArg<4>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1>; def int_amdgcn_raw_buffer_store_format : AMDGPURawBufferStore; def int_amdgcn_raw_buffer_store : AMDGPURawBufferStore; @@ -872,8 +936,8 @@ class AMDGPUStructBufferStore : Intrinsic < llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrWriteMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrWriteMem, ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1>; def int_amdgcn_struct_buffer_store_format : AMDGPUStructBufferStore; def int_amdgcn_struct_buffer_store : AMDGPUStructBufferStore; @@ -885,7 +949,7 @@ class AMDGPURawBufferAtomic : Intrinsic < llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty], // cachepolicy(imm; bit 1 = slc) - [], "", [SDNPMemOperand]>, + [ImmArg<4>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1, 0>; def int_amdgcn_raw_buffer_atomic_swap : AMDGPURawBufferAtomic; def int_amdgcn_raw_buffer_atomic_add : AMDGPURawBufferAtomic; @@ -905,7 +969,7 @@ def int_amdgcn_raw_buffer_atomic_cmpswap : Intrinsic< llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty], // cachepolicy(imm; bit 1 = slc) - [], "", [SDNPMemOperand]>, + [ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<2, 0>; class AMDGPUStructBufferAtomic : Intrinsic < @@ -916,7 +980,7 @@ class AMDGPUStructBufferAtomic : Intrinsic < llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty], // cachepolicy(imm; bit 1 = slc) - [], "", [SDNPMemOperand]>, + [ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1, 0>; def int_amdgcn_struct_buffer_atomic_swap : AMDGPUStructBufferAtomic; def int_amdgcn_struct_buffer_atomic_add : AMDGPUStructBufferAtomic; @@ -937,7 +1001,7 @@ def int_amdgcn_struct_buffer_atomic_cmpswap : Intrinsic< llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty], // cachepolicy(imm; bit 1 = slc) - [], "", [SDNPMemOperand]>, + [ImmArg<6>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<2, 0>; // Obsolescent tbuffer intrinsics. @@ -952,7 +1016,8 @@ def int_amdgcn_tbuffer_load : Intrinsic < llvm_i32_ty, // nfmt(imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrReadMem], "", [SDNPMemOperand]>, + [IntrReadMem, ImmArg<4>, ImmArg<5>, ImmArg<6>, + ImmArg<7>, ImmArg<8>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<0>; def int_amdgcn_tbuffer_store : Intrinsic < @@ -967,7 +1032,8 @@ def int_amdgcn_tbuffer_store : Intrinsic < llvm_i32_ty, // nfmt(imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrWriteMem], "", [SDNPMemOperand]>, + [IntrWriteMem, ImmArg<5>, ImmArg<6>, ImmArg<7>, + ImmArg<8>, ImmArg<9>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1>; // New tbuffer intrinsics, with: @@ -980,8 +1046,8 @@ def int_amdgcn_raw_tbuffer_load : Intrinsic < llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty, // format(imm; bits 3..0 = dfmt, bits 6..4 = nfmt) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrReadMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrReadMem, ImmArg<3>, ImmArg<4>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<0>; def int_amdgcn_raw_tbuffer_store : Intrinsic < @@ -991,8 +1057,8 @@ def int_amdgcn_raw_tbuffer_store : Intrinsic < llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty, // format(imm; bits 3..0 = dfmt, bits 6..4 = nfmt) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrWriteMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrWriteMem, ImmArg<4>, ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1>; def int_amdgcn_struct_tbuffer_load : Intrinsic < @@ -1002,8 +1068,8 @@ def int_amdgcn_struct_tbuffer_load : Intrinsic < llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty, // format(imm; bits 3..0 = dfmt, bits 6..4 = nfmt) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrReadMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrReadMem, ImmArg<4>, ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<0>; def int_amdgcn_struct_tbuffer_store : Intrinsic < @@ -1014,18 +1080,18 @@ def int_amdgcn_struct_tbuffer_store : Intrinsic < llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling) llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling) llvm_i32_ty, // format(imm; bits 3..0 = dfmt, bits 6..4 = nfmt) - llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc) - [IntrWriteMem], "", [SDNPMemOperand]>, + llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc on gfx10+) + [IntrWriteMem, ImmArg<5>, ImmArg<6>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1>; class AMDGPUBufferAtomic : Intrinsic < - [llvm_i32_ty], - [llvm_i32_ty, // vdata(VGPR) + [llvm_anyint_ty], + [LLVMMatchType<0>, // vdata(VGPR) llvm_v4i32_ty, // rsrc(SGPR) llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty], // slc(imm) - [], "", [SDNPMemOperand]>, + [ImmArg<4>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<1, 0>; def int_amdgcn_buffer_atomic_swap : AMDGPUBufferAtomic; def int_amdgcn_buffer_atomic_add : AMDGPUBufferAtomic; @@ -1045,7 +1111,7 @@ def int_amdgcn_buffer_atomic_cmpswap : Intrinsic< llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty], // slc(imm) - [], "", [SDNPMemOperand]>, + [ImmArg<5>], "", [SDNPMemOperand]>, AMDGPURsrcIntrinsic<2, 0>; } // defset AMDGPUBufferIntrinsics @@ -1062,7 +1128,7 @@ def int_amdgcn_exp : Intrinsic <[], [ llvm_i1_ty, // done llvm_i1_ty // vm ], - [] + [ImmArg<0>, ImmArg<1>, ImmArg<6>, ImmArg<7>, IntrInaccessibleMemOnly] >; // exp with compr bit set. @@ -1073,7 +1139,7 @@ def int_amdgcn_exp_compr : Intrinsic <[], [ LLVMMatchType<0>, // src1 llvm_i1_ty, // done llvm_i1_ty], // vm - [] + [ImmArg<0>, ImmArg<1>, ImmArg<4>, ImmArg<5>, IntrInaccessibleMemOnly] >; def int_amdgcn_buffer_wbinvl1_sc : @@ -1090,27 +1156,27 @@ def int_amdgcn_s_dcache_inv : def int_amdgcn_s_memtime : GCCBuiltin<"__builtin_amdgcn_s_memtime">, - Intrinsic<[llvm_i64_ty], [], [IntrReadMem]>; + Intrinsic<[llvm_i64_ty], []>; def int_amdgcn_s_sleep : GCCBuiltin<"__builtin_amdgcn_s_sleep">, - Intrinsic<[], [llvm_i32_ty], []> { + Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]> { } def int_amdgcn_s_incperflevel : GCCBuiltin<"__builtin_amdgcn_s_incperflevel">, - Intrinsic<[], [llvm_i32_ty], []> { + Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]> { } def int_amdgcn_s_decperflevel : GCCBuiltin<"__builtin_amdgcn_s_decperflevel">, - Intrinsic<[], [llvm_i32_ty], []> { + Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]> { } def int_amdgcn_s_getreg : GCCBuiltin<"__builtin_amdgcn_s_getreg">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty], - [IntrReadMem, IntrSpeculatable] + [IntrInaccessibleMemOnly, IntrReadMem, IntrSpeculatable, ImmArg<0>] >; // int_amdgcn_s_getpc is provided to allow a specific style of position @@ -1129,7 +1195,7 @@ def int_amdgcn_interp_mov : GCCBuiltin<"__builtin_amdgcn_interp_mov">, Intrinsic<[llvm_float_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable]>; + [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>]>; // __builtin_amdgcn_interp_p1 <i>, <attr_chan>, <attr>, <m0> // This intrinsic reads from lds, but the memory values are constant, @@ -1138,16 +1204,30 @@ def int_amdgcn_interp_p1 : GCCBuiltin<"__builtin_amdgcn_interp_p1">, Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable]>; + [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>]>; // __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_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable]>; + [IntrNoMem, IntrSpeculatable, ImmArg<2>, ImmArg<3>]>; // See int_amdgcn_v_interp_p1 for why this is IntrNoMem. +// __builtin_amdgcn_interp_p1_f16 <i>, <attr_chan>, <attr>, <high>, <m0> +def int_amdgcn_interp_p1_f16 : + GCCBuiltin<"__builtin_amdgcn_interp_p1_f16">, + Intrinsic<[llvm_float_ty], + [llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>, ImmArg<3>]>; + +// __builtin_amdgcn_interp_p2_f16 <p1>, <j>, <attr_chan>, <attr>, <high>, <m0> +def int_amdgcn_interp_p2_f16 : + GCCBuiltin<"__builtin_amdgcn_interp_p2_f16">, + Intrinsic<[llvm_half_ty], + [llvm_float_ty, llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; + // Pixel shaders only: whether the current pixel is live (i.e. not a helper // invocation for derivative computation). def int_amdgcn_ps_live : Intrinsic < @@ -1166,16 +1246,17 @@ def int_amdgcn_mbcnt_hi : // llvm.amdgcn.ds.swizzle src offset def int_amdgcn_ds_swizzle : GCCBuiltin<"__builtin_amdgcn_ds_swizzle">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrConvergent, ImmArg<1>]>; def int_amdgcn_ubfe : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable] + [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_sbfe : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable] + [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_lerp : @@ -1233,12 +1314,12 @@ def int_amdgcn_cvt_pk_u8_f32 : >; def int_amdgcn_icmp : - Intrinsic<[llvm_i64_ty], [llvm_anyint_ty, LLVMMatchType<0>, llvm_i32_ty], - [IntrNoMem, IntrConvergent]>; + Intrinsic<[llvm_anyint_ty], [llvm_anyint_ty, LLVMMatchType<1>, llvm_i32_ty], + [IntrNoMem, IntrConvergent, ImmArg<2>]>; def int_amdgcn_fcmp : - Intrinsic<[llvm_i64_ty], [llvm_anyfloat_ty, LLVMMatchType<0>, llvm_i32_ty], - [IntrNoMem, IntrConvergent]>; + Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>, llvm_i32_ty], + [IntrNoMem, IntrConvergent, ImmArg<2>]>; def int_amdgcn_readfirstlane : GCCBuiltin<"__builtin_amdgcn_readfirstlane">, @@ -1263,16 +1344,86 @@ def int_amdgcn_writelane : [IntrNoMem, IntrConvergent] >; -def int_amdgcn_alignbit : Intrinsic<[llvm_i32_ty], +def int_amdgcn_alignbit : + GCCBuiltin<"__builtin_amdgcn_alignbit">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrSpeculatable] >; -def int_amdgcn_alignbyte : Intrinsic<[llvm_i32_ty], - [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], +def int_amdgcn_alignbyte : GCCBuiltin<"__builtin_amdgcn_alignbyte">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrSpeculatable] >; +def int_amdgcn_mul_i24 : Intrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; + +def int_amdgcn_mul_u24 : Intrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; + +// llvm.amdgcn.ds.gws.init(i32 bar_val, i32 resource_id) +// +// bar_val is the total number of waves that will wait on this +// barrier, minus 1. +def int_amdgcn_ds_gws_init : + GCCBuiltin<"__builtin_amdgcn_ds_gws_init">, + Intrinsic<[], + [llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrWriteMem, IntrInaccessibleMemOnly], "", + [SDNPMemOperand] +>; + +// llvm.amdgcn.ds.gws.barrier(i32 vsrc0, i32 resource_id) +// bar_val is the total number of waves that will wait on this +// barrier, minus 1. +def int_amdgcn_ds_gws_barrier : + GCCBuiltin<"__builtin_amdgcn_ds_gws_barrier">, + Intrinsic<[], + [llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrInaccessibleMemOnly], "", + [SDNPMemOperand] +>; + +// llvm.amdgcn.ds.gws.sema.v(i32 resource_id) +def int_amdgcn_ds_gws_sema_v : + GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_v">, + Intrinsic<[], + [llvm_i32_ty], + [IntrConvergent, IntrInaccessibleMemOnly], "", + [SDNPMemOperand] +>; + +// llvm.amdgcn.ds.gws.sema.br(i32 vsrc, i32 resource_id) +def int_amdgcn_ds_gws_sema_br : + GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_br">, + Intrinsic<[], + [llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrInaccessibleMemOnly], "", + [SDNPMemOperand] +>; + +// llvm.amdgcn.ds.gws.sema.p(i32 resource_id) +def int_amdgcn_ds_gws_sema_p : + GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_p">, + Intrinsic<[], + [llvm_i32_ty], + [IntrConvergent, IntrInaccessibleMemOnly], "", + [SDNPMemOperand] +>; + +// llvm.amdgcn.ds.gws.sema.release.all(i32 resource_id) +def int_amdgcn_ds_gws_sema_release_all : + GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_release_all">, + Intrinsic<[], + [llvm_i32_ty], + [IntrConvergent, IntrInaccessibleMemOnly], "", + [SDNPMemOperand] +>; + // Copies the source value to the destination value, with the guarantee that // the source value is computed as if the entire program were executed in WQM. @@ -1295,7 +1446,7 @@ def int_amdgcn_kill : Intrinsic<[], [llvm_i1_ty], []>; // enabled, with a few exceptions: - Phi nodes with require WWM return an // undefined value. def int_amdgcn_wwm : Intrinsic<[llvm_any_ty], - [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] + [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrConvergent] >; // Given a value, copies it while setting all the inactive lanes to a given @@ -1328,7 +1479,8 @@ def int_amdgcn_buffer_wbinvl1_vol : def int_amdgcn_mov_dpp : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i1_ty], [IntrNoMem, IntrConvergent]>; + llvm_i1_ty], [IntrNoMem, IntrConvergent, ImmArg<1>, + ImmArg<2>, ImmArg<3>, ImmArg<4>]>; // llvm.amdgcn.update.dpp.i32 <old> <src> <dpp_ctrl> <row_mask> <bank_mask> <bound_ctrl> // Should be equivalent to: @@ -1336,8 +1488,10 @@ def int_amdgcn_mov_dpp : // v_mov_b32 <dest> <src> <dpp_ctrl> <row_mask> <bank_mask> <bound_ctrl> def int_amdgcn_update_dpp : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i1_ty], [IntrNoMem, IntrConvergent]>; + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i1_ty], + [IntrNoMem, IntrConvergent, + ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; def int_amdgcn_s_dcache_wb : GCCBuiltin<"__builtin_amdgcn_s_dcache_wb">, @@ -1349,7 +1503,7 @@ def int_amdgcn_s_dcache_wb_vol : def int_amdgcn_s_memrealtime : GCCBuiltin<"__builtin_amdgcn_s_memrealtime">, - Intrinsic<[llvm_i64_ty], [], [IntrReadMem]>; + Intrinsic<[llvm_i64_ty]>; // llvm.amdgcn.ds.permute <index> <src> def int_amdgcn_ds_permute : @@ -1362,6 +1516,34 @@ def int_amdgcn_ds_bpermute : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>; //===----------------------------------------------------------------------===// +// GFX10 Intrinsics +//===----------------------------------------------------------------------===// + +// llvm.amdgcn.permlane16 <old> <src0> <src1> <src2> <fi> <bound_control> +def int_amdgcn_permlane16 : GCCBuiltin<"__builtin_amdgcn_permlane16">, + Intrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i1_ty], + [IntrNoMem, IntrConvergent, ImmArg<4>, ImmArg<5>]>; + +// llvm.amdgcn.permlanex16 <old> <src0> <src1> <src2> <fi> <bound_control> +def int_amdgcn_permlanex16 : GCCBuiltin<"__builtin_amdgcn_permlanex16">, + Intrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i1_ty], + [IntrNoMem, IntrConvergent, ImmArg<4>, ImmArg<5>]>; + +// llvm.amdgcn.mov.dpp8.i32 <src> <sel> +// <sel> is a 32-bit constant whose high 8 bits must be zero which selects +// the lanes to read from. +def int_amdgcn_mov_dpp8 : + Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, llvm_i32_ty], + [IntrNoMem, IntrConvergent, ImmArg<1>]>; + +def int_amdgcn_s_get_waveid_in_workgroup : + GCCBuiltin<"__builtin_amdgcn_s_get_waveid_in_workgroup">, + Intrinsic<[llvm_i32_ty], [], [IntrReadMem, IntrInaccessibleMemOnly]>; + +//===----------------------------------------------------------------------===// // Deep learning intrinsics. //===----------------------------------------------------------------------===// @@ -1377,7 +1559,7 @@ def int_amdgcn_fdot2 : llvm_float_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; // i32 %r = llvm.amdgcn.sdot2(v2i16 %a, v2i16 %b, i32 %c, i1 %clamp) @@ -1392,7 +1574,7 @@ def int_amdgcn_sdot2 : llvm_i32_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; // u32 %r = llvm.amdgcn.udot2(v2u16 %a, v2u16 %b, u32 %c, i1 %clamp) @@ -1407,7 +1589,7 @@ def int_amdgcn_udot2 : llvm_i32_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; // i32 %r = llvm.amdgcn.sdot4(v4i8 (as i32) %a, v4i8 (as i32) %b, i32 %c, i1 %clamp) @@ -1422,7 +1604,7 @@ def int_amdgcn_sdot4 : llvm_i32_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; // u32 %r = llvm.amdgcn.udot4(v4u8 (as u32) %a, v4u8 (as u32) %b, u32 %c, i1 %clamp) @@ -1437,7 +1619,7 @@ def int_amdgcn_udot4 : llvm_i32_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; // i32 %r = llvm.amdgcn.sdot8(v8i4 (as i32) %a, v8i4 (as i32) %b, i32 %c, i1 %clamp) @@ -1453,7 +1635,7 @@ def int_amdgcn_sdot8 : llvm_i32_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; // u32 %r = llvm.amdgcn.udot8(v8u4 (as u32) %a, v8u4 (as u32) %b, u32 %c, i1 %clamp) @@ -1469,30 +1651,154 @@ def int_amdgcn_udot8 : llvm_i32_ty, // %c llvm_i1_ty // %clamp ], - [IntrNoMem, IntrSpeculatable] + [IntrNoMem, IntrSpeculatable, ImmArg<3>] >; //===----------------------------------------------------------------------===// +// gfx908 intrinsics +// ===----------------------------------------------------------------------===// + +class AMDGPUBufferAtomicNoRtn : Intrinsic < + [], + [llvm_anyfloat_ty, // vdata(VGPR) + llvm_v4i32_ty, // rsrc(SGPR) + llvm_i32_ty, // vindex(VGPR) + llvm_i32_ty, // offset(SGPR/VGPR/imm) + llvm_i1_ty], // slc(imm) + [], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<1, 0>; + +class AMDGPUGlobalAtomicNoRtn : Intrinsic < + [], + [llvm_anyptr_ty, // vaddr + llvm_anyfloat_ty], // vdata(VGPR) + [IntrArgMemOnly, NoCapture<0>], "", [SDNPMemOperand]>; + +def int_amdgcn_buffer_atomic_fadd : AMDGPUBufferAtomicNoRtn; +def int_amdgcn_global_atomic_fadd : AMDGPUGlobalAtomicNoRtn; + +// llvm.amdgcn.mfma.f32.* vdst, srcA, srcB, srcC, cbsz, abid, blgp +def int_amdgcn_mfma_f32_32x32x1f32 : Intrinsic<[llvm_v32f32_ty], + [llvm_float_ty, llvm_float_ty, llvm_v32f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_16x16x1f32 : Intrinsic<[llvm_v16f32_ty], + [llvm_float_ty, llvm_float_ty, llvm_v16f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_4x4x1f32 : Intrinsic<[llvm_v4f32_ty], + [llvm_float_ty, llvm_float_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_32x32x2f32 : Intrinsic<[llvm_v16f32_ty], + [llvm_float_ty, llvm_float_ty, llvm_v16f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_16x16x4f32 : Intrinsic<[llvm_v4f32_ty], + [llvm_float_ty, llvm_float_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_32x32x4f16 : Intrinsic<[llvm_v32f32_ty], + [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v32f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_16x16x4f16 : Intrinsic<[llvm_v16f32_ty], + [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v16f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_4x4x4f16 : Intrinsic<[llvm_v4f32_ty], + [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_32x32x8f16 : Intrinsic<[llvm_v16f32_ty], + [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v16f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_16x16x16f16 : Intrinsic<[llvm_v4f32_ty], + [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_i32_32x32x4i8 : Intrinsic<[llvm_v32i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_v32i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_i32_16x16x4i8 : Intrinsic<[llvm_v16i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_v16i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_i32_4x4x4i8 : Intrinsic<[llvm_v4i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_i32_32x32x8i8 : Intrinsic<[llvm_v16i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_v16i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_i32_16x16x16i8 : Intrinsic<[llvm_v4i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_32x32x2bf16 : Intrinsic<[llvm_v32f32_ty], + [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v32f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_16x16x2bf16 : Intrinsic<[llvm_v16f32_ty], + [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v16f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_4x4x2bf16 : Intrinsic<[llvm_v4f32_ty], + [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_32x32x4bf16 : Intrinsic<[llvm_v16f32_ty], + [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v16f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +def int_amdgcn_mfma_f32_16x16x8bf16 : Intrinsic<[llvm_v4f32_ty], + [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v4f32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; + +//===----------------------------------------------------------------------===// // Special Intrinsics for backend internal use only. No frontend // should emit calls to these. // ===----------------------------------------------------------------------===// -def int_amdgcn_if : Intrinsic<[llvm_i1_ty, llvm_i64_ty], +def int_amdgcn_if : Intrinsic<[llvm_i1_ty, llvm_anyint_ty], [llvm_i1_ty], [IntrConvergent] >; -def int_amdgcn_else : Intrinsic<[llvm_i1_ty, llvm_i64_ty], - [llvm_i64_ty], [IntrConvergent] +def int_amdgcn_else : Intrinsic<[llvm_i1_ty, llvm_anyint_ty], + [llvm_anyint_ty], [IntrConvergent] >; -def int_amdgcn_if_break : Intrinsic<[llvm_i64_ty], - [llvm_i1_ty, llvm_i64_ty], [IntrNoMem, IntrConvergent] +def int_amdgcn_if_break : Intrinsic<[llvm_anyint_ty], + [llvm_i1_ty, llvm_anyint_ty], [IntrNoMem, IntrConvergent] >; def int_amdgcn_loop : Intrinsic<[llvm_i1_ty], - [llvm_i64_ty], [IntrConvergent] + [llvm_anyint_ty], [IntrConvergent] >; -def int_amdgcn_end_cf : Intrinsic<[], [llvm_i64_ty], [IntrConvergent]>; +def int_amdgcn_end_cf : Intrinsic<[], [llvm_anyint_ty], [IntrConvergent]>; // Represent unreachable in a divergent region. def int_amdgcn_unreachable : Intrinsic<[], [], [IntrConvergent]>; diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index 4e11f9c29dd0..4792af097d95 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -1,9 +1,8 @@ //===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -20,7 +19,7 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". // A space-consuming intrinsic primarily for testing ARMConstantIslands. The // first argument is the number of bytes this "instruction" takes up, the second // and return value are essentially chains, used to force ordering during ISel. -def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [ImmArg<0>]>; // 16-bit multiplications def int_arm_smulbb : GCCBuiltin<"__builtin_arm_smulbb">, @@ -263,59 +262,59 @@ def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty], // Coprocessor def int_arm_ldc : GCCBuiltin<"__builtin_arm_ldc">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_ldcl : GCCBuiltin<"__builtin_arm_ldcl">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_ldc2 : GCCBuiltin<"__builtin_arm_ldc2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_ldc2l : GCCBuiltin<"__builtin_arm_ldc2l">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stc : GCCBuiltin<"__builtin_arm_stc">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stcl : GCCBuiltin<"__builtin_arm_stcl">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stc2 : GCCBuiltin<"__builtin_arm_stc2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stc2l : GCCBuiltin<"__builtin_arm_stc2l">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; // Move to coprocessor def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; // Move from coprocessor def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">, MSBuiltin<"_MoveFromCoprocessor">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">, MSBuiltin<"_MoveFromCoprocessor2">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; // Coprocessor data processing def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; // Move from two registers to coprocessor def int_arm_mcrr : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<4>]>; def int_arm_mcrr2 : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<4>]>; def int_arm_mrrc : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>]>; def int_arm_mrrc2 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>]>; //===----------------------------------------------------------------------===// // CRC32 @@ -334,6 +333,18 @@ def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; //===----------------------------------------------------------------------===// +// CMSE + +def int_arm_cmse_tt : GCCBuiltin<"__builtin_arm_cmse_TT">, + Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; +def int_arm_cmse_ttt : GCCBuiltin<"__builtin_arm_cmse_TTT">, + Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; +def int_arm_cmse_tta : GCCBuiltin<"__builtin_arm_cmse_TTA">, + Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; +def int_arm_cmse_ttat : GCCBuiltin<"__builtin_arm_cmse_TTAT">, + Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; + +//===----------------------------------------------------------------------===// // HINT def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>; diff --git a/include/llvm/IR/IntrinsicsBPF.td b/include/llvm/IR/IntrinsicsBPF.td index 94eca8e40332..d7595a2a7700 100644 --- a/include/llvm/IR/IntrinsicsBPF.td +++ b/include/llvm/IR/IntrinsicsBPF.td @@ -1,9 +1,8 @@ //===- IntrinsicsBPF.td - Defines BPF intrinsics -----------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td index ecc69a679553..2abc1dc07ebd 100644 --- a/include/llvm/IR/IntrinsicsHexagon.td +++ b/include/llvm/IR/IntrinsicsHexagon.td @@ -1,8 +1,7 @@ //===- IntrinsicsHexagon.td - Defines Hexagon intrinsics ---*- tablegen -*-===// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -52,19 +51,19 @@ class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [IntrArgMemOnly, ImmArg<3>]>; class Hexagon_mem_memsisisi_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrWriteMem]>; + [IntrWriteMem, ImmArg<3>]>; class Hexagon_mem_memdisisi_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], - [IntrWriteMem]>; + [IntrWriteMem, ImmArg<3>]>; // // BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4) @@ -554,16 +553,18 @@ class Hexagon_v32i32_v32i32v32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : V6_vaslw_acc -class Hexagon_v16i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v16i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vaslw_acc -class Hexagon_v32i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vmux class Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<string GCCIntSuffix> @@ -581,7 +582,7 @@ class Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<string GCCIntSuffix> class Hexagon_i32_i32i32i32i32_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>, ImmArg<3>]>; // tag : V6_vandnqrt_acc class Hexagon_v16i32_v16i32v512i1i32_Intrinsic<string GCCIntSuffix> @@ -596,58 +597,62 @@ class Hexagon_v32i32_v32i32v1024i1i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : V6_vrmpybusi -class Hexagon_v32i32_v32i32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v32i32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vrmpybusi -class Hexagon_v64i32_v64i32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v64i32_v64i32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vsubb_dv -class Hexagon_v64i32_v64i32v64i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v64i32_v64i32v64i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : M2_mpysu_up -class Hexagon_i32_i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i32_i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : M2_mpyud_acc_ll_s0 -class Hexagon_i64_i64i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i64_i64i32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : S2_lsr_i_r_nac -class Hexagon_i32_i32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i32_i32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : M2_cmpysc_s0 -class Hexagon_i64_i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i64_i32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i64_ty], [llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_lo -class Hexagon_v16i32_v32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v16i32_v32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v16i32_ty], [llvm_v32i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_lo -class Hexagon_v32i32_v64i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v64i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v64i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : S2_shuffoh class Hexagon_i64_i64i64_Intrinsic<string GCCIntSuffix> @@ -698,10 +703,10 @@ class Hexagon_v32i32_v32i32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : A4_vcmphgti -class Hexagon_i32_i64i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i32_i64i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_i64_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : class Hexagon_v32i32_v16i32i32_Intrinsic<string GCCIntSuffix> @@ -710,10 +715,11 @@ class Hexagon_v32i32_v16i32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : S6_rol_i_p_or -class Hexagon_i64_i64i64i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i64_i64i64i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vgtuh_and class Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<string GCCIntSuffix> @@ -728,16 +734,18 @@ class Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : A2_abssat -class Hexagon_i32_i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i32_i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : A2_vcmpwgtu -class Hexagon_i32_i64i64_Intrinsic<string GCCIntSuffix> +class Hexagon_i32_i64i64_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_i64_ty,llvm_i64_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vtmpybus_acc class Hexagon_v64i32_v64i32v64i32i32_Intrinsic<string GCCIntSuffix> @@ -764,16 +772,18 @@ class Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : S2_asr_i_p_rnd_goodsyntax -class Hexagon_i64_i64i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i64_i64i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : F2_conv_w2df -class Hexagon_double_i32_Intrinsic<string GCCIntSuffix> +class Hexagon_double_i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_double_ty], [llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vunpackuh class Hexagon_v32i32_v16i32_Intrinsic<string GCCIntSuffix> @@ -866,16 +876,18 @@ class Hexagon_i32_v32i32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : V6_vlutvwhi -class Hexagon_v32i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vlutvwhi -class Hexagon_v64i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v64i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vgtuh class Hexagon_v512i1_v16i32v16i32_Intrinsic<string GCCIntSuffix> @@ -902,10 +914,11 @@ class Hexagon_double_i64_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : S2_vzxthw -class Hexagon_i64_i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i64_i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i64_ty], [llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vtmpyhb class Hexagon_v64i32_v64i32i32_Intrinsic<string GCCIntSuffix> @@ -944,10 +957,11 @@ class Hexagon_v16i32_v16i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : F2_conv_uw2sf -class Hexagon_float_i32_Intrinsic<string GCCIntSuffix> +class Hexagon_float_i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_float_ty], [llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vswap class Hexagon_v32i32_v512i1v16i32v16i32_Intrinsic<string GCCIntSuffix> @@ -1022,16 +1036,17 @@ class Hexagon_v32i32_v32i32v32i32v1024i1_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : V6_vlutvvb_oracc -class Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vlutvvb_oracc -class Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vrmpybub_rtt class Hexagon_v32i32_v16i32i64_Intrinsic<string GCCIntSuffix> @@ -1052,16 +1067,18 @@ class Hexagon_i64i32_i64i64i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : V6_vrsadubi_acc -class Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vrsadubi_acc -class Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : F2_conv_df2sf class Hexagon_float_double_Intrinsic<string GCCIntSuffix> @@ -1166,10 +1183,11 @@ class Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : S2_insertp -class Hexagon_i64_i64i64i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_i64_i64i64i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : F2_sfinvsqrta class Hexagon_floati32_float_Intrinsic<string GCCIntSuffix> @@ -1190,16 +1208,18 @@ class Hexagon_v32i32v32i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix> [IntrNoMem]>; // tag : V6_vlutvwh_oracc -class Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : V6_vlutvwh_oracc -class Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix> +class Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty], - [IntrNoMem]>; + !listconcat([IntrNoMem], intr_properties)>; // tag : F2_dfcmpge class Hexagon_i32_doubledouble_Intrinsic<string GCCIntSuffix> @@ -1223,7 +1243,7 @@ class Hexagon_i32_float_Intrinsic<string GCCIntSuffix> class Hexagon_i32_floati32_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_float_ty,llvm_i32_ty], - [IntrNoMem, Throws]>; + [IntrNoMem, Throws, ImmArg<1>]>; // tag : F2_conv_sf2ud_chop class Hexagon_i64_float_Intrinsic<string GCCIntSuffix> @@ -1292,10 +1312,11 @@ class Hexagon_float_floatfloatfloati32_Intrinsic<string GCCIntSuffix> [IntrNoMem, Throws]>; // tag : F2_dfclass -class Hexagon_i32_doublei32_Intrinsic<string GCCIntSuffix> +class Hexagon_i32_doublei32_Intrinsic<string GCCIntSuffix, + list<IntrinsicProperty> intr_properties = []> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_i32_ty], [llvm_double_ty,llvm_i32_ty], - [IntrNoMem, Throws]>; + !listconcat([IntrNoMem, Throws], intr_properties)>; // tag : V6_vd0 class Hexagon_v16i32__Intrinsic<string GCCIntSuffix> @@ -1393,13 +1414,13 @@ def int_hexagon_A2_vabswsat : Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabswsat">; def int_hexagon_S2_asr_i_r : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r", [ImmArg<1>]>; def int_hexagon_S2_asr_i_p : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p", [ImmArg<1>]>; def int_hexagon_A4_combineri : -Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineri">; +Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineri", [ImmArg<1>]>; def int_hexagon_M2_mpy_nac_sat_hl_s1 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s1">; @@ -1450,7 +1471,7 @@ def int_hexagon_A2_maxup : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_maxup">; def int_hexagon_A4_vcmphgti : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgti">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgti", [ImmArg<1>]>; def int_hexagon_S2_interleave : Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_interleave">; @@ -1471,10 +1492,10 @@ def int_hexagon_C2_cmpgtp : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpgtp">; def int_hexagon_A4_cmphgtui : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgtui">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgtui", [ImmArg<1>]>; def int_hexagon_C2_cmpgti : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgti">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgti", [ImmArg<1>]>; def int_hexagon_M2_mpyi : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyi">; @@ -1492,16 +1513,16 @@ def int_hexagon_M2_mpy_lh_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_lh_s0">; def int_hexagon_S2_lsr_i_r_xacc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_xacc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_xacc", [ImmArg<2>]>; def int_hexagon_S2_vrcnegh : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vrcnegh">; def int_hexagon_S2_extractup : -Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S2_extractup">; +Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S2_extractup", [ImmArg<1>, ImmArg<2>]>; def int_hexagon_S2_asr_i_p_rnd_goodsyntax : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd_goodsyntax">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd_goodsyntax", [ImmArg<1>]>; def int_hexagon_S4_ntstbit_r : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_r">; @@ -1528,10 +1549,10 @@ def int_hexagon_S2_asr_r_r_and : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_and">; def int_hexagon_A4_rcmpneqi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpneqi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpneqi", [ImmArg<1>]>; def int_hexagon_S2_asl_i_r_nac : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_nac">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_nac", [ImmArg<2>]>; def int_hexagon_M2_subacc : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_subacc">; @@ -1546,10 +1567,10 @@ def int_hexagon_M2_mpy_acc_sat_lh_s1 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s1">; def int_hexagon_S2_asr_i_vh : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vh">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vh", [ImmArg<1>]>; def int_hexagon_S2_asr_i_vw : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vw">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vw", [ImmArg<1>]>; def int_hexagon_A4_cmpbgtu : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtu">; @@ -1558,7 +1579,7 @@ def int_hexagon_A4_vcmpbeq_any : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A4_vcmpbeq_any">; def int_hexagon_A4_cmpbgti : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgti">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgti", [ImmArg<1>]>; def int_hexagon_M2_mpyd_lh_s1 : Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_lh_s1">; @@ -1567,7 +1588,7 @@ def int_hexagon_S2_asl_r_p_nac : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_nac">; def int_hexagon_S2_lsr_i_r_nac : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_nac">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_nac", [ImmArg<2>]>; def int_hexagon_A2_addsp : Hexagon_i64_i32i64_Intrinsic<"HEXAGON_A2_addsp">; @@ -1576,7 +1597,7 @@ def int_hexagon_S4_vxsubaddw : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddw">; def int_hexagon_A4_vcmpheqi : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpheqi">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpheqi", [ImmArg<1>]>; def int_hexagon_S4_vxsubaddh : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddh">; @@ -1603,16 +1624,16 @@ def int_hexagon_A2_pxorf : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_A2_pxorf">; def int_hexagon_C2_cmpgei : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgei">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgei", [ImmArg<1>]>; def int_hexagon_A2_vsubub : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubub">; def int_hexagon_S2_asl_i_p : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_p">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_p", [ImmArg<1>]>; def int_hexagon_S2_asl_i_r : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r", [ImmArg<1>]>; def int_hexagon_A4_vrminuw : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminuw">; @@ -1642,10 +1663,10 @@ def int_hexagon_C2_bitsset : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsset">; def int_hexagon_M2_mpysip : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysip">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysip", [ImmArg<1>]>; def int_hexagon_M2_mpysin : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysin">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysin", [ImmArg<1>]>; def int_hexagon_A4_boundscheck : Hexagon_i32_i32i64_Intrinsic<"HEXAGON_A4_boundscheck">; @@ -1684,10 +1705,10 @@ def int_hexagon_A2_vnavgw : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgw">; def int_hexagon_S2_asl_i_r_acc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_acc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_acc", [ImmArg<2>]>; def int_hexagon_S4_subi_lsr_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_lsr_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_lsr_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_S2_vzxthw : Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vzxthw">; @@ -1714,7 +1735,7 @@ def int_hexagon_S2_packhl : Hexagon_i64_i32i32_Intrinsic<"HEXAGON_S2_packhl">; def int_hexagon_A4_vcmpwgti : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgti">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgti", [ImmArg<1>]>; def int_hexagon_A2_vavguwr : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguwr">; @@ -1735,7 +1756,7 @@ def int_hexagon_F2_conv_d2df : Hexagon_double_i64_Intrinsic<"HEXAGON_F2_conv_d2df">; def int_hexagon_C2_cmpgtui : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgtui">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgtui", [ImmArg<1>]>; def int_hexagon_A2_vconj : Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vconj">; @@ -1765,7 +1786,7 @@ def int_hexagon_S2_togglebit_r : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_r">; def int_hexagon_S2_togglebit_i : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_i">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_i", [ImmArg<1>]>; def int_hexagon_F2_conv_uw2sf : Hexagon_float_i32_Intrinsic<"HEXAGON_F2_conv_uw2sf">; @@ -1801,10 +1822,10 @@ def int_hexagon_S2_asl_r_r_nac : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_nac">; def int_hexagon_S2_asl_i_p_acc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_acc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_acc", [ImmArg<2>]>; def int_hexagon_A4_vcmpwgtui : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgtui">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgtui", [ImmArg<1>]>; def int_hexagon_M4_vrmpyoh_acc_s0 : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s0">; @@ -1831,7 +1852,7 @@ def int_hexagon_A2_vavgwcr : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgwcr">; def int_hexagon_S2_asl_i_p_xacc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_xacc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_xacc", [ImmArg<2>]>; def int_hexagon_A4_vrmaxw : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxw">; @@ -1843,22 +1864,22 @@ def int_hexagon_M4_cmpyi_wh : Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyi_wh">; def int_hexagon_A2_tfrsi : -Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrsi">; +Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrsi", [ImmArg<0>]>; def int_hexagon_S2_asr_i_r_acc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_acc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_acc", [ImmArg<2>]>; def int_hexagon_A2_svnavgh : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svnavgh">; def int_hexagon_S2_lsr_i_r : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r", [ImmArg<1>]>; def int_hexagon_M2_vmac2 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2">; def int_hexagon_A4_vcmphgtui : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgtui">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgtui", [ImmArg<1>]>; def int_hexagon_A2_svavgh : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svavgh">; @@ -1870,7 +1891,7 @@ def int_hexagon_M4_vrmpyeh_acc_s1 : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s1">; def int_hexagon_S2_lsr_i_p : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p", [ImmArg<1>]>; def int_hexagon_A2_combine_hl : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_hl">; @@ -1909,7 +1930,7 @@ def int_hexagon_M2_mmpyul_rs0 : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_rs0">; def int_hexagon_S2_asr_i_r_rnd_goodsyntax : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd_goodsyntax">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd_goodsyntax", [ImmArg<1>]>; def int_hexagon_S2_lsr_r_p_nac : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_nac">; @@ -1924,10 +1945,10 @@ def int_hexagon_M4_or_and : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_and">; def int_hexagon_M4_mpyrr_addi : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyrr_addi">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyrr_addi", [ImmArg<0>]>; def int_hexagon_S4_or_andi : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andi">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andi", [ImmArg<2>]>; def int_hexagon_M2_mpy_sat_hl_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s0">; @@ -2032,7 +2053,7 @@ def int_hexagon_F2_sffms_lib : Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffms_lib">; def int_hexagon_C4_cmpneqi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpneqi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpneqi", [ImmArg<1>]>; def int_hexagon_M4_and_xor : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_xor">; @@ -2056,7 +2077,7 @@ def int_hexagon_A2_vrsadub_acc : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_A2_vrsadub_acc">; def int_hexagon_C2_bitsclri : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsclri">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsclri", [ImmArg<1>]>; def int_hexagon_A2_subh_h16_sat_hh : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_hh">; @@ -2158,10 +2179,10 @@ def int_hexagon_S2_parityp : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_S2_parityp">; def int_hexagon_S2_lsr_i_p_and : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_and">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_and", [ImmArg<2>]>; def int_hexagon_S2_asr_i_r_or : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_or">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_or", [ImmArg<2>]>; def int_hexagon_M2_mpyu_nac_ll_s0 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s0">; @@ -2191,7 +2212,7 @@ def int_hexagon_M2_cnacsc_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacsc_s0">; def int_hexagon_S4_subaddi : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subaddi">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subaddi", [ImmArg<1>]>; def int_hexagon_M2_mpyud_nac_hl_s1 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s1">; @@ -2200,13 +2221,13 @@ def int_hexagon_M2_mpyud_nac_hl_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s0">; def int_hexagon_S5_vasrhrnd_goodsyntax : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S5_vasrhrnd_goodsyntax">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S5_vasrhrnd_goodsyntax", [ImmArg<1>]>; def int_hexagon_S2_tstbit_r : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_r">; def int_hexagon_S4_vrcrotate : -Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate">; +Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate", [ImmArg<2>]>; def int_hexagon_M2_mmachs_s1 : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_s1">; @@ -2215,7 +2236,7 @@ def int_hexagon_M2_mmachs_s0 : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_s0">; def int_hexagon_S2_tstbit_i : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_i">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_i", [ImmArg<1>]>; def int_hexagon_M2_mpy_up_s1 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up_s1">; @@ -2227,7 +2248,7 @@ def int_hexagon_M2_mmpyuh_rs0 : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_rs0">; def int_hexagon_S2_lsr_i_vw : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vw">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vw", [ImmArg<1>]>; def int_hexagon_M2_mpy_rnd_ll_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s0">; @@ -2266,16 +2287,16 @@ def int_hexagon_A2_subh_l16_sat_hl : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_sat_hl">; def int_hexagon_C2_cmpeqi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpeqi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpeqi", [ImmArg<1>]>; def int_hexagon_S2_asl_i_r_and : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_and">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_and", [ImmArg<2>]>; def int_hexagon_S2_vcnegh : Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_vcnegh">; def int_hexagon_A4_vcmpweqi : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpweqi">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpweqi", [ImmArg<1>]>; def int_hexagon_M2_vdmpyrs_s0 : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vdmpyrs_s0">; @@ -2308,7 +2329,7 @@ def int_hexagon_S2_cl0p : Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_cl0p">; def int_hexagon_S2_valignib : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_valignib">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_valignib", [ImmArg<2>]>; def int_hexagon_F2_sffixupd : Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sffixupd">; @@ -2338,7 +2359,7 @@ def int_hexagon_M2_mmpyul_rs1 : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_rs1">; def int_hexagon_S4_ntstbit_i : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_i">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_i", [ImmArg<1>]> ; def int_hexagon_F2_sffixupr : Hexagon_float_float_Intrinsic<"HEXAGON_F2_sffixupr">; @@ -2362,7 +2383,7 @@ def int_hexagon_M2_vmpy2s_s0pack : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s0pack">; def int_hexagon_S4_addaddi : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addaddi">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addaddi", [ImmArg<2>]>; def int_hexagon_M2_mpyd_acc_ll_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s0">; @@ -2371,13 +2392,13 @@ def int_hexagon_M2_mpy_acc_sat_hl_s1 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s1">; def int_hexagon_A4_rcmpeqi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpeqi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpeqi", [ImmArg<1>]>; def int_hexagon_M4_xor_and : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_and">; def int_hexagon_S2_asl_i_p_and : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_and">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_and", [ImmArg<2>]>; def int_hexagon_M2_mmpyuh_rs1 : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_rs1">; @@ -2386,7 +2407,7 @@ def int_hexagon_S2_asr_r_r_or : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_or">; def int_hexagon_A4_round_ri : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri", [ImmArg<1>]>; def int_hexagon_A2_max : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_max">; @@ -2395,10 +2416,10 @@ def int_hexagon_A4_round_rr : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_rr">; def int_hexagon_A4_combineii : -Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineii">; +Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineii", [ImmArg<0>, ImmArg<1>]>; def int_hexagon_A4_combineir : -Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineir">; +Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineir", [ImmArg<0>]>; def int_hexagon_C4_and_orn : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_orn">; @@ -2413,7 +2434,7 @@ def int_hexagon_M4_cmpyr_whc : Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyr_whc">; def int_hexagon_S2_lsr_i_r_acc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_acc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_acc", [ImmArg<2>]>; def int_hexagon_S2_vzxtbh : Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vzxtbh">; @@ -2440,7 +2461,7 @@ def int_hexagon_S2_asl_r_p_or : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_or">; def int_hexagon_S4_ori_asl_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_asl_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_asl_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_C4_nbitsset : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsset">; @@ -2476,10 +2497,10 @@ def int_hexagon_M2_mpyd_acc_hh_s1 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s1">; def int_hexagon_F2_sfimm_p : -Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_p">; +Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_p", [ImmArg<0>]>; def int_hexagon_F2_sfimm_n : -Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_n">; +Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_n", [ImmArg<0>]>; def int_hexagon_M4_cmpyr_wh : Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyr_wh">; @@ -2497,7 +2518,7 @@ def int_hexagon_A2_vavguh : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguh">; def int_hexagon_A4_cmpbeqi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbeqi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbeqi", [ImmArg<1>]>; def int_hexagon_F2_sfcmpuo : Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpuo">; @@ -2506,7 +2527,7 @@ def int_hexagon_A2_vavguw : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguw">; def int_hexagon_S2_asr_i_p_nac : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_nac">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_nac", [ImmArg<2>]>; def int_hexagon_S2_vsatwh_nopack : Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsatwh_nopack">; @@ -2533,7 +2554,7 @@ def int_hexagon_A2_minp : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_minp">; def int_hexagon_S4_or_andix : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andix">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andix", [ImmArg<2>]>; def int_hexagon_M2_mpy_rnd_lh_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s0">; @@ -2584,19 +2605,19 @@ def int_hexagon_S2_lsl_r_r_or : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_or">; def int_hexagon_C4_cmplteui : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteui">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteui", [ImmArg<1>]>; def int_hexagon_S4_addi_lsr_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_lsr_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_lsr_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_A4_tfrcpp : Hexagon_i64_i64_Intrinsic<"HEXAGON_A4_tfrcpp">; def int_hexagon_S2_asr_i_svw_trun : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S2_asr_i_svw_trun">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S2_asr_i_svw_trun", [ImmArg<1>]>; def int_hexagon_A4_cmphgti : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgti">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgti", [ImmArg<1>]>; def int_hexagon_A4_vrminh : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminh">; @@ -2614,7 +2635,7 @@ def int_hexagon_A2_vnavghcr : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavghcr">; def int_hexagon_S4_subi_asl_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_asl_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_asl_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_S2_lsl_r_vh : Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_vh">; @@ -2638,7 +2659,7 @@ def int_hexagon_C2_cmpltu : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpltu">; def int_hexagon_S2_insertp : -Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S2_insertp">; +Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S2_insertp", [ImmArg<2>, ImmArg<3>]>; def int_hexagon_M2_mpyd_rnd_ll_s1 : Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s1">; @@ -2647,7 +2668,7 @@ def int_hexagon_M2_mpyd_rnd_ll_s0 : Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s0">; def int_hexagon_S2_lsr_i_p_nac : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_nac">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_nac", [ImmArg<2>]>; def int_hexagon_S2_extractup_rp : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_extractup_rp">; @@ -2749,7 +2770,7 @@ def int_hexagon_M2_dpmpyss_rnd_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_rnd_s0">; def int_hexagon_C2_muxri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxri", [ImmArg<1>]>; def int_hexagon_M2_vmac2es_s0 : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es_s0">; @@ -2767,7 +2788,7 @@ def int_hexagon_M2_mpyu_lh_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_lh_s0">; def int_hexagon_S2_asl_i_r_or : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_or">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_or", [ImmArg<2>]>; def int_hexagon_M2_mpyd_acc_hl_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s0">; @@ -2782,7 +2803,7 @@ def int_hexagon_A2_vaddw : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddw">; def int_hexagon_S2_asr_i_r_and : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_and">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_and", [ImmArg<2>]>; def int_hexagon_A2_vaddh : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddh">; @@ -2797,22 +2818,22 @@ def int_hexagon_C2_cmpeqp : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpeqp">; def int_hexagon_M4_mpyri_addi : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addi">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addi", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_A2_not : Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_not">; def int_hexagon_S4_andi_lsr_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_lsr_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_lsr_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_M2_macsip : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsip">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsip", [ImmArg<2>]>; def int_hexagon_A2_tfrcrr : Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrcrr">; def int_hexagon_M2_macsin : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsin">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsin", [ImmArg<2>]>; def int_hexagon_C2_orn : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_orn">; @@ -2875,7 +2896,7 @@ def int_hexagon_F2_dfcmpge : Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpge">; def int_hexagon_M2_accii : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_accii">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_accii", [ImmArg<2>]>; def int_hexagon_A5_vaddhubs : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A5_vaddhubs">; @@ -2893,10 +2914,10 @@ def int_hexagon_S2_vsxthw : Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsxthw">; def int_hexagon_S4_andi_asl_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_asl_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_asl_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_S2_asl_i_p_nac : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_nac">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_nac", [ImmArg<2>]>; def int_hexagon_S2_lsl_r_p_xor : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_xor">; @@ -2929,7 +2950,7 @@ def int_hexagon_M4_xor_andn : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_andn">; def int_hexagon_S2_addasl_rrri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_addasl_rrri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_addasl_rrri", [ImmArg<2>]>; def int_hexagon_M5_vdmpybsu : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vdmpybsu">; @@ -2941,7 +2962,7 @@ def int_hexagon_M2_mpyu_nac_hh_s1 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s1">; def int_hexagon_A2_addi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addi", [ImmArg<1>]>; def int_hexagon_A2_addp : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_addp">; @@ -2962,7 +2983,7 @@ def int_hexagon_S2_shuffeh : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffeh">; def int_hexagon_S2_lsr_i_r_and : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_and">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_and", [ImmArg<2>]>; def int_hexagon_M2_mpy_sat_rnd_hh_s1 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s1">; @@ -3064,13 +3085,13 @@ def int_hexagon_S5_popcountp : Hexagon_i32_i64_Intrinsic<"HEXAGON_S5_popcountp">; def int_hexagon_S4_extractp : -Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_extractp">; +Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_extractp", [ImmArg<1>, ImmArg<2>]>; def int_hexagon_S2_cl0 : Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_cl0">; def int_hexagon_A4_vcmpbgti : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgti">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgti", [ImmArg<1>]>; def int_hexagon_M2_mmacls_s1 : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_s1">; @@ -3118,7 +3139,7 @@ def int_hexagon_A2_vmaxuh : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxuh">; def int_hexagon_A4_bitspliti : -Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_bitspliti">; +Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_bitspliti", [ImmArg<1>]>; def int_hexagon_A2_vmaxub : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxub">; @@ -3145,13 +3166,13 @@ def int_hexagon_S2_asr_r_r_nac : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_nac">; def int_hexagon_F2_dfimm_n : -Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_n">; +Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_n", [ImmArg<0>]>; def int_hexagon_A4_cmphgt : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgt">; def int_hexagon_F2_dfimm_p : -Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_p">; +Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_p", [ImmArg<0>]>; def int_hexagon_M2_mpyud_acc_lh_s1 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s1">; @@ -3160,7 +3181,7 @@ def int_hexagon_M2_vcmpy_s1_sat_r : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_r">; def int_hexagon_M4_mpyri_addr_u2 : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr_u2">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr_u2", [ImmArg<1>]>; def int_hexagon_M2_vcmpy_s1_sat_i : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_i">; @@ -3172,10 +3193,10 @@ def int_hexagon_M5_vrmacbuu : Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vrmacbuu">; def int_hexagon_S5_asrhub_rnd_sat_goodsyntax : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_rnd_sat_goodsyntax">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_rnd_sat_goodsyntax", [ImmArg<1>]>; def int_hexagon_S2_vspliceib : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vspliceib">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vspliceib", [ImmArg<2>]>; def int_hexagon_M2_dpmpyss_acc_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_acc_s0">; @@ -3193,25 +3214,25 @@ def int_hexagon_A2_maxp : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_maxp">; def int_hexagon_A2_andir : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_andir">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_andir", [ImmArg<1>]>; def int_hexagon_F2_sfrecipa : Hexagon_floati32_floatfloat_Intrinsic<"HEXAGON_F2_sfrecipa">; def int_hexagon_A2_combineii : -Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A2_combineii">; +Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A2_combineii", [ImmArg<0>, ImmArg<1>]>; def int_hexagon_A4_orn : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_orn">; def int_hexagon_A4_cmpbgtui : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtui">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtui", [ImmArg<1>]>; def int_hexagon_S2_lsr_r_r_or : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_or">; def int_hexagon_A4_vcmpbeqi : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbeqi">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbeqi", [ImmArg<1>]>; def int_hexagon_S2_lsl_r_r : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r">; @@ -3247,19 +3268,19 @@ def int_hexagon_M2_vrcmpys_s1 : Hexagon_i64_i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_s1">; def int_hexagon_S4_or_ori : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_ori">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_ori", [ImmArg<2>]>; def int_hexagon_C4_fastcorner9_not : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_fastcorner9_not">; def int_hexagon_A2_tfrih : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfrih">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfrih", [ImmArg<1>]>; def int_hexagon_A2_tfril : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfril">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfril", [ImmArg<1>]>; def int_hexagon_M4_mpyri_addr : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr", [ImmArg<2>]>; def int_hexagon_S2_vtrunehb : Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vtrunehb">; @@ -3274,16 +3295,16 @@ def int_hexagon_F2_sfsub : Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfsub">; def int_hexagon_C2_muxii : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxii">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxii", [ImmArg<1>, ImmArg<2>]>; def int_hexagon_C2_muxir : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxir">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxir", [ImmArg<2>]>; def int_hexagon_A2_swiz : Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_swiz">; def int_hexagon_S2_asr_i_p_and : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_and">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_and", [ImmArg<2>]>; def int_hexagon_M2_cmpyrsc_s0 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrsc_s0">; @@ -3313,7 +3334,7 @@ def int_hexagon_M2_mpy_nac_sat_ll_s0 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s0">; def int_hexagon_S4_extract : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_extract">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_extract", [ImmArg<1>, ImmArg<2>]>; def int_hexagon_A2_vcmpweq : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpweq">; @@ -3322,10 +3343,10 @@ def int_hexagon_M2_acci : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_acci">; def int_hexagon_S2_lsr_i_p_acc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_acc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_acc", [ImmArg<2>]>; def int_hexagon_S2_lsr_i_p_or : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_or">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_or", [ImmArg<2>]>; def int_hexagon_F2_conv_ud2sf : Hexagon_float_i64_Intrinsic<"HEXAGON_F2_conv_ud2sf">; @@ -3334,10 +3355,10 @@ def int_hexagon_A2_tfr : Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfr">; def int_hexagon_S2_asr_i_p_or : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_or">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_or", [ImmArg<2>]>; def int_hexagon_A2_subri : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subri">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subri", [ImmArg<0>]>; def int_hexagon_A4_vrmaxuw : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxuw">; @@ -3349,7 +3370,7 @@ def int_hexagon_A4_vrmaxuh : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxuh">; def int_hexagon_S2_asl_i_vw : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vw">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vw", [ImmArg<1>]>; def int_hexagon_A2_vavgw : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgw">; @@ -3361,13 +3382,13 @@ def int_hexagon_A2_vavgh : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgh">; def int_hexagon_S2_clrbit_i : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_clrbit_i">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_clrbit_i", [ImmArg<1>]>; def int_hexagon_S2_asl_i_vh : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vh">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vh", [ImmArg<1>]>; def int_hexagon_S2_lsr_i_r_or : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_or">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_or", [ImmArg<2>]>; def int_hexagon_S2_lsl_r_r_nac : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_nac">; @@ -3385,7 +3406,7 @@ def int_hexagon_M2_mmpyl_s1 : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_s1">; def int_hexagon_M2_naccii : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_naccii">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_naccii", [ImmArg<2>]>; def int_hexagon_S2_vrndpackwhs : Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vrndpackwhs">; @@ -3406,7 +3427,7 @@ def int_hexagon_M4_mac_up_s1_sat : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mac_up_s1_sat">; def int_hexagon_S4_vrcrotate_acc : -Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate_acc">; +Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate_acc", [ImmArg<3>]>; def int_hexagon_F2_conv_uw2df : Hexagon_double_i32_Intrinsic<"HEXAGON_F2_conv_uw2df">; @@ -3418,7 +3439,7 @@ def int_hexagon_S2_asr_r_r_acc : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_acc">; def int_hexagon_A2_orir : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_orir">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_orir", [ImmArg<1>]>; def int_hexagon_A2_andp : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_andp">; @@ -3430,7 +3451,7 @@ def int_hexagon_A2_min : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_min">; def int_hexagon_M2_mpysmi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysmi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysmi", [ImmArg<1>]>; def int_hexagon_M2_vcmpy_s0_sat_r : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_r">; @@ -3466,10 +3487,10 @@ def int_hexagon_F2_conv_df2w : Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2w">; def int_hexagon_S5_asrhub_sat : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_sat">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_sat", [ImmArg<1>]>; def int_hexagon_S2_asl_i_r_xacc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_xacc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_xacc", [ImmArg<2>]>; def int_hexagon_F2_conv_df2d : Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2d">; @@ -3505,7 +3526,7 @@ def int_hexagon_F2_sffma_sc : Hexagon_float_floatfloatfloati32_Intrinsic<"HEXAGON_F2_sffma_sc">; def int_hexagon_F2_dfclass : -Hexagon_i32_doublei32_Intrinsic<"HEXAGON_F2_dfclass">; +Hexagon_i32_doublei32_Intrinsic<"HEXAGON_F2_dfclass", [ImmArg<1>]>; def int_hexagon_F2_conv_df2ud : Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2ud">; @@ -3520,7 +3541,7 @@ def int_hexagon_M2_cmpyrs_s1 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrs_s1">; def int_hexagon_C4_cmpltei : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpltei">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpltei", [ImmArg<1>]>; def int_hexagon_C4_cmplteu : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteu">; @@ -3532,7 +3553,7 @@ def int_hexagon_A2_subh_l16_ll : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_ll">; def int_hexagon_S2_asr_i_r_rnd : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd", [ImmArg<1>]>; def int_hexagon_M2_vrmpy_s0 : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrmpy_s0">; @@ -3577,7 +3598,7 @@ def int_hexagon_M2_vrcmpyi_s0c : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyi_s0c">; def int_hexagon_S2_asr_i_p_rnd : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd", [ImmArg<1>]>; def int_hexagon_A2_addpsat : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_addpsat">; @@ -3586,7 +3607,7 @@ def int_hexagon_A2_svaddhs : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svaddhs">; def int_hexagon_S4_ori_lsr_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_lsr_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_lsr_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_M2_mpy_sat_rnd_ll_s1 : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s1">; @@ -3619,7 +3640,7 @@ def int_hexagon_S2_asl_r_r_or : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_or">; def int_hexagon_S4_lsli : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_lsli">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_lsli", [ImmArg<0>]>; def int_hexagon_S2_lsl_r_vw : Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_vw">; @@ -3664,7 +3685,7 @@ def int_hexagon_A2_negp : Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_negp">; def int_hexagon_S2_asl_i_r_sat : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_sat">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_sat", [ImmArg<1>]>; def int_hexagon_A2_addh_l16_sat_hl : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_sat_hl">; @@ -3682,10 +3703,10 @@ def int_hexagon_C2_cmpgtup : Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpgtup">; def int_hexagon_A4_cround_ri : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_ri">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_ri", [ImmArg<1>]>; def int_hexagon_S4_clbpaddi : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S4_clbpaddi">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S4_clbpaddi", [ImmArg<1>]>; def int_hexagon_A4_cround_rr : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_rr">; @@ -3715,13 +3736,13 @@ def int_hexagon_A2_vminub : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminub">; def int_hexagon_S2_extractu : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_extractu">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_extractu", [ImmArg<1>, ImmArg<2>]>; def int_hexagon_A2_svsubh : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubh">; def int_hexagon_S4_clbaddi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_clbaddi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_clbaddi", [ImmArg<1>]>; def int_hexagon_F2_sffms : Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffms">; @@ -3754,7 +3775,7 @@ def int_hexagon_M2_mpy_acc_hh_s0 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s0">; def int_hexagon_S4_addi_asl_ri : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_asl_ri">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_asl_ri", [ImmArg<0>, ImmArg<2>]>; def int_hexagon_M2_mpyd_nac_hh_s1 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s1">; @@ -3763,10 +3784,10 @@ def int_hexagon_M2_mpyd_nac_hh_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s0">; def int_hexagon_S2_asr_i_r_nac : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_nac">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_nac", [ImmArg<2>]>; def int_hexagon_A4_cmpheqi : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpheqi">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpheqi", [ImmArg<1>]>; def int_hexagon_S2_lsr_r_p_xor : Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_xor">; @@ -3781,7 +3802,7 @@ def int_hexagon_F2_conv_sf2ud_chop : Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2ud_chop">; def int_hexagon_C2_cmpgeui : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgeui">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgeui", [ImmArg<1>]>; def int_hexagon_M2_mpy_acc_sat_hh_s0 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s0">; @@ -3808,7 +3829,7 @@ def int_hexagon_M2_mpyud_nac_lh_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s0">; def int_hexagon_A4_round_ri_sat : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri_sat">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri_sat", [ImmArg<1>]>; def int_hexagon_M2_mpy_nac_hl_s0 : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s0">; @@ -3829,10 +3850,10 @@ def int_hexagon_M2_cmaci_s0 : Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmaci_s0">; def int_hexagon_S2_setbit_i : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_setbit_i">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_setbit_i", [ImmArg<1>]>; def int_hexagon_S2_asl_i_p_or : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_or">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_or", [ImmArg<2>]>; def int_hexagon_A4_andn : Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_andn">; @@ -3856,13 +3877,13 @@ def int_hexagon_M2_xor_xacc : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_xor_xacc">; def int_hexagon_A4_vcmpbgtui : -Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgtui">; +Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgtui", [ImmArg<1>]>; def int_hexagon_A4_ornp : Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A4_ornp">; def int_hexagon_A2_tfrpi : -Hexagon_i64_i32_Intrinsic<"HEXAGON_A2_tfrpi">; +Hexagon_i64_i32_Intrinsic<"HEXAGON_A2_tfrpi", [ImmArg<0>]>; def int_hexagon_C4_and_or : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_or">; @@ -3886,16 +3907,16 @@ def int_hexagon_M2_vmpy2su_s0 : Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2su_s0">; def int_hexagon_S2_asr_i_p_acc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_acc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_acc", [ImmArg<2>]>; def int_hexagon_C4_nbitsclri : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsclri">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsclri", [ImmArg<1>]>; def int_hexagon_S2_lsr_i_vh : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vh">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vh", [ImmArg<1>]>; def int_hexagon_S2_lsr_i_p_xacc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_xacc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_xacc", [ImmArg<2>]>; // V55 Scalar Instructions. @@ -3905,40 +3926,40 @@ Hexagon_i64i32_i64i64i64_Intrinsic<"HEXAGON_A5_ACS">; // V60 Scalar Instructions. def int_hexagon_S6_rol_i_p_and : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_and">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_and", [ImmArg<2>]>; def int_hexagon_S6_rol_i_r_xacc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_xacc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_xacc", [ImmArg<2>]>; def int_hexagon_S6_rol_i_r_and : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_and">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_and", [ImmArg<2>]>; def int_hexagon_S6_rol_i_r_acc : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_acc">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_acc", [ImmArg<2>]>; def int_hexagon_S6_rol_i_p_xacc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_xacc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_xacc", [ImmArg<2>]>; def int_hexagon_S6_rol_i_p : -Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S6_rol_i_p">; +Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S6_rol_i_p", [ImmArg<1>]>; def int_hexagon_S6_rol_i_p_nac : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_nac">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_nac", [ImmArg<2>]>; def int_hexagon_S6_rol_i_p_acc : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_acc">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_acc", [ImmArg<2>]>; def int_hexagon_S6_rol_i_r_or : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_or">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_or", [ImmArg<2>]>; def int_hexagon_S6_rol_i_r : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S6_rol_i_r">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S6_rol_i_r", [ImmArg<1>]>; def int_hexagon_S6_rol_i_r_nac : -Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_nac">; +Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_nac", [ImmArg<2>]>; def int_hexagon_S6_rol_i_p_or : -Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_or">; +Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_or", [ImmArg<2>]>; // V62 Scalar Instructions. @@ -3980,7 +4001,7 @@ def int_hexagon_M2_mnaci : Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mnaci">; def int_hexagon_S2_mask : -Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_mask">; +Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_mask", [ImmArg<0>, ImmArg<1>]>; // V60 HVX Instructions. @@ -4021,10 +4042,10 @@ def int_hexagon_V6_vaddh_dv_128B : Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddh_dv_128B">; def int_hexagon_V6_vrmpybusi : -Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi">; +Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi", [ImmArg<2>]>; def int_hexagon_V6_vrmpybusi_128B : -Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_128B">; +Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_128B", [ImmArg<2>]>; def int_hexagon_V6_vshufoh : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoh">; @@ -4045,10 +4066,10 @@ def int_hexagon_V6_vdmpyhsuisat_128B : Hexagon_v32i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_128B">; def int_hexagon_V6_vrsadubi_acc : -Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc">; +Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc", [ImmArg<3>]>; def int_hexagon_V6_vrsadubi_acc_128B : -Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc_128B">; +Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc_128B", [ImmArg<3>]>; def int_hexagon_V6_vnavgw : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgw">; @@ -4915,10 +4936,10 @@ def int_hexagon_V6_vsubhsat_128B : Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhsat_128B">; def int_hexagon_V6_vrmpyubi_acc : -Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc">; +Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc", [ImmArg<3>]>; def int_hexagon_V6_vrmpyubi_acc_128B : -Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc_128B">; +Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc_128B", [ImmArg<3>]>; def int_hexagon_V6_vabsw : Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsw">; @@ -5095,10 +5116,10 @@ def int_hexagon_V6_vmpybv_acc_128B : Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybv_acc_128B">; def int_hexagon_V6_vrsadubi : -Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi">; +Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi", [ImmArg<2>]>; def int_hexagon_V6_vrsadubi_128B : -Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_128B">; +Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_128B", [ImmArg<2>]>; def int_hexagon_V6_vdmpyhb_dv_acc : Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc">; @@ -5377,10 +5398,10 @@ def int_hexagon_V6_vaddbnq_128B : Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbnq_128B">; def int_hexagon_V6_vlalignbi : -Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlalignbi">; +Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlalignbi", [ImmArg<2>]>; def int_hexagon_V6_vlalignbi_128B : -Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlalignbi_128B">; +Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlalignbi_128B", [ImmArg<2>]>; def int_hexagon_V6_vsatwh : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatwh">; @@ -5443,10 +5464,10 @@ def int_hexagon_V6_veqh_and_128B : Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqh_and_128B">; def int_hexagon_V6_valignbi : -Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_valignbi">; +Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_valignbi", [ImmArg<2>]>; def int_hexagon_V6_valignbi_128B : -Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_valignbi_128B">; +Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_valignbi_128B", [ImmArg<2>]>; def int_hexagon_V6_vaddwsat : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddwsat">; @@ -5689,10 +5710,10 @@ def int_hexagon_V6_vsubh_128B : Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubh_128B">; def int_hexagon_V6_vrmpyubi : -Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi">; +Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi", [ImmArg<2>]>; def int_hexagon_V6_vrmpyubi_128B : -Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_128B">; +Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_128B", [ImmArg<2>]>; def int_hexagon_V6_vminw : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminw">; @@ -5755,10 +5776,10 @@ def int_hexagon_V6_vsubuhw_128B : Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhw_128B">; def int_hexagon_V6_vrmpybusi_acc : -Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc">; +Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc", [ImmArg<3>]>; def int_hexagon_V6_vrmpybusi_acc_128B : -Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc_128B">; +Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc_128B", [ImmArg<3>]>; def int_hexagon_V6_vasrw : Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vasrw">; @@ -5883,10 +5904,10 @@ def int_hexagon_V6_vlsrb_128B : Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrb_128B">; def int_hexagon_V6_vlutvwhi : -Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi">; +Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi", [ImmArg<2>]>; def int_hexagon_V6_vlutvwhi_128B : -Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi_128B">; +Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi_128B", [ImmArg<2>]>; def int_hexagon_V6_vaddububb_sat : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddububb_sat">; @@ -5907,10 +5928,10 @@ def int_hexagon_V6_ldtp0_128B : Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldtp0_128B">; def int_hexagon_V6_vlutvvb_oracci : -Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci">; +Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci", [ImmArg<3>]>; def int_hexagon_V6_vlutvvb_oracci_128B : -Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci_128B">; +Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci_128B", [ImmArg<3>]>; def int_hexagon_V6_vsubuwsat_dv : Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuwsat_dv">; @@ -6045,10 +6066,10 @@ def int_hexagon_V6_vasrwuhrndsat_128B : Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwuhrndsat_128B">; def int_hexagon_V6_vlutvvbi : -Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi">; +Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi", [ImmArg<2>]>; def int_hexagon_V6_vlutvvbi_128B : -Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi_128B">; +Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi_128B", [ImmArg<2>]>; def int_hexagon_V6_vsubuwsat : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuwsat">; @@ -6141,10 +6162,10 @@ def int_hexagon_V6_ldcnp0_128B : Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldcnp0_128B">; def int_hexagon_V6_vlutvwh_oracci : -Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci">; +Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci", [ImmArg<3>]>; def int_hexagon_V6_vlutvwh_oracci_128B : -Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci_128B">; +Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci_128B", [ImmArg<3>]>; def int_hexagon_V6_vsubbsat : Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubbsat">; diff --git a/include/llvm/IR/IntrinsicsMips.td b/include/llvm/IR/IntrinsicsMips.td index 421a79be4ebc..6393a9ca35d5 100644 --- a/include/llvm/IR/IntrinsicsMips.td +++ b/include/llvm/IR/IntrinsicsMips.td @@ -1,9 +1,8 @@ //===- IntrinsicsMips.td - Defines Mips intrinsics ---------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -235,9 +234,9 @@ def int_mips_extpdp: GCCBuiltin<"__builtin_mips_extpdp">, // Misc def int_mips_wrdsp: GCCBuiltin<"__builtin_mips_wrdsp">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<1>]>; def int_mips_rddsp: GCCBuiltin<"__builtin_mips_rddsp">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem, ImmArg<0>]>; def int_mips_insv: GCCBuiltin<"__builtin_mips_insv">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>; @@ -303,10 +302,10 @@ def int_mips_adduh_r_qb: GCCBuiltin<"__builtin_mips_adduh_r_qb">, def int_mips_append: GCCBuiltin<"__builtin_mips_append">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">, Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; @@ -356,14 +355,14 @@ def int_mips_precr_qb_ph: GCCBuiltin<"__builtin_mips_precr_qb_ph">, Intrinsic<[llvm_v4i8_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>; def int_mips_precr_sra_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_ph_w">, Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_precr_sra_r_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_r_ph_w">, Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_prepend: GCCBuiltin<"__builtin_mips_prepend">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_shra_qb: GCCBuiltin<"__builtin_mips_shra_qb">, Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>; @@ -464,22 +463,22 @@ def int_mips_addv_d : GCCBuiltin<"__builtin_msa_addv_d">, def int_mips_addvi_b : GCCBuiltin<"__builtin_msa_addvi_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], - [Commutative, IntrNoMem]>; + [Commutative, IntrNoMem, ImmArg<1>]>; def int_mips_addvi_h : GCCBuiltin<"__builtin_msa_addvi_h">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], - [Commutative, IntrNoMem]>; + [Commutative, IntrNoMem, ImmArg<1>]>; def int_mips_addvi_w : GCCBuiltin<"__builtin_msa_addvi_w">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], - [Commutative, IntrNoMem]>; + [Commutative, IntrNoMem, ImmArg<1>]>; def int_mips_addvi_d : GCCBuiltin<"__builtin_msa_addvi_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], - [Commutative, IntrNoMem]>; + [Commutative, IntrNoMem, ImmArg<1>]>; def int_mips_and_v : GCCBuiltin<"__builtin_msa_and_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_andi_b : GCCBuiltin<"__builtin_msa_andi_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_asub_s_b : GCCBuiltin<"__builtin_msa_asub_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -561,13 +560,13 @@ def int_mips_bclr_d : GCCBuiltin<"__builtin_msa_bclr_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_bclri_b : GCCBuiltin<"__builtin_msa_bclri_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bclri_h : GCCBuiltin<"__builtin_msa_bclri_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bclri_w : GCCBuiltin<"__builtin_msa_bclri_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bclri_d : GCCBuiltin<"__builtin_msa_bclri_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_binsl_b : GCCBuiltin<"__builtin_msa_binsl_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], @@ -584,16 +583,16 @@ def int_mips_binsl_d : GCCBuiltin<"__builtin_msa_binsl_d">, def int_mips_binsli_b : GCCBuiltin<"__builtin_msa_binsli_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsli_h : GCCBuiltin<"__builtin_msa_binsli_h">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsli_w : GCCBuiltin<"__builtin_msa_binsli_w">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsli_d : GCCBuiltin<"__builtin_msa_binsli_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsr_b : GCCBuiltin<"__builtin_msa_binsr_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], @@ -610,16 +609,16 @@ def int_mips_binsr_d : GCCBuiltin<"__builtin_msa_binsr_d">, def int_mips_binsri_b : GCCBuiltin<"__builtin_msa_binsri_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsri_h : GCCBuiltin<"__builtin_msa_binsri_h">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsri_w : GCCBuiltin<"__builtin_msa_binsri_w">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_binsri_d : GCCBuiltin<"__builtin_msa_binsri_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_bmnz_v : GCCBuiltin<"__builtin_msa_bmnz_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], @@ -627,7 +626,7 @@ def int_mips_bmnz_v : GCCBuiltin<"__builtin_msa_bmnz_v">, def int_mips_bmnzi_b : GCCBuiltin<"__builtin_msa_bmnzi_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_bmz_v : GCCBuiltin<"__builtin_msa_bmz_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], @@ -635,7 +634,7 @@ def int_mips_bmz_v : GCCBuiltin<"__builtin_msa_bmz_v">, def int_mips_bmzi_b : GCCBuiltin<"__builtin_msa_bmzi_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_bneg_b : GCCBuiltin<"__builtin_msa_bneg_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -647,13 +646,13 @@ def int_mips_bneg_d : GCCBuiltin<"__builtin_msa_bneg_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_bnegi_b : GCCBuiltin<"__builtin_msa_bnegi_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bnegi_h : GCCBuiltin<"__builtin_msa_bnegi_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bnegi_w : GCCBuiltin<"__builtin_msa_bnegi_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bnegi_d : GCCBuiltin<"__builtin_msa_bnegi_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bnz_b : GCCBuiltin<"__builtin_msa_bnz_b">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; @@ -673,7 +672,7 @@ def int_mips_bsel_v : GCCBuiltin<"__builtin_msa_bsel_v">, def int_mips_bseli_b : GCCBuiltin<"__builtin_msa_bseli_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_bset_b : GCCBuiltin<"__builtin_msa_bset_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -685,13 +684,13 @@ def int_mips_bset_d : GCCBuiltin<"__builtin_msa_bset_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_bseti_b : GCCBuiltin<"__builtin_msa_bseti_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bseti_h : GCCBuiltin<"__builtin_msa_bseti_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bseti_w : GCCBuiltin<"__builtin_msa_bseti_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bseti_d : GCCBuiltin<"__builtin_msa_bseti_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_bz_b : GCCBuiltin<"__builtin_msa_bz_b">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; @@ -715,16 +714,16 @@ def int_mips_ceq_d : GCCBuiltin<"__builtin_msa_ceq_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_ceqi_b : GCCBuiltin<"__builtin_msa_ceqi_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_ceqi_h : GCCBuiltin<"__builtin_msa_ceqi_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_ceqi_w : GCCBuiltin<"__builtin_msa_ceqi_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_ceqi_d : GCCBuiltin<"__builtin_msa_ceqi_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_cfcmsa : GCCBuiltin<"__builtin_msa_cfcmsa">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<0>]>; def int_mips_cle_s_b : GCCBuiltin<"__builtin_msa_cle_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -745,22 +744,22 @@ def int_mips_cle_u_d : GCCBuiltin<"__builtin_msa_cle_u_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_clei_s_b : GCCBuiltin<"__builtin_msa_clei_s_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_s_h : GCCBuiltin<"__builtin_msa_clei_s_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_s_w : GCCBuiltin<"__builtin_msa_clei_s_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_s_d : GCCBuiltin<"__builtin_msa_clei_s_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_u_b : GCCBuiltin<"__builtin_msa_clei_u_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_u_h : GCCBuiltin<"__builtin_msa_clei_u_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_u_w : GCCBuiltin<"__builtin_msa_clei_u_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clei_u_d : GCCBuiltin<"__builtin_msa_clei_u_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clt_s_b : GCCBuiltin<"__builtin_msa_clt_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -781,22 +780,22 @@ def int_mips_clt_u_d : GCCBuiltin<"__builtin_msa_clt_u_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_clti_s_b : GCCBuiltin<"__builtin_msa_clti_s_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_s_h : GCCBuiltin<"__builtin_msa_clti_s_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_s_w : GCCBuiltin<"__builtin_msa_clti_s_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_s_d : GCCBuiltin<"__builtin_msa_clti_s_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_u_b : GCCBuiltin<"__builtin_msa_clti_u_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_u_h : GCCBuiltin<"__builtin_msa_clti_u_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_u_w : GCCBuiltin<"__builtin_msa_clti_u_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_clti_u_d : GCCBuiltin<"__builtin_msa_clti_u_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_copy_s_b : GCCBuiltin<"__builtin_msa_copy_s_b">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; @@ -817,7 +816,7 @@ def int_mips_copy_u_d : GCCBuiltin<"__builtin_msa_copy_u_d">, Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; def int_mips_ctcmsa : GCCBuiltin<"__builtin_msa_ctcmsa">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<0>]>; def int_mips_div_s_b : GCCBuiltin<"__builtin_msa_div_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1245,41 +1244,41 @@ def int_mips_insert_d : GCCBuiltin<"__builtin_msa_insert_d">, def int_mips_insve_b : GCCBuiltin<"__builtin_msa_insve_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_mips_insve_h : GCCBuiltin<"__builtin_msa_insve_h">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_mips_insve_w : GCCBuiltin<"__builtin_msa_insve_w">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_mips_insve_d : GCCBuiltin<"__builtin_msa_insve_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty, llvm_v2i64_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_mips_ld_b : GCCBuiltin<"__builtin_msa_ld_b">, Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_mips_ld_h : GCCBuiltin<"__builtin_msa_ld_h">, Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_mips_ld_w : GCCBuiltin<"__builtin_msa_ld_w">, Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_mips_ld_d : GCCBuiltin<"__builtin_msa_ld_d">, Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_mips_ldi_b : GCCBuiltin<"__builtin_msa_ldi_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; def int_mips_ldi_h : GCCBuiltin<"__builtin_msa_ldi_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; def int_mips_ldi_w : GCCBuiltin<"__builtin_msa_ldi_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; def int_mips_ldi_d : GCCBuiltin<"__builtin_msa_ldi_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; // This instruction is part of the MSA spec but it does not share the // __builtin_msa prefix because it operates on the GPR registers. @@ -1342,22 +1341,22 @@ def int_mips_max_u_d : GCCBuiltin<"__builtin_msa_max_u_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_maxi_s_b : GCCBuiltin<"__builtin_msa_maxi_s_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_s_h : GCCBuiltin<"__builtin_msa_maxi_s_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_s_w : GCCBuiltin<"__builtin_msa_maxi_s_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_s_d : GCCBuiltin<"__builtin_msa_maxi_s_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_u_b : GCCBuiltin<"__builtin_msa_maxi_u_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_u_h : GCCBuiltin<"__builtin_msa_maxi_u_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_u_w : GCCBuiltin<"__builtin_msa_maxi_u_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_maxi_u_d : GCCBuiltin<"__builtin_msa_maxi_u_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_min_a_b : GCCBuiltin<"__builtin_msa_min_a_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1387,22 +1386,22 @@ def int_mips_min_u_d : GCCBuiltin<"__builtin_msa_min_u_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_mini_s_b : GCCBuiltin<"__builtin_msa_mini_s_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_s_h : GCCBuiltin<"__builtin_msa_mini_s_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_s_w : GCCBuiltin<"__builtin_msa_mini_s_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_s_d : GCCBuiltin<"__builtin_msa_mini_s_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_u_b : GCCBuiltin<"__builtin_msa_mini_u_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_u_h : GCCBuiltin<"__builtin_msa_mini_u_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_u_w : GCCBuiltin<"__builtin_msa_mini_u_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mini_u_d : GCCBuiltin<"__builtin_msa_mini_u_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_mod_s_b : GCCBuiltin<"__builtin_msa_mod_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1493,13 +1492,13 @@ def int_mips_nor_v : GCCBuiltin<"__builtin_msa_nor_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_nori_b : GCCBuiltin<"__builtin_msa_nori_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_or_v : GCCBuiltin<"__builtin_msa_or_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_ori_b : GCCBuiltin<"__builtin_msa_ori_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_pckev_b : GCCBuiltin<"__builtin_msa_pckev_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1529,29 +1528,29 @@ def int_mips_pcnt_d : GCCBuiltin<"__builtin_msa_pcnt_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; def int_mips_sat_s_b : GCCBuiltin<"__builtin_msa_sat_s_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_s_h : GCCBuiltin<"__builtin_msa_sat_s_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_s_w : GCCBuiltin<"__builtin_msa_sat_s_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_s_d : GCCBuiltin<"__builtin_msa_sat_s_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_u_b : GCCBuiltin<"__builtin_msa_sat_u_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_u_h : GCCBuiltin<"__builtin_msa_sat_u_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_u_w : GCCBuiltin<"__builtin_msa_sat_u_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sat_u_d : GCCBuiltin<"__builtin_msa_sat_u_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_shf_b : GCCBuiltin<"__builtin_msa_shf_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_shf_h : GCCBuiltin<"__builtin_msa_shf_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_shf_w : GCCBuiltin<"__builtin_msa_shf_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sld_b : GCCBuiltin<"__builtin_msa_sld_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; @@ -1564,16 +1563,16 @@ def int_mips_sld_d : GCCBuiltin<"__builtin_msa_sld_d">, def int_mips_sldi_b : GCCBuiltin<"__builtin_msa_sldi_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_sldi_h : GCCBuiltin<"__builtin_msa_sldi_h">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_sldi_w : GCCBuiltin<"__builtin_msa_sldi_w">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_sldi_d : GCCBuiltin<"__builtin_msa_sldi_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_mips_sll_b : GCCBuiltin<"__builtin_msa_sll_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1585,13 +1584,13 @@ def int_mips_sll_d : GCCBuiltin<"__builtin_msa_sll_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_slli_b : GCCBuiltin<"__builtin_msa_slli_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_slli_h : GCCBuiltin<"__builtin_msa_slli_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_slli_w : GCCBuiltin<"__builtin_msa_slli_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_slli_d : GCCBuiltin<"__builtin_msa_slli_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_splat_b : GCCBuiltin<"__builtin_msa_splat_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; @@ -1603,13 +1602,13 @@ def int_mips_splat_d : GCCBuiltin<"__builtin_msa_splat_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; def int_mips_splati_b : GCCBuiltin<"__builtin_msa_splati_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_splati_h : GCCBuiltin<"__builtin_msa_splati_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_splati_w : GCCBuiltin<"__builtin_msa_splati_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_splati_d : GCCBuiltin<"__builtin_msa_splati_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_sra_b : GCCBuiltin<"__builtin_msa_sra_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1621,13 +1620,13 @@ def int_mips_sra_d : GCCBuiltin<"__builtin_msa_sra_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_srai_b : GCCBuiltin<"__builtin_msa_srai_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srai_h : GCCBuiltin<"__builtin_msa_srai_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srai_w : GCCBuiltin<"__builtin_msa_srai_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srai_d : GCCBuiltin<"__builtin_msa_srai_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srar_b : GCCBuiltin<"__builtin_msa_srar_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1639,13 +1638,13 @@ def int_mips_srar_d : GCCBuiltin<"__builtin_msa_srar_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_srari_b : GCCBuiltin<"__builtin_msa_srari_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srari_h : GCCBuiltin<"__builtin_msa_srari_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srari_w : GCCBuiltin<"__builtin_msa_srari_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srari_d : GCCBuiltin<"__builtin_msa_srari_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srl_b : GCCBuiltin<"__builtin_msa_srl_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1657,13 +1656,13 @@ def int_mips_srl_d : GCCBuiltin<"__builtin_msa_srl_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_srli_b : GCCBuiltin<"__builtin_msa_srli_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srli_h : GCCBuiltin<"__builtin_msa_srli_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srli_w : GCCBuiltin<"__builtin_msa_srli_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srli_d : GCCBuiltin<"__builtin_msa_srli_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srlr_b : GCCBuiltin<"__builtin_msa_srlr_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1675,26 +1674,26 @@ def int_mips_srlr_d : GCCBuiltin<"__builtin_msa_srlr_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_srlri_b : GCCBuiltin<"__builtin_msa_srlri_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srlri_h : GCCBuiltin<"__builtin_msa_srlri_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srlri_w : GCCBuiltin<"__builtin_msa_srlri_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_srlri_d : GCCBuiltin<"__builtin_msa_srlri_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_st_b : GCCBuiltin<"__builtin_msa_st_b">, Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [IntrArgMemOnly, ImmArg<2>]>; def int_mips_st_h : GCCBuiltin<"__builtin_msa_st_h">, Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [IntrArgMemOnly, ImmArg<2>]>; def int_mips_st_w : GCCBuiltin<"__builtin_msa_st_w">, Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [IntrArgMemOnly, ImmArg<2>]>; def int_mips_st_d : GCCBuiltin<"__builtin_msa_st_d">, Intrinsic<[], [llvm_v2i64_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [IntrArgMemOnly, ImmArg<2>]>; def int_mips_subs_s_b : GCCBuiltin<"__builtin_msa_subs_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -1742,13 +1741,13 @@ def int_mips_subv_d : GCCBuiltin<"__builtin_msa_subv_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_mips_subvi_b : GCCBuiltin<"__builtin_msa_subvi_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_subvi_h : GCCBuiltin<"__builtin_msa_subvi_h">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_subvi_w : GCCBuiltin<"__builtin_msa_subvi_w">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_subvi_d : GCCBuiltin<"__builtin_msa_subvi_d">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_mips_vshf_b : GCCBuiltin<"__builtin_msa_vshf_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], @@ -1767,5 +1766,5 @@ def int_mips_xor_v : GCCBuiltin<"__builtin_msa_xor_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_xori_b : GCCBuiltin<"__builtin_msa_xori_b">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; } diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td index 7f694f68969e..dba7dd76c4ff 100644 --- a/include/llvm/IR/IntrinsicsNVVM.td +++ b/include/llvm/IR/IntrinsicsNVVM.td @@ -1,9 +1,8 @@ //===- IntrinsicsNVVM.td - Defines NVVM intrinsics ---------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -38,6 +37,245 @@ def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64* // MISC // +// Helper class for construction of n-element list<LLVMtype> [t,t,...,t] +class RepLLVMType<int N, LLVMType T> { + list<LLVMType> ret = !if(N, !listconcat(RepLLVMType<!add(N,-1), T>.ret, [T]), []); +} + +// Helper class that represents a 'fragment' of an NVPTX *MMA instruction. +// Geom: m<M>n<N>k<K>. E.g. m8n32k16 +// Frag: [abcd] +// PtxEltType: PTX type for the element. +class WMMA_REGS<string Geom, string Frag, string PtxEltType> { + string geom = Geom; + string frag = Frag; + string ptx_elt_type = PtxEltType; + string gft = Geom#":"#Frag#":"#ptx_elt_type; + string ft = frag#":"#ptx_elt_type; + list<LLVMType> regs = !cond( + // fp16 -> fp16/fp32 @ m16n16k16/m8n32k16/m32n8k16 + // All currently supported geometries use the same fragment format, + // so we only need to consider {fragment, type}. + !eq(ft,"a:f16") : RepLLVMType<8, llvm_v2f16_ty>.ret, + !eq(ft,"b:f16") : RepLLVMType<8, llvm_v2f16_ty>.ret, + !eq(ft,"c:f16") : RepLLVMType<4, llvm_v2f16_ty>.ret, + !eq(ft,"d:f16") : RepLLVMType<4, llvm_v2f16_ty>.ret, + !eq(ft,"c:f32") : RepLLVMType<8, llvm_float_ty>.ret, + !eq(ft,"d:f32") : RepLLVMType<8, llvm_float_ty>.ret, + + // u8/s8 -> s32 @ m16n16k16/m8n32k16/m32n8k16 + !eq(gft,"m16n16k16:a:u8") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m16n16k16:a:s8") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m16n16k16:b:u8") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m16n16k16:b:s8") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m16n16k16:c:s32") : RepLLVMType<8, llvm_i32_ty>.ret, + !eq(gft,"m16n16k16:d:s32") : RepLLVMType<8, llvm_i32_ty>.ret, + + !eq(gft,"m8n32k16:a:u8") : [llvm_i32_ty], + !eq(gft,"m8n32k16:a:s8") : [llvm_i32_ty], + !eq(gft,"m8n32k16:b:u8") : RepLLVMType<4, llvm_i32_ty>.ret, + !eq(gft,"m8n32k16:b:s8") : RepLLVMType<4, llvm_i32_ty>.ret, + !eq(gft,"m8n32k16:c:s32") : RepLLVMType<8, llvm_i32_ty>.ret, + !eq(gft,"m8n32k16:d:s32") : RepLLVMType<8, llvm_i32_ty>.ret, + + !eq(gft,"m32n8k16:a:u8") : RepLLVMType<4, llvm_i32_ty>.ret, + !eq(gft,"m32n8k16:a:s8") : RepLLVMType<4, llvm_i32_ty>.ret, + !eq(gft,"m32n8k16:b:u8") : [llvm_i32_ty], + !eq(gft,"m32n8k16:b:s8") : [llvm_i32_ty], + !eq(gft,"m32n8k16:c:s32") : RepLLVMType<8, llvm_i32_ty>.ret, + !eq(gft,"m32n8k16:d:s32") : RepLLVMType<8, llvm_i32_ty>.ret, + + // u4/s4/b1 -> s32 @ m8n8k32 (u4/s4), m8n8k128(b1) + !eq(gft,"m8n8k128:a:b1") : [llvm_i32_ty], + !eq(gft,"m8n8k32:a:u4") : [llvm_i32_ty], + !eq(gft,"m8n8k32:a:s4") : [llvm_i32_ty], + !eq(gft,"m8n8k128:b:b1") : [llvm_i32_ty], + !eq(gft,"m8n8k32:b:u4") : [llvm_i32_ty], + !eq(gft,"m8n8k32:b:s4") : [llvm_i32_ty], + !eq(gft,"m8n8k128:c:s32") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m8n8k128:d:s32") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m8n8k32:c:s32") : RepLLVMType<2, llvm_i32_ty>.ret, + !eq(gft,"m8n8k32:d:s32") : RepLLVMType<2, llvm_i32_ty>.ret, + ); +} + +class WMMA_NAME_LDST<string Op, WMMA_REGS Frag, string Layout, int WithStride> { + string intr = "llvm.nvvm.wmma." + # Frag.geom + # "." # Op + # "." # Frag.frag + # "." # Layout + # !if(WithStride, ".stride", "") + # "." # Frag.ptx_elt_type + ; + // TODO(tra): record name should ideally use the same field order as the intrinsic. + // E.g. string record = !subst("llvm", "int", + // !subst(".", "_", llvm)); + string record = "int_nvvm_wmma_" + # Frag.geom + # "_" # Op + # "_" # Frag.frag + # "_" # Frag.ptx_elt_type + # "_" # Layout + # !if(WithStride, "_stride", ""); +} + +class MMA_SIGNATURE<WMMA_REGS A, WMMA_REGS B, WMMA_REGS C, WMMA_REGS D> { + list<WMMA_REGS> id_frags = !cond( + // int and sub-int ops are identified by input type. + !eq(A.ptx_elt_type, "s8") : [A], + !eq(A.ptx_elt_type, "u8") : [A], + !eq(A.ptx_elt_type, "s4") : [A], + !eq(A.ptx_elt_type, "u4") : [A], + !eq(A.ptx_elt_type, "b1") : [A], + // the rest are FP ops identified by accumulator & result type. + 1: [D, C] + ); + string ret = !foldl("", id_frags, a, b, !strconcat(a, ".", b.ptx_elt_type)); +} + +class WMMA_NAME_MMA<string ALayout, string BLayout, int Satfinite, + WMMA_REGS A, WMMA_REGS B, WMMA_REGS C, WMMA_REGS D> { + string signature = MMA_SIGNATURE<A, B, C, D>.ret; + string llvm = "llvm.nvvm.wmma." + # A.geom + # ".mma" + # "." # ALayout + # "." # BLayout + # signature + # !if(Satfinite, ".satfinite", ""); + + string record = !subst(".", "_", + !subst("llvm.", "int_", llvm)); +} + +// Generates list of 4-tuples of WMMA_REGS representing a valid MMA op. +// Geom: list of supported geometries. +// TypeN: PTX type of the corresponding fragment's element. +// TypeB and TypeD may be empty if it must match that of TypeA or TypeC. +class MMA_OPS<list<string> Geom, list<string> TypeA, list<string> TypeB, + list<string> TypeC, list<string> TypeD> { + list<list<WMMA_REGS>> ret = + !foldl([]<list<WMMA_REGS>>, Geom, t1, geom, !listconcat(t1, + !foldl([]<list<WMMA_REGS>>, TypeA, t2, type_a, !listconcat(t2, + !foldl([]<list<WMMA_REGS>>, !if(!size(TypeB), TypeB, [type_a]), t3, type_b, !listconcat(t3, + !foldl([]<list<WMMA_REGS>>, TypeC, t4, type_c, !listconcat(t4, + !foldl([]<list<WMMA_REGS>>, !if(!size(TypeC), TypeC, [type_c]), t5, type_d, !listconcat(t5, + [[WMMA_REGS<geom, "a", type_a>, + WMMA_REGS<geom, "b", type_b>, + WMMA_REGS<geom, "c", type_c>, + WMMA_REGS<geom, "d", type_d>]])))))))))); + // Debugging aid for readable representation of the list above. + list<list<string>> ops = !foreach(x, ret, [x[0].gft, x[1].gft, x[2].gft, x[3].gft]); +} + +class MMA_LDST_OPS<list<string> Geom, list<string> Frags, list<string> Types> { + list<WMMA_REGS> ret = + !foldl([]<WMMA_REGS>, Geom, t1, geom, !listconcat(t1, + !foldl([]<WMMA_REGS>, Frags, t2, frag, !listconcat(t2, + !foldl([]<WMMA_REGS>, Types, t3, type, !listconcat(t3, + [WMMA_REGS<geom, frag, type>])))))); + // Debugging aid for readable representation of the list above. + list<string> ops = !foreach(x, ret, x.gft); +} + + + +// Creates list of valid combinations of fragments. This is the master list that +// drives generation of corresponding intrinsics and instructions. +class NVVM_MMA_OPS<int _ = 0> { + list<list<WMMA_REGS>> fp_mma_ops = MMA_OPS< + ["m16n16k16", "m32n8k16", "m8n32k16"], + ["f16"], [], ["f16", "f32"], ["f16", "f32"]>.ret; + list<list<WMMA_REGS>> int_mma_ops = MMA_OPS< + ["m16n16k16", "m32n8k16", "m8n32k16"], + ["s8", "u8"], [], ["s32"], []>.ret; + list<list<WMMA_REGS>> subint_mma_ops = MMA_OPS< + ["m8n8k32"], + ["s4", "u4"], [], ["s32"], []>.ret; + list<list<WMMA_REGS>> bit_mma_ops = MMA_OPS< + ["m8n8k128"], + ["b1"], [], ["s32"], []>.ret; + list<list<WMMA_REGS>> all_mma_ops = !listconcat(fp_mma_ops, int_mma_ops, + subint_mma_ops, bit_mma_ops); + + list<WMMA_REGS> ldst_ab_ops = MMA_LDST_OPS< + ["m16n16k16", "m32n8k16", "m8n32k16"], + ["a", "b"], ["f16", "u8", "s8"]>.ret; + list<WMMA_REGS> ldst_cd_ops = MMA_LDST_OPS< + ["m16n16k16", "m32n8k16", "m8n32k16"], + ["c", "d"], ["f16", "f32", "s32"]>.ret; + list<WMMA_REGS> ldst_subint_ab_ops = MMA_LDST_OPS< + ["m8n8k32"], ["a", "b"], ["s4","u4"]>.ret; + list<WMMA_REGS> ldst_bit_ab_ops = MMA_LDST_OPS< + ["m8n8k128"], ["a", "b"], ["b1"]>.ret; + list<WMMA_REGS> ldst_subint_cd_ops = MMA_LDST_OPS< + ["m8n8k32", "m8n8k128"], ["c", "d"], ["s32"]>.ret; + list<WMMA_REGS> all_ldst_ops = !listconcat(ldst_ab_ops, ldst_cd_ops, + ldst_subint_ab_ops, + ldst_bit_ab_ops, + ldst_subint_cd_ops); + // Separate A/B/C fragments (loads) from D (stores). + list<WMMA_REGS> all_ld_ops = !foldl([]<WMMA_REGS>, all_ldst_ops, a, b, + !listconcat(a, !if(!eq(b.frag,"d"), [],[b]))); + list<WMMA_REGS> all_st_ops = !foldl([]<WMMA_REGS>, all_ldst_ops, a, b, + !listconcat(a, !if(!eq(b.frag,"d"), [b],[]))); +} + +def NVVM_MMA_OPS : NVVM_MMA_OPS; + +// Returns [1] if this combination of layout/satf is supported, [] otherwise. +// MMA ops must provide all parameters. Loads and stores -- only frags and layout_a. +// The class is used to prevent generation of records for the unsupported variants. +// E.g. +// foreach _ = NVVM_MMA_SUPPORTED<...>.ret in = +// def : FOO<>; // The record will only be defined for supported ops. +// +class NVVM_MMA_SUPPORTED<list<WMMA_REGS> frags, string layout_a, string layout_b="-", int satf=-1> { + // MMA ops check both layouts. + string mma = frags[0].ptx_elt_type + # ":" # layout_a + # ":" # layout_b; + // Load ops only need type/fragment/layout. + string ld = frags[0].ptx_elt_type + # ":" # frags[0].frag + # ":" # layout_a + ; + string ldf = frags[0].ptx_elt_type + # ":" # frags[0].frag + ; + string t = frags[0].ptx_elt_type; + list<int> ret = !cond( + // Sub-int MMA only supports fixed A/B layout. + // b1 does not support .satf. + !eq(mma#":"#satf, "b1:row:col:0") : [1], + !eq(mma, "s4:row:col") : [1], + !eq(mma, "u4:row:col") : [1], + !eq(mma, "s4:row:col") : [1], + !eq(mma, "u4:row:col") : [1], + // Sub-int load/stores have fixed layout for A and B. + !and(!eq(layout_b, "-"), // It's a Load or Store op + !or(!eq(ld, "b1:a:row"), + !eq(ld, "b1:b:col"), + !eq(ldf, "b1:c"), + !eq(ldf, "b1:d"), + !eq(ld, "s4:a:row"), + !eq(ld, "s4:b:col"), + !eq(ldf, "s4:c"), + !eq(ldf, "s4:d"), + !eq(ld, "u4:a:row"), + !eq(ld, "u4:b:col"), + !eq(ldf, "u4:c"), + !eq(ldf, "u4:d"))) : [1], + // All other sub-int ops are not supported. + !eq(t, "b1") : [], + !eq(t, "s4") : [], + !eq(t, "u4") : [], + // All other (non sub-int) are OK. + 1: [1] + ); +} + let TargetPrefix = "nvvm" in { def int_nvvm_prmt : GCCBuiltin<"__nvvm_prmt">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], @@ -689,14 +927,6 @@ let TargetPrefix = "nvvm" in { [IntrNoMem]>; // Atomics not available as llvm intrinsics. - def int_nvvm_atomic_load_add_f32 : Intrinsic<[llvm_float_ty], - [LLVMAnyPointerType<llvm_float_ty>, llvm_float_ty], - [IntrArgMemOnly, NoCapture<0>]>; - // Atomic add of f64 requires sm_60. - def int_nvvm_atomic_load_add_f64 : Intrinsic<[llvm_double_ty], - [LLVMAnyPointerType<llvm_double_ty>, llvm_double_ty], - [IntrArgMemOnly, NoCapture<0>]>; - def int_nvvm_atomic_load_inc_32 : Intrinsic<[llvm_i32_ty], [LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty], [IntrArgMemOnly, NoCapture<0>]>; @@ -3674,11 +3904,19 @@ multiclass PTXReadSRegIntrinsic_v4i32<string regname> { class PTXReadSRegIntrinsic_r32<string name> : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, GCCBuiltin<"__nvvm_read_ptx_sreg_" # name>; - class PTXReadSRegIntrinsic_r64<string name> : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>, GCCBuiltin<"__nvvm_read_ptx_sreg_" # name>; +// Intrinsics to read registers with non-constant values. E.g. the values that +// do change over the kernel lifetime. Such reads should not be CSE'd. +class PTXReadNCSRegIntrinsic_r32<string name> + : Intrinsic<[llvm_i32_ty], [], [IntrInaccessibleMemOnly]>, + GCCBuiltin<"__nvvm_read_ptx_sreg_" # name>; +class PTXReadNCSRegIntrinsic_r64<string name> + : Intrinsic<[llvm_i64_ty], [], [IntrInaccessibleMemOnly]>, + GCCBuiltin<"__nvvm_read_ptx_sreg_" # name>; + defm int_nvvm_read_ptx_sreg_tid : PTXReadSRegIntrinsic_v4i32<"tid">; defm int_nvvm_read_ptx_sreg_ntid : PTXReadSRegIntrinsic_v4i32<"ntid">; @@ -3704,13 +3942,13 @@ def int_nvvm_read_ptx_sreg_lanemask_ge : def int_nvvm_read_ptx_sreg_lanemask_gt : PTXReadSRegIntrinsic_r32<"lanemask_gt">; -def int_nvvm_read_ptx_sreg_clock : PTXReadSRegIntrinsic_r32<"clock">; -def int_nvvm_read_ptx_sreg_clock64 : PTXReadSRegIntrinsic_r64<"clock64">; +def int_nvvm_read_ptx_sreg_clock : PTXReadNCSRegIntrinsic_r32<"clock">; +def int_nvvm_read_ptx_sreg_clock64 : PTXReadNCSRegIntrinsic_r64<"clock64">; -def int_nvvm_read_ptx_sreg_pm0 : PTXReadSRegIntrinsic_r32<"pm0">; -def int_nvvm_read_ptx_sreg_pm1 : PTXReadSRegIntrinsic_r32<"pm1">; -def int_nvvm_read_ptx_sreg_pm2 : PTXReadSRegIntrinsic_r32<"pm2">; -def int_nvvm_read_ptx_sreg_pm3 : PTXReadSRegIntrinsic_r32<"pm3">; +def int_nvvm_read_ptx_sreg_pm0 : PTXReadNCSRegIntrinsic_r32<"pm0">; +def int_nvvm_read_ptx_sreg_pm1 : PTXReadNCSRegIntrinsic_r32<"pm1">; +def int_nvvm_read_ptx_sreg_pm2 : PTXReadNCSRegIntrinsic_r32<"pm2">; +def int_nvvm_read_ptx_sreg_pm3 : PTXReadNCSRegIntrinsic_r32<"pm3">; def int_nvvm_read_ptx_sreg_warpsize : PTXReadSRegIntrinsic_r32<"warpsize">; @@ -3882,166 +4120,59 @@ def int_nvvm_match_all_sync_i64p : // // WMMA instructions // - // WMMA.LOAD -class NVVM_WMMA_LD_GALSTS<string Geometry, string Abc, string Layout, - string Type, LLVMType regty, int WithStride> - : Intrinsic<!if(!eq(Abc#Type,"cf16"), - [regty, regty, regty, regty], - [regty, regty, regty, regty, - regty, regty, regty, regty]), +class NVVM_WMMA_LD<WMMA_REGS Frag, string Layout, int WithStride> + : Intrinsic<Frag.regs, !if(WithStride, [llvm_anyptr_ty, llvm_i32_ty], [llvm_anyptr_ty]), [IntrReadMem, IntrArgMemOnly, ReadOnly<0>, NoCapture<0>], - "llvm.nvvm.wmma." - # Geometry - # ".load" - # "." # Abc - # "." # Layout - # !if(WithStride, ".stride", "") - # "." # Type>; - -multiclass NVVM_WMMA_LD_GALT<string Geometry, string Abc, string Layout, - string Type, LLVMType regty> { - def _stride: NVVM_WMMA_LD_GALSTS<Geometry, Abc, Layout, Type, regty, 1>; - def NAME : NVVM_WMMA_LD_GALSTS<Geometry, Abc, Layout, Type, regty, 0>; -} - -multiclass NVVM_WMMA_LD_GAT<string Geometry, string Abc, - string Type, LLVMType regty> { - defm _row: NVVM_WMMA_LD_GALT<Geometry, Abc, "row", Type, regty>; - defm _col: NVVM_WMMA_LD_GALT<Geometry, Abc, "col", Type, regty>; -} - -multiclass NVVM_WMMA_LD_G<string Geometry> { - defm _a_f16: NVVM_WMMA_LD_GAT<Geometry, "a", "f16", llvm_v2f16_ty>; - defm _b_f16: NVVM_WMMA_LD_GAT<Geometry, "b", "f16", llvm_v2f16_ty>; - defm _c_f16: NVVM_WMMA_LD_GAT<Geometry, "c", "f16", llvm_v2f16_ty>; - defm _c_f32: NVVM_WMMA_LD_GAT<Geometry, "c", "f32", llvm_float_ty>; -} - -multiclass NVVM_WMMA_LD { - defm _m32n8k16_load: NVVM_WMMA_LD_G<"m32n8k16">; - defm _m16n16k16_load: NVVM_WMMA_LD_G<"m16n16k16">; - defm _m8n32k16_load: NVVM_WMMA_LD_G<"m8n32k16">; -} - -defm int_nvvm_wmma: NVVM_WMMA_LD; + WMMA_NAME_LDST<"load", Frag, Layout, WithStride>.intr>; // WMMA.STORE.D -class NVVM_WMMA_STD_GLSTS<string Geometry, string Layout, - string Type, LLVMType regty, int WithStride, - // This is only used to create a typed empty array we - // need to pass to !if below. - list<LLVMType>Empty=[]> +class NVVM_WMMA_ST<WMMA_REGS Frag, string Layout, int WithStride> : Intrinsic<[], !listconcat( [llvm_anyptr_ty], - !if(!eq(Type,"f16"), - [regty, regty, regty, regty], - [regty, regty, regty, regty, - regty, regty, regty, regty]), - !if(WithStride, [llvm_i32_ty], Empty)), + Frag.regs, + !if(WithStride, [llvm_i32_ty], [])), [IntrWriteMem, IntrArgMemOnly, WriteOnly<0>, NoCapture<0>], - "llvm.nvvm.wmma." - # Geometry - # ".store.d" - # "." # Layout - # !if(WithStride, ".stride", "") - # "." # Type>; - -multiclass NVVM_WMMA_STD_GLT<string Geometry, string Layout, - string Type, LLVMType regty> { - def _stride: NVVM_WMMA_STD_GLSTS<Geometry, Layout, Type, regty, 1>; - def NAME: NVVM_WMMA_STD_GLSTS<Geometry, Layout, Type, regty, 0>; -} - -multiclass NVVM_WMMA_STD_GT<string Geometry, string Type, LLVMType regty> { - defm _row: NVVM_WMMA_STD_GLT<Geometry, "row", Type, regty>; - defm _col: NVVM_WMMA_STD_GLT<Geometry, "col", Type, regty>; -} -multiclass NVVM_WMMA_STD_G<string Geometry> { - defm _d_f16: NVVM_WMMA_STD_GT<Geometry, "f16", llvm_v2f16_ty>; - defm _d_f32: NVVM_WMMA_STD_GT<Geometry, "f32", llvm_float_ty>; -} - -multiclass NVVM_WMMA_STD { - defm _m32n8k16_store: NVVM_WMMA_STD_G<"m32n8k16">; - defm _m16n16k16_store: NVVM_WMMA_STD_G<"m16n16k16">; - defm _m8n32k16_store: NVVM_WMMA_STD_G<"m8n32k16">; + WMMA_NAME_LDST<"store", Frag, Layout, WithStride>.intr>; + +// Create all load/store variants +foreach layout = ["row", "col"] in { + foreach stride = [0, 1] in { + foreach frag = NVVM_MMA_OPS.all_ld_ops in + foreach _ = NVVM_MMA_SUPPORTED<[frag], layout>.ret in + def WMMA_NAME_LDST<"load", frag, layout, stride>.record + : NVVM_WMMA_LD<frag, layout, stride>; + foreach frag = NVVM_MMA_OPS.all_st_ops in + foreach _ = NVVM_MMA_SUPPORTED<[frag], layout>.ret in + def WMMA_NAME_LDST<"store", frag, layout, stride>.record + : NVVM_WMMA_ST<frag, layout, stride>; + } } -defm int_nvvm_wmma: NVVM_WMMA_STD; - // WMMA.MMA -class NVVM_WMMA_MMA_GABDCS<string Geometry, - string ALayout, string BLayout, - string DType, LLVMType d_regty, - string CType, LLVMType c_regty, - string Satfinite = ""> - : Intrinsic<!if(!eq(DType,"f16"), - [d_regty, d_regty, d_regty, d_regty], - [d_regty, d_regty, d_regty, d_regty, - d_regty, d_regty, d_regty, d_regty]), - !listconcat( - [// A - llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, - llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, - // B - llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, - llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty, llvm_v2f16_ty], - !if(!eq(CType,"f16"), - [c_regty, c_regty, c_regty, c_regty], - [c_regty, c_regty, c_regty, c_regty, - c_regty, c_regty, c_regty, c_regty])), +class NVVM_WMMA_MMA<string ALayout, string BLayout, int Satfinite, + WMMA_REGS A, WMMA_REGS B, + WMMA_REGS C, WMMA_REGS D> + : Intrinsic<D.regs, + !listconcat(A.regs, B.regs, C.regs), [IntrNoMem], - "llvm.nvvm.wmma." - # Geometry - # ".mma" - # "." # ALayout - # "." # BLayout - # "." # DType - # "." # CType - # Satfinite> { -} - -multiclass NVVM_WMMA_MMA_GABDC<string Geometry, string ALayout, string BLayout, - string DType, LLVMType d_regty, - string CType, LLVMType c_regty> { - def NAME : NVVM_WMMA_MMA_GABDCS<Geometry, ALayout, BLayout, - DType, d_regty, CType, c_regty>; - def _satfinite: NVVM_WMMA_MMA_GABDCS<Geometry, ALayout, BLayout, - DType, d_regty, CType, c_regty,".satfinite">; -} - -multiclass NVVM_WMMA_MMA_GABD<string Geometry, string ALayout, string BLayout, - string DType, LLVMType d_regty> { - defm _f16: NVVM_WMMA_MMA_GABDC<Geometry, ALayout, BLayout, DType, d_regty, - "f16", llvm_v2f16_ty>; - defm _f32: NVVM_WMMA_MMA_GABDC<Geometry, ALayout, BLayout, DType, d_regty, - "f32", llvm_float_ty>; -} - -multiclass NVVM_WMMA_MMA_GAB<string Geometry, string ALayout, string BLayout> { - defm _f16: NVVM_WMMA_MMA_GABD<Geometry, ALayout, BLayout, "f16", llvm_v2f16_ty>; - defm _f32: NVVM_WMMA_MMA_GABD<Geometry, ALayout, BLayout, "f32", llvm_float_ty>; -} - -multiclass NVVM_WMMA_MMA_GA<string Geometry, string ALayout> { - defm _col: NVVM_WMMA_MMA_GAB<Geometry, ALayout, "col">; - defm _row: NVVM_WMMA_MMA_GAB<Geometry, ALayout, "row">; -} - -multiclass NVVM_WMMA_MMA_G<string Geometry> { - defm _col: NVVM_WMMA_MMA_GA<Geometry, "col">; - defm _row: NVVM_WMMA_MMA_GA<Geometry, "row">; -} - -multiclass NVVM_WMMA_MMA { - defm _m32n8k16_mma : NVVM_WMMA_MMA_G<"m32n8k16">; - defm _m16n16k16_mma : NVVM_WMMA_MMA_G<"m16n16k16">; - defm _m8n32k16_mma : NVVM_WMMA_MMA_G<"m8n32k16">; -} - -defm int_nvvm_wmma : NVVM_WMMA_MMA; + WMMA_NAME_MMA<ALayout, BLayout, Satfinite, A, B, C, D>.llvm>; + +foreach layout_a = ["row", "col"] in { + foreach layout_b = ["row", "col"] in { + foreach satf = [0, 1] in { + foreach op = NVVM_MMA_OPS.all_mma_ops in { + foreach _ = NVVM_MMA_SUPPORTED<op, layout_a, layout_b, satf>.ret in { + def WMMA_NAME_MMA<layout_a, layout_b, satf, + op[0], op[1], op[2], op[3]>.record + : NVVM_WMMA_MMA<layout_a, layout_b, satf, + op[0], op[1], op[2], op[3]>; + } + } + } // satf + } // layout_b +} // layout_a } // let TargetPrefix = "nvvm" diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index 62b2e8f77e7d..f87317445753 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -1,9 +1,8 @@ //===- IntrinsicsPowerPC.td - Defines PowerPC intrinsics ---*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,7 +18,8 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". // dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions. def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbf : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">, + Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], @@ -610,16 +610,16 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.". // FP <-> integer conversion. def int_ppc_altivec_vcfsx : GCCBuiltin<"__builtin_altivec_vcfsx">, Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_ppc_altivec_vcfux : GCCBuiltin<"__builtin_altivec_vcfux">, Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_ppc_altivec_vctsxs : GCCBuiltin<"__builtin_altivec_vctsxs">, Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_ppc_altivec_vctuxs : GCCBuiltin<"__builtin_altivec_vctuxs">, Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_ppc_altivec_vrfim : GCCBuiltin<"__builtin_altivec_vrfim">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; @@ -716,11 +716,11 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.". def int_ppc_altivec_crypto_vshasigmad : GCCBuiltin<"__builtin_altivec_crypto_vshasigmad">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>, ImmArg<2>]>; def int_ppc_altivec_crypto_vshasigmaw : GCCBuiltin<"__builtin_altivec_crypto_vshasigmaw">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>, ImmArg<2>]>; } def int_ppc_altivec_crypto_vcipher : PowerPC_Vec_DDD_Intrinsic<"crypto_vcipher">; @@ -915,10 +915,10 @@ def int_ppc_vsx_xvxsigsp : [llvm_v4f32_ty], [IntrNoMem]>; def int_ppc_vsx_xvtstdcdp : PowerPC_VSX_Intrinsic<"xvtstdcdp", [llvm_v2i64_ty], - [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_ppc_vsx_xvtstdcsp : PowerPC_VSX_Intrinsic<"xvtstdcsp", [llvm_v4i32_ty], - [llvm_v4f32_ty,llvm_i32_ty], [IntrNoMem]>; + [llvm_v4f32_ty,llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_ppc_vsx_xvcvhpsp : PowerPC_VSX_Intrinsic<"xvcvhpsp", [llvm_v4f32_ty], [llvm_v8i16_ty],[IntrNoMem]>; @@ -1113,9 +1113,9 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_tbegin : GCCBuiltin<"__builtin_tbegin">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<0>]>; def int_ppc_tend : GCCBuiltin<"__builtin_tend">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<0>]>; def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; @@ -1167,4 +1167,9 @@ def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">, Intrinsic<[llvm_i64_ty], [], []>; def int_ppc_cfence : Intrinsic<[], [llvm_anyint_ty], []>; + +// PowerPC set FPSCR Intrinsic Definitions. +def int_ppc_setrnd : GCCBuiltin<"__builtin_setrnd">, + Intrinsic<[llvm_double_ty], [llvm_i32_ty], []>; + } diff --git a/include/llvm/IR/IntrinsicsRISCV.td b/include/llvm/IR/IntrinsicsRISCV.td index 0ac7348b56db..60393189b830 100644 --- a/include/llvm/IR/IntrinsicsRISCV.td +++ b/include/llvm/IR/IntrinsicsRISCV.td @@ -1,9 +1,8 @@ //===- IntrinsicsRISCV.td - Defines RISCV intrinsics -------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,13 +18,13 @@ let TargetPrefix = "riscv" in { class MaskedAtomicRMW32Intrinsic : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrArgMemOnly, NoCapture<0>]>; + [IntrArgMemOnly, NoCapture<0>, ImmArg<3>]>; class MaskedAtomicRMW32WithSextIntrinsic : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrArgMemOnly, NoCapture<0>]>; + [IntrArgMemOnly, NoCapture<0>, ImmArg<4>]>; def int_riscv_masked_atomicrmw_xchg_i32 : MaskedAtomicRMW32Intrinsic; def int_riscv_masked_atomicrmw_add_i32 : MaskedAtomicRMW32Intrinsic; @@ -39,6 +38,31 @@ def int_riscv_masked_atomicrmw_umin_i32 : MaskedAtomicRMW32Intrinsic; def int_riscv_masked_cmpxchg_i32 : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrArgMemOnly, NoCapture<0>]>; + [IntrArgMemOnly, NoCapture<0>, ImmArg<4>]>; + +class MaskedAtomicRMW64Intrinsic + : Intrinsic<[llvm_i64_ty], + [llvm_anyptr_ty, llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], + [IntrArgMemOnly, NoCapture<0>, ImmArg<3>]>; + +class MaskedAtomicRMW64WithSextIntrinsic + : Intrinsic<[llvm_i64_ty], + [llvm_anyptr_ty, llvm_i64_ty, llvm_i64_ty, llvm_i64_ty, + llvm_i64_ty], + [IntrArgMemOnly, NoCapture<0>, ImmArg<4>]>; + +def int_riscv_masked_atomicrmw_xchg_i64 : MaskedAtomicRMW64Intrinsic; +def int_riscv_masked_atomicrmw_add_i64 : MaskedAtomicRMW64Intrinsic; +def int_riscv_masked_atomicrmw_sub_i64 : MaskedAtomicRMW64Intrinsic; +def int_riscv_masked_atomicrmw_nand_i64 : MaskedAtomicRMW64Intrinsic; +def int_riscv_masked_atomicrmw_max_i64 : MaskedAtomicRMW64WithSextIntrinsic; +def int_riscv_masked_atomicrmw_min_i64 : MaskedAtomicRMW64WithSextIntrinsic; +def int_riscv_masked_atomicrmw_umax_i64 : MaskedAtomicRMW64Intrinsic; +def int_riscv_masked_atomicrmw_umin_i64 : MaskedAtomicRMW64Intrinsic; + +def int_riscv_masked_cmpxchg_i64 + : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty, llvm_i64_ty, llvm_i64_ty, + llvm_i64_ty, llvm_i64_ty], + [IntrArgMemOnly, NoCapture<0>, ImmArg<4>]>; } // TargetPrefix = "riscv" diff --git a/include/llvm/IR/IntrinsicsSystemZ.td b/include/llvm/IR/IntrinsicsSystemZ.td index caa2ec209a31..40d6ba17eaf1 100644 --- a/include/llvm/IR/IntrinsicsSystemZ.td +++ b/include/llvm/IR/IntrinsicsSystemZ.td @@ -1,9 +1,8 @@ //===- IntrinsicsSystemZ.td - Defines SystemZ intrinsics ---*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -39,7 +38,8 @@ class SystemZBinaryConvCC<LLVMType result, LLVMType arg> : Intrinsic<[result, llvm_i32_ty], [arg, arg], [IntrNoMem]>; class SystemZBinaryConvIntCC<LLVMType result, LLVMType arg> - : Intrinsic<[result, llvm_i32_ty], [arg, llvm_i32_ty], [IntrNoMem]>; + : Intrinsic<[result, llvm_i32_ty], [arg, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; class SystemZBinaryCC<LLVMType type> : SystemZBinaryConvCC<type, type>; @@ -48,23 +48,28 @@ class SystemZTernaryConv<string name, LLVMType result, LLVMType arg> : GCCBuiltin<"__builtin_s390_" ## name>, Intrinsic<[result], [arg, arg, result], [IntrNoMem]>; +class SystemZTernaryConvCC<LLVMType result, LLVMType arg> + : Intrinsic<[result, llvm_i32_ty], [arg, arg, result], [IntrNoMem]>; + class SystemZTernary<string name, LLVMType type> : SystemZTernaryConv<name, type, type>; class SystemZTernaryInt<string name, LLVMType type> : GCCBuiltin<"__builtin_s390_" ## name>, - Intrinsic<[type], [type, type, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[type], [type, type, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; class SystemZTernaryIntCC<LLVMType type> - : Intrinsic<[type, llvm_i32_ty], [type, type, llvm_i32_ty], [IntrNoMem]>; + : Intrinsic<[type, llvm_i32_ty], [type, type, llvm_i32_ty], + [IntrNoMem, ImmArg<2>]>; class SystemZQuaternaryInt<string name, LLVMType type> : GCCBuiltin<"__builtin_s390_" ## name>, - Intrinsic<[type], [type, type, type, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[type], [type, type, type, llvm_i32_ty], + [IntrNoMem, ImmArg<3>]>; class SystemZQuaternaryIntCC<LLVMType type> : Intrinsic<[type, llvm_i32_ty], [type, type, type, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; multiclass SystemZUnaryExtBHF<string name> { def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>; @@ -180,7 +185,8 @@ multiclass SystemZQuaternaryIntBHF<string name> { def f : SystemZQuaternaryInt<name##"f", llvm_v4i32_ty>; } -multiclass SystemZQuaternaryIntBHFG<string name> : SystemZQuaternaryIntBHF<name> { +multiclass SystemZQuaternaryIntBHFG<string name> : + SystemZQuaternaryIntBHF<name> { def g : SystemZQuaternaryInt<name##"g", llvm_v2i64_ty>; } @@ -232,11 +238,11 @@ let TargetPrefix = "s390" in { let TargetPrefix = "s390" in { def int_s390_lcbb : GCCBuiltin<"__builtin_s390_lcbb">, Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_s390_vlbb : GCCBuiltin<"__builtin_s390_vlbb">, Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_s390_vll : GCCBuiltin<"__builtin_s390_vll">, Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty, llvm_ptr_ty], @@ -245,7 +251,7 @@ let TargetPrefix = "s390" in { def int_s390_vpdi : GCCBuiltin<"__builtin_s390_vpdi">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_s390_vperm : GCCBuiltin<"__builtin_s390_vperm">, Intrinsic<[llvm_v16i8_ty], @@ -311,7 +317,7 @@ let TargetPrefix = "s390" in { def int_s390_vsldb : GCCBuiltin<"__builtin_s390_vsldb">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; defm int_s390_vscbi : SystemZBinaryBHFG<"vscbi">; @@ -370,7 +376,7 @@ let TargetPrefix = "s390" in { def int_s390_vfidb : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>, ImmArg<2>]>; // Instructions from the Vector Enhancements Facility 1 def int_s390_vbperm : SystemZBinaryConv<"vbperm", llvm_v2i64_ty, @@ -379,20 +385,20 @@ let TargetPrefix = "s390" in { def int_s390_vmslg : GCCBuiltin<"__builtin_s390_vmslg">, Intrinsic<[llvm_v16i8_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v16i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>]>; def int_s390_vfmaxdb : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_s390_vfmindb : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_s390_vfmaxsb : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_s390_vfminsb : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_s390_vfcesbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>; def int_s390_vfchsbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>; @@ -402,7 +408,7 @@ let TargetPrefix = "s390" in { def int_s390_vfisb : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>, ImmArg<2>]>; // Instructions from the Vector Packed Decimal Facility def int_s390_vlrl : GCCBuiltin<"__builtin_s390_vlrl">, @@ -412,6 +418,24 @@ let TargetPrefix = "s390" in { def int_s390_vstrl : GCCBuiltin<"__builtin_s390_vstrl">, Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty], [IntrArgMemOnly, IntrWriteMem]>; + + // Instructions from the Vector Enhancements Facility 2 + def int_s390_vsld : GCCBuiltin<"__builtin_s390_vsld">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>]>; + + def int_s390_vsrd : GCCBuiltin<"__builtin_s390_vsrd">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>]>; + + def int_s390_vstrsb : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v16i8_ty>; + def int_s390_vstrsh : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v8i16_ty>; + def int_s390_vstrsf : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v4i32_ty>; + def int_s390_vstrszb : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v16i8_ty>; + def int_s390_vstrszh : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v8i16_ty>; + def int_s390_vstrszf : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v4i32_ty>; } //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td index b015650906e0..1b892727547d 100644 --- a/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -1,9 +1,8 @@ //===- IntrinsicsWebAssembly.td - Defines wasm intrinsics --*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -41,8 +40,8 @@ def int_wasm_trunc_saturate_unsigned : Intrinsic<[llvm_anyint_ty], // throw / rethrow def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], - [Throws, IntrNoReturn]>; -def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>; + [Throws, IntrNoReturn, ImmArg<0>]>; +def int_wasm_rethrow_in_catch : Intrinsic<[], [], [Throws, IntrNoReturn]>; // Since wasm does not use landingpad instructions, these instructions return // exception pointer and selector values until we lower them in WasmEHPrepare. @@ -50,17 +49,16 @@ def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty], [IntrHasSideEffects]>; def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrHasSideEffects]>; - -// wasm.catch returns the pointer to the exception object caught by wasm 'catch' -// instruction. -def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], - [IntrHasSideEffects]>; +// This is the same as llvm.wasm.get.exception except that it does not take a +// token operand. This is only for instruction selection purpose. +def int_wasm_extract_exception : Intrinsic<[llvm_ptr_ty], [], + [IntrHasSideEffects]>; // WebAssembly EH must maintain the landingpads in the order assigned to them // by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is // used in order to give them the indices in WasmEHPrepare. def int_wasm_landingpad_index: Intrinsic<[], [llvm_token_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; // Returns LSDA address of the current function. def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; @@ -112,4 +110,27 @@ def int_wasm_alltrue : [llvm_anyvector_ty], [IntrNoMem, IntrSpeculatable]>; +//===----------------------------------------------------------------------===// +// Bulk memory intrinsics +//===----------------------------------------------------------------------===// + +def int_wasm_memory_init : + Intrinsic<[], + [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], + [IntrWriteMem, IntrInaccessibleMemOrArgMemOnly, WriteOnly<2>, + IntrHasSideEffects, ImmArg<0>, ImmArg<1>]>; +def int_wasm_data_drop : + Intrinsic<[], + [llvm_i32_ty], + [IntrNoDuplicate, IntrHasSideEffects, ImmArg<0>]>; + +//===----------------------------------------------------------------------===// +// Thread-local storage intrinsics +//===----------------------------------------------------------------------===// + +def int_wasm_tls_size : + Intrinsic<[llvm_anyint_ty], + [], + [IntrNoMem, IntrSpeculatable]>; + } // TargetPrefix = "wasm" diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index 8d8cc8e97678..236d312d7d78 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -1,9 +1,8 @@ //===- IntrinsicsX86.td - Defines X86 intrinsics -----------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,7 +13,7 @@ //===----------------------------------------------------------------------===// // Interrupt traps let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_int : Intrinsic<[], [llvm_i8_ty]>; + def int_x86_int : Intrinsic<[], [llvm_i8_ty], [ImmArg<0>]>; } //===----------------------------------------------------------------------===// @@ -204,12 +203,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse_cmp_ss : GCCBuiltin<"__builtin_ia32_cmpss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; // NOTE: This comparison intrinsic is not used by clang as long as the // distinction in signaling behaviour is not implemented. def int_x86_sse_cmp_ps : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_sse_comieq_ss : GCCBuiltin<"__builtin_ia32_comieq">, Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; @@ -278,9 +277,17 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Control register. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse_stmxcsr : - Intrinsic<[], [llvm_ptr_ty], []>; + Intrinsic<[], [llvm_ptr_ty], + [IntrWriteMem, IntrArgMemOnly, + // This prevents reordering with ldmxcsr + IntrHasSideEffects]>; def int_x86_sse_ldmxcsr : - Intrinsic<[], [llvm_ptr_ty], []>; + Intrinsic<[], [llvm_ptr_ty], + [IntrReadMem, IntrArgMemOnly, IntrHasSideEffects, + // FIXME: LDMXCSR does not actualy write to memory, + // but Fast and DAG Isel both use writing to memory + // as a proxy for having side effects. + IntrWriteMem]>; } // Misc. @@ -312,12 +319,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse2_cmp_sd : GCCBuiltin<"__builtin_ia32_cmpsd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; // NOTE: This comparison intrinsic is not used by clang as long as the // distinction in signaling behaviour is not implemented. def int_x86_sse2_cmp_pd : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_sse2_comieq_sd : GCCBuiltin<"__builtin_ia32_comisdeq">, Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; @@ -367,6 +374,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd128">, Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem, Commutative]>; + def int_x86_sse2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb128">, + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, + llvm_v16i8_ty], [IntrNoMem, Commutative]>; + def int_x86_sse2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw128">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, + llvm_v8i16_ty], [IntrNoMem, Commutative]>; def int_x86_sse2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw128">, Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem, Commutative]>; @@ -399,6 +412,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; + // Oddly these don't require an immediate due to a gcc compatibility issue. def int_x86_sse2_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi128">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; @@ -604,7 +618,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v16i8_ty], [IntrNoMem]>; def int_x86_sse_pshuf_w : GCCBuiltin<"__builtin_ia32_pshufw">, Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; } // Sign ops @@ -650,16 +664,16 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_round_ss : GCCBuiltin<"__builtin_ia32_roundss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_sse41_round_ps : GCCBuiltin<"__builtin_ia32_roundps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_x86_sse41_round_sd : GCCBuiltin<"__builtin_ia32_roundsd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_sse41_round_pd : GCCBuiltin<"__builtin_ia32_roundpd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; } // Vector min element @@ -722,20 +736,20 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_aesni_aeskeygenassist : GCCBuiltin<"__builtin_ia32_aeskeygenassist128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; } // PCLMUL instructions let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_pclmulqdq : GCCBuiltin<"__builtin_ia32_pclmulqdq128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_pclmulqdq_256 : GCCBuiltin<"__builtin_ia32_pclmulqdq256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_pclmulqdq_512 : GCCBuiltin<"__builtin_ia32_pclmulqdq512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; } // Vector pack @@ -749,7 +763,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_insertps : GCCBuiltin<"__builtin_ia32_insertps128">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; } // Vector blend @@ -769,17 +783,17 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_dppd : GCCBuiltin<"__builtin_ia32_dppd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem, Commutative]>; + [IntrNoMem, Commutative, ImmArg<2>]>; def int_x86_sse41_dpps : GCCBuiltin<"__builtin_ia32_dpps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem, Commutative]>; + [IntrNoMem, Commutative, ImmArg<2>]>; } // Vector sum of absolute differences let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw128">, Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_i8_ty], - [IntrNoMem, Commutative]>; + [IntrNoMem, Commutative, ImmArg<2>]>; } // Test instruction with bitwise comparison. @@ -820,66 +834,66 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse42_pcmpistrm128 : GCCBuiltin<"__builtin_ia32_pcmpistrm128">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpistri128 : GCCBuiltin<"__builtin_ia32_pcmpistri128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sse42_pcmpestrm128 : GCCBuiltin<"__builtin_ia32_pcmpestrm128">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_sse42_pcmpestri128 : GCCBuiltin<"__builtin_ia32_pcmpestri128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">, Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; } //===----------------------------------------------------------------------===// @@ -888,13 +902,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse4a_extrqi : GCCBuiltin<"__builtin_ia32_extrqi">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>, ImmArg<2>]>; def int_x86_sse4a_extrq : GCCBuiltin<"__builtin_ia32_extrq">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_x86_sse4a_insertqi : GCCBuiltin<"__builtin_ia32_insertqi">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_i8_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<2>, ImmArg<3>]>; def int_x86_sse4a_insertq : GCCBuiltin<"__builtin_ia32_insertq">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; } @@ -931,10 +946,10 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_round_pd_256 : GCCBuiltin<"__builtin_ia32_roundpd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; def int_x86_avx_round_ps_256 : GCCBuiltin<"__builtin_ia32_roundps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<1>]>; } // Horizontal ops @@ -1086,33 +1101,33 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_vgf2p8affineinvqb_v16qi">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_vgf2p8affineinvqb_256 : GCCBuiltin<"__builtin_ia32_vgf2p8affineinvqb_v32qi">, Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_vgf2p8affineinvqb_512 : GCCBuiltin<"__builtin_ia32_vgf2p8affineinvqb_v64qi">, Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_vgf2p8affineqb_128 : GCCBuiltin<"__builtin_ia32_vgf2p8affineqb_v16qi">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_vgf2p8affineqb_256 : GCCBuiltin<"__builtin_ia32_vgf2p8affineqb_v32qi">, Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_vgf2p8affineqb_512 : GCCBuiltin<"__builtin_ia32_vgf2p8affineqb_v64qi">, Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_vgf2p8mulb_128 : GCCBuiltin<"__builtin_ia32_vgf2p8mulb_v16qi">, @@ -1145,17 +1160,18 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_dp_ps_256 : GCCBuiltin<"__builtin_ia32_dpps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem, Commutative]>; + llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem, Commutative, ImmArg<2>]>; } // Vector compare let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_cmp_pd_256 : Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx_cmp_ps_256 : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; } // Vector convert @@ -1222,30 +1238,30 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_fpclass_pd_128 : Intrinsic<[llvm_v2i1_ty], [llvm_v2f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_fpclass_pd_256 : Intrinsic<[llvm_v4i1_ty], [llvm_v4f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_fpclass_pd_512 : Intrinsic<[llvm_v8i1_ty], [llvm_v8f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_fpclass_ps_128 : Intrinsic<[llvm_v4i1_ty], [llvm_v4f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_fpclass_ps_256 : Intrinsic<[llvm_v8i1_ty], [llvm_v8f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_fpclass_ps_512 : Intrinsic<[llvm_v16i1_ty], [llvm_v16f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_mask_fpclass_sd : GCCBuiltin<"__builtin_ia32_fpclasssd_mask">, Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_mask_fpclass_ss : GCCBuiltin<"__builtin_ia32_fpclassss_mask">, Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; } // Vector extract sign mask @@ -1328,6 +1344,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd256">, Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem, Commutative]>; + def int_x86_avx2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb256">, + Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, + llvm_v32i8_ty], [IntrNoMem, Commutative]>; + def int_x86_avx2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw256">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, + llvm_v16i16_ty], [IntrNoMem, Commutative]>; def int_x86_avx2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw256">, Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem, Commutative]>; @@ -1360,6 +1382,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v4i32_ty], [IntrNoMem]>; + // Oddly these don't require an immediate due to a gcc compatibility issue. def int_x86_avx2_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi256">, Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; @@ -1392,6 +1415,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v2i64_ty], [IntrNoMem]>; + // Oddly these don't require an immediate due to a gcc compatibility issue. def int_x86_avx512_psrai_q_128 : GCCBuiltin<"__builtin_ia32_psraqi128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; @@ -1427,6 +1451,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v2i64_ty], [IntrNoMem]>; + // Oddly these don't require an immediate due to a gcc compatibility issue. def int_x86_avx512_pslli_w_512 : GCCBuiltin<"__builtin_ia32_psllwi512">, Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; @@ -1677,71 +1702,73 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Gather ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; } // Misc. @@ -1753,7 +1780,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v32i8_ty], [IntrNoMem]>; def int_x86_avx2_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw256">, Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty, - llvm_i8_ty], [IntrNoMem, Commutative]>; + llvm_i8_ty], [IntrNoMem, Commutative, ImmArg<2>]>; } //===----------------------------------------------------------------------===// @@ -1763,32 +1790,32 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_vfmadd_pd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_vfmadd_ps_512 : Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; // TODO: Can we use 2 vfmadds+shufflevector? def int_x86_avx512_vfmaddsub_pd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_vfmaddsub_ps_512 : Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_vfmadd_f64 : Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty, llvm_double_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_vfmadd_f32 : Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_vpmadd52h_uq_128 : GCCBuiltin<"__builtin_ia32_vpmadd52huq128">, @@ -1878,23 +1905,23 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_xop_vpermil2pd : GCCBuiltin<"__builtin_ia32_vpermil2pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_xop_vpermil2pd_256 : GCCBuiltin<"__builtin_ia32_vpermil2pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_xop_vpermil2ps : GCCBuiltin<"__builtin_ia32_vpermil2ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_xop_vpermil2ps_256 : GCCBuiltin<"__builtin_ia32_vpermil2ps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_xop_vfrcz_pd : GCCBuiltin<"__builtin_ia32_vfrczpd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; @@ -1909,31 +1936,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_xop_vfrcz_ps_256 : GCCBuiltin<"__builtin_ia32_vfrczps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; - def int_x86_xop_vpcomb : GCCBuiltin<"__builtin_ia32_vpcomb">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomw : GCCBuiltin<"__builtin_ia32_vpcomw">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomd : GCCBuiltin<"__builtin_ia32_vpcomd">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomq : GCCBuiltin<"__builtin_ia32_vpcomq">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomub : GCCBuiltin<"__builtin_ia32_vpcomub">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomuw : GCCBuiltin<"__builtin_ia32_vpcomuw">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomud : GCCBuiltin<"__builtin_ia32_vpcomud">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vpcomuq : GCCBuiltin<"__builtin_ia32_vpcomuq">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_xop_vphaddbd : GCCBuiltin<"__builtin_ia32_vphaddbd">, Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; @@ -2261,6 +2263,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], [IntrNoMem]>; + // Oddly these don't require an immediate due to a gcc compatibility issue. def int_x86_mmx_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi">, Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i32_ty], [IntrNoMem]>; @@ -2398,15 +2401,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">, Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, - llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">, Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">, Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; } //===----------------------------------------------------------------------===// @@ -2527,13 +2530,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty], [IntrNoMem]>; def int_x86_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph">, Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">, Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_i16_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<3>]>; 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]>; @@ -2542,13 +2546,16 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". 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]>; + llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; } //===----------------------------------------------------------------------===// @@ -2556,9 +2563,11 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_tbm_bextri_u32 : GCCBuiltin<"__builtin_ia32_bextri_u32">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_tbm_bextri_u64 : GCCBuiltin<"__builtin_ia32_bextri_u64">, - Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], + [IntrNoMem, ImmArg<1>]>; } //===----------------------------------------------------------------------===// @@ -2604,7 +2613,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">, Intrinsic<[], [], []>; def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">, - Intrinsic<[], [llvm_i8_ty], []>; + Intrinsic<[], [llvm_i8_ty], [ImmArg<0>]>; def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">, Intrinsic<[llvm_i32_ty], [], []>; } @@ -2645,55 +2654,71 @@ let TargetPrefix = "x86" in { // Conversion ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_cvttss2si : GCCBuiltin<"__builtin_ia32_vcvttss2si32">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvttss2si64 : GCCBuiltin<"__builtin_ia32_vcvttss2si64">, - Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvttss2usi : GCCBuiltin<"__builtin_ia32_vcvttss2usi32">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvttss2usi64 : GCCBuiltin<"__builtin_ia32_vcvttss2usi64">, - Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvtusi2ss : GCCBuiltin<"__builtin_ia32_cvtusi2ss32">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cvtusi642ss : GCCBuiltin<"__builtin_ia32_cvtusi2ss64">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cvttsd2si : GCCBuiltin<"__builtin_ia32_vcvttsd2si32">, - Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvttsd2si64 : GCCBuiltin<"__builtin_ia32_vcvttsd2si64">, - Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvttsd2usi : GCCBuiltin<"__builtin_ia32_vcvttsd2usi32">, - Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvttsd2usi64 : GCCBuiltin<"__builtin_ia32_vcvttsd2usi64">, - Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvtusi642sd : GCCBuiltin<"__builtin_ia32_cvtusi2sd64">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_vcvtss2usi32 : GCCBuiltin<"__builtin_ia32_vcvtss2usi32">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtss2usi64 : GCCBuiltin<"__builtin_ia32_vcvtss2usi64">, - Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtss2si32 : GCCBuiltin<"__builtin_ia32_vcvtss2si32">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtss2si64 : GCCBuiltin<"__builtin_ia32_vcvtss2si64">, - Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtsd2usi32 : GCCBuiltin<"__builtin_ia32_vcvtsd2usi32">, - Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtsd2usi64 : GCCBuiltin<"__builtin_ia32_vcvtsd2usi64">, - Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtsd2si32 : GCCBuiltin<"__builtin_ia32_vcvtsd2si32">, - Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_vcvtsd2si64 : GCCBuiltin<"__builtin_ia32_vcvtsd2si64">, - Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_cvtsi2ss32 : GCCBuiltin<"__builtin_ia32_cvtsi2ss32">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cvtsi2ss64 : GCCBuiltin<"__builtin_ia32_cvtsi2ss64">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cvtsi2sd64 : GCCBuiltin<"__builtin_ia32_cvtsi2sd64">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; } // Pack ops. @@ -2714,11 +2739,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Vector convert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - 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_sitofp_round : + Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; + + def int_x86_avx512_uitofp_round : + Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_mask_cvtpd2dq_128 : GCCBuiltin<"__builtin_ia32_cvtpd2dq128_mask">, @@ -2730,25 +2757,25 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">, Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; 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]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtsd2ss_round : GCCBuiltin<"__builtin_ia32_cvtsd2ss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v2f64_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_cvtss2sd_round : GCCBuiltin<"__builtin_ia32_cvtss2sd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v4f32_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_cvtpd2ps : GCCBuiltin<"__builtin_ia32_cvtpd2ps_mask">, @@ -2772,7 +2799,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtpd2qq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtpd2udq_128 : GCCBuiltin<"__builtin_ia32_cvtpd2udq128_mask">, @@ -2790,7 +2817,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">, Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtpd2uqq_128 : GCCBuiltin<"__builtin_ia32_cvtpd2uqq128_mask">, @@ -2808,7 +2835,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtpd2uqq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtps2dq_128 : GCCBuiltin<"__builtin_ia32_cvtps2dq128_mask">, @@ -2826,13 +2853,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">, Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; 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]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtps2qq_128 : GCCBuiltin<"__builtin_ia32_cvtps2qq128_mask">, @@ -2850,7 +2877,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtps2qq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtps2udq_128 : GCCBuiltin<"__builtin_ia32_cvtps2udq128_mask">, @@ -2868,7 +2895,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">, Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtps2uqq_128 : GCCBuiltin<"__builtin_ia32_cvtps2uqq128_mask">, @@ -2886,13 +2913,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". 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_512 : - GCCBuiltin<"__builtin_ia32_cvtqq2pd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtqq2ps_128 : GCCBuiltin<"__builtin_ia32_cvtqq2ps128_mask">, @@ -2900,18 +2921,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [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], @@ -2922,7 +2931,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">, Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvttpd2qq_128 : GCCBuiltin<"__builtin_ia32_cvttpd2qq128_mask">, @@ -2940,7 +2949,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvttpd2qq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvttpd2udq_128 : GCCBuiltin<"__builtin_ia32_cvttpd2udq128_mask">, @@ -2958,7 +2967,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">, Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvttpd2uqq_128 : GCCBuiltin<"__builtin_ia32_cvttpd2uqq128_mask">, @@ -2976,13 +2985,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvttpd2uqq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; 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]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvttps2qq_128 : GCCBuiltin<"__builtin_ia32_cvttps2qq128_mask">, @@ -3000,7 +3009,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvttps2qq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvttps2udq_128 : GCCBuiltin<"__builtin_ia32_cvttps2udq128_mask">, @@ -3018,7 +3027,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">, Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvttps2uqq_128 : GCCBuiltin<"__builtin_ia32_cvttps2uqq128_mask">, @@ -3036,19 +3045,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". 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_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_512 : - GCCBuiltin<"__builtin_ia32_cvtuqq2pd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_cvtuqq2ps_128 : GCCBuiltin<"__builtin_ia32_cvtuqq2ps128_mask">, @@ -3056,72 +3053,78 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [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]>; + llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>, ImmArg<4>]>; 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]>; + llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_i16_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>, ImmArg<4>]>; 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]>; + llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>, ImmArg<4>]>; 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]>; + llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<1>]>; 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]>; + llvm_i16_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>, ImmArg<4>]>; 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]>; + llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<2>]>; 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]>; + llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<2>]>; 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]>; + llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<5>]>; 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]>; + llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<2>]>; 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]>; + llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<2>]>; 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]>; + llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<5>]>; } // Vector load with broadcast @@ -3151,109 +3154,111 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_add_ps_512 : GCCBuiltin<"__builtin_ia32_addps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_add_pd_512 : GCCBuiltin<"__builtin_ia32_addpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_sub_ps_512 : GCCBuiltin<"__builtin_ia32_subps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_sub_pd_512 : GCCBuiltin<"__builtin_ia32_subpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_mul_ps_512 : GCCBuiltin<"__builtin_ia32_mulps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_mul_pd_512 : GCCBuiltin<"__builtin_ia32_mulpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_div_ps_512 : GCCBuiltin<"__builtin_ia32_divps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_div_pd_512 : GCCBuiltin<"__builtin_ia32_divpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_mask_add_ss_round : GCCBuiltin<"__builtin_ia32_addss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_div_ss_round : GCCBuiltin<"__builtin_ia32_divss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_mul_ss_round : GCCBuiltin<"__builtin_ia32_mulss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_sub_ss_round : GCCBuiltin<"__builtin_ia32_subss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_max_ss_round : GCCBuiltin<"__builtin_ia32_maxss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_min_ss_round : GCCBuiltin<"__builtin_ia32_minss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_add_sd_round : GCCBuiltin<"__builtin_ia32_addsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_div_sd_round : GCCBuiltin<"__builtin_ia32_divsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_mul_sd_round : GCCBuiltin<"__builtin_ia32_mulsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_sub_sd_round : GCCBuiltin<"__builtin_ia32_subsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_max_sd_round : GCCBuiltin<"__builtin_ia32_maxsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_min_sd_round : GCCBuiltin<"__builtin_ia32_minsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>, ImmArg<5>]>; def int_x86_avx512_mask_rndscale_sd : GCCBuiltin<"__builtin_ia32_rndscalesd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>, ImmArg<5>]>; def int_x86_avx512_mask_range_ss : GCCBuiltin<"__builtin_ia32_rangess128_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>, ImmArg<5>]>; def int_x86_avx512_mask_range_sd : GCCBuiltin<"__builtin_ia32_rangesd128_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>, ImmArg<5>]>; def int_x86_avx512_mask_reduce_ss : GCCBuiltin<"__builtin_ia32_reducess_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>, ImmArg<5>]>; def int_x86_avx512_mask_reduce_sd : GCCBuiltin<"__builtin_ia32_reducesd_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>, ImmArg<5>]>; def int_x86_avx512_mask_scalef_sd : GCCBuiltin<"__builtin_ia32_scalefsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_scalef_ss : GCCBuiltin<"__builtin_ia32_scalefss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; 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]>; @@ -3262,7 +3267,8 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v4f64_ty, llvm_i8_ty],[IntrNoMem]>; def int_x86_avx512_mask_scalef_pd_512 : GCCBuiltin<"__builtin_ia32_scalefpd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_scalef_ps_128 : GCCBuiltin<"__builtin_ia32_scalefps128_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; @@ -3271,99 +3277,104 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_scalef_ps_512 : GCCBuiltin<"__builtin_ia32_scalefps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_sqrt_ss : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_sqrt_sd : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_sqrt_pd_512 : - Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_sqrt_ps_512 : - Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; def int_x86_avx512_mask_fixupimm_pd_128 : GCCBuiltin<"__builtin_ia32_fixupimmpd128_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_maskz_fixupimm_pd_128 : GCCBuiltin<"__builtin_ia32_fixupimmpd128_maskz">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_fixupimm_pd_256 : GCCBuiltin<"__builtin_ia32_fixupimmpd256_mask">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_maskz_fixupimm_pd_256 : GCCBuiltin<"__builtin_ia32_fixupimmpd256_maskz">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_fixupimm_pd_512 : GCCBuiltin<"__builtin_ia32_fixupimmpd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8i64_ty, llvm_i32_ty, llvm_i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_maskz_fixupimm_pd_512 : GCCBuiltin<"__builtin_ia32_fixupimmpd512_maskz">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8i64_ty, llvm_i32_ty, llvm_i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_mask_fixupimm_ps_128 : GCCBuiltin<"__builtin_ia32_fixupimmps128_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_maskz_fixupimm_ps_128 : GCCBuiltin<"__builtin_ia32_fixupimmps128_maskz">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_fixupimm_ps_256 : GCCBuiltin<"__builtin_ia32_fixupimmps256_mask">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_maskz_fixupimm_ps_256 : GCCBuiltin<"__builtin_ia32_fixupimmps256_maskz">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_fixupimm_ps_512 : GCCBuiltin<"__builtin_ia32_fixupimmps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16i32_ty, llvm_i32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_maskz_fixupimm_ps_512 : GCCBuiltin<"__builtin_ia32_fixupimmps512_maskz">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16i32_ty, llvm_i32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_mask_fixupimm_sd : GCCBuiltin<"__builtin_ia32_fixupimmsd_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_maskz_fixupimm_sd : GCCBuiltin<"__builtin_ia32_fixupimmsd_maskz">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_mask_fixupimm_ss : GCCBuiltin<"__builtin_ia32_fixupimmss_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_maskz_fixupimm_ss : GCCBuiltin<"__builtin_ia32_fixupimmss_maskz">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>; def int_x86_avx512_mask_getexp_pd_128 : GCCBuiltin<"__builtin_ia32_getexppd128_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; @@ -3372,7 +3383,8 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_getexp_pd_512 : GCCBuiltin<"__builtin_ia32_getexppd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_getexp_ps_128 : GCCBuiltin<"__builtin_ia32_getexpps128_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; @@ -3381,62 +3393,65 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_getexp_ps_512 : GCCBuiltin<"__builtin_ia32_getexpps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i16_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_mask_getexp_ss : GCCBuiltin<"__builtin_ia32_getexpss128_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_mask_getexp_sd : GCCBuiltin<"__builtin_ia32_getexpsd128_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<4>]>; 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]>; + [IntrNoMem, ImmArg<1>]>; 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]>; + [IntrNoMem, ImmArg<1>]>; 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]>; + [IntrNoMem, ImmArg<1>, ImmArg<4>]>; 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]>; + [IntrNoMem, ImmArg<1>]>; 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]>; + [IntrNoMem, ImmArg<1>]>; 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]>; + [IntrNoMem, ImmArg<1>, ImmArg<4>]>; def int_x86_avx512_mask_getmant_ss : GCCBuiltin<"__builtin_ia32_getmantss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>, ImmArg<5>]>; def int_x86_avx512_mask_getmant_sd : GCCBuiltin<"__builtin_ia32_getmantsd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v2f64_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>, ImmArg<5>]>; def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, @@ -3491,41 +3506,41 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx512_rcp28_ps : GCCBuiltin<"__builtin_ia32_rcp28ps_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_rcp28_pd : GCCBuiltin<"__builtin_ia32_rcp28pd_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_exp2_ps : GCCBuiltin<"__builtin_ia32_exp2ps_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_exp2_pd : GCCBuiltin<"__builtin_ia32_exp2pd_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_rsqrt28_ps : GCCBuiltin<"__builtin_ia32_rsqrt28ps_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_rsqrt28_pd : GCCBuiltin<"__builtin_ia32_rsqrt28pd_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss_round_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd_round_mask">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<4>]>; def int_x86_avx512_psad_bw_512 : GCCBuiltin<"__builtin_ia32_psadbw512">, Intrinsic<[llvm_v8i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty], [IntrNoMem, Commutative]>; @@ -3538,6 +3553,12 @@ let TargetPrefix = "x86" in { def int_x86_avx512_pmulh_w_512 : GCCBuiltin<"__builtin_ia32_pmulhw512">, Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty], [IntrNoMem, Commutative]>; + def int_x86_avx512_pavg_b_512 : GCCBuiltin<"__builtin_ia32_pavgb512">, + Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty], + [IntrNoMem]>; + def int_x86_avx512_pavg_w_512 : GCCBuiltin<"__builtin_ia32_pavgw512">, + Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty], + [IntrNoMem]>; def int_x86_avx512_pmaddw_d_512 : GCCBuiltin<"__builtin_ia32_pmaddwd512">, Intrinsic<[llvm_v16i32_ty], [llvm_v32i16_ty, llvm_v32i16_ty], [IntrNoMem, Commutative]>; @@ -3548,582 +3569,553 @@ let TargetPrefix = "x86" in { def int_x86_avx512_dbpsadbw_128 : GCCBuiltin<"__builtin_ia32_dbpsadbw128">, Intrinsic<[llvm_v8i16_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_dbpsadbw_256 : GCCBuiltin<"__builtin_ia32_dbpsadbw256">, Intrinsic<[llvm_v16i16_ty], - [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_dbpsadbw_512 : GCCBuiltin<"__builtin_ia32_dbpsadbw512">, Intrinsic<[llvm_v32i16_ty], - [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty], [IntrNoMem]>; + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>]>; } // Gather and Scatter ops let TargetPrefix = "x86" in { // NOTE: These are deprecated in favor of the versions that take a vXi1 mask. - def int_x86_avx512_gather_dpd_512 : GCCBuiltin<"__builtin_ia32_gathersiv8df">, + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. + def int_x86_avx512_gather_dpd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_gather_dps_512 : GCCBuiltin<"__builtin_ia32_gathersiv16sf">, + [IntrReadMem, ImmArg<4>]>; + def int_x86_avx512_gather_dps_512 : Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_gather_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherdiv8df">, + [IntrReadMem, ImmArg<4>]>; + def int_x86_avx512_gather_qpd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_gather_qps_512 : GCCBuiltin<"__builtin_ia32_gatherdiv16sf">, + [IntrReadMem, ImmArg<4>]>; + def int_x86_avx512_gather_qps_512 : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; - def int_x86_avx512_gather_dpq_512 : GCCBuiltin<"__builtin_ia32_gathersiv8di">, + def int_x86_avx512_gather_dpq_512 : Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_gather_dpi_512 : GCCBuiltin<"__builtin_ia32_gathersiv16si">, + [IntrReadMem, ImmArg<4>]>; + def int_x86_avx512_gather_dpi_512 : Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_gather_qpq_512 : GCCBuiltin<"__builtin_ia32_gatherdiv8di">, + [IntrReadMem, ImmArg<4>]>; + def int_x86_avx512_gather_qpq_512 : Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_gather_qpi_512 : GCCBuiltin<"__builtin_ia32_gatherdiv16si">, + [IntrReadMem, ImmArg<4>]>; + def int_x86_avx512_gather_qpi_512 : Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div2_df : - GCCBuiltin<"__builtin_ia32_gather3div2df">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div2_di : - GCCBuiltin<"__builtin_ia32_gather3div2di">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div4_df : - GCCBuiltin<"__builtin_ia32_gather3div4df">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div4_di : - GCCBuiltin<"__builtin_ia32_gather3div4di">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div4_sf : - GCCBuiltin<"__builtin_ia32_gather3div4sf">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div4_si : - GCCBuiltin<"__builtin_ia32_gather3div4si">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div8_sf : - GCCBuiltin<"__builtin_ia32_gather3div8sf">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3div8_si : - GCCBuiltin<"__builtin_ia32_gather3div8si">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv2_df : - GCCBuiltin<"__builtin_ia32_gather3siv2df">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv2_di : - GCCBuiltin<"__builtin_ia32_gather3siv2di">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv4_df : - GCCBuiltin<"__builtin_ia32_gather3siv4df">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv4_di : - GCCBuiltin<"__builtin_ia32_gather3siv4di">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv4_sf : - GCCBuiltin<"__builtin_ia32_gather3siv4sf">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv4_si : - GCCBuiltin<"__builtin_ia32_gather3siv4si">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv8_sf : - GCCBuiltin<"__builtin_ia32_gather3siv8sf">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_gather3siv8_si : - GCCBuiltin<"__builtin_ia32_gather3siv8si">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; // scatter // NOTE: These are deprecated in favor of the versions that take a vXi1 mask. - def int_x86_avx512_scatter_dpd_512 : GCCBuiltin<"__builtin_ia32_scattersiv8df">, + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. + def int_x86_avx512_scatter_dpd_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; - def int_x86_avx512_scatter_dps_512 : GCCBuiltin<"__builtin_ia32_scattersiv16sf">, + [ImmArg<4>]>; + def int_x86_avx512_scatter_dps_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; - def int_x86_avx512_scatter_qpd_512 : GCCBuiltin<"__builtin_ia32_scatterdiv8df">, + [ImmArg<4>]>; + def int_x86_avx512_scatter_qpd_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; - def int_x86_avx512_scatter_qps_512 : GCCBuiltin<"__builtin_ia32_scatterdiv16sf">, + [ImmArg<4>]>; + def int_x86_avx512_scatter_qps_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; - def int_x86_avx512_scatter_dpq_512 : GCCBuiltin<"__builtin_ia32_scattersiv8di">, + def int_x86_avx512_scatter_dpq_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; - def int_x86_avx512_scatter_dpi_512 : GCCBuiltin<"__builtin_ia32_scattersiv16si">, + [ImmArg<4>]>; + def int_x86_avx512_scatter_dpi_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; - def int_x86_avx512_scatter_qpq_512 : GCCBuiltin<"__builtin_ia32_scatterdiv8di">, + [ImmArg<4>]>; + def int_x86_avx512_scatter_qpq_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; - def int_x86_avx512_scatter_qpi_512 : GCCBuiltin<"__builtin_ia32_scatterdiv16si">, + [ImmArg<4>]>; + def int_x86_avx512_scatter_qpi_512 : Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv2_df : - GCCBuiltin<"__builtin_ia32_scatterdiv2df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv2_di : - GCCBuiltin<"__builtin_ia32_scatterdiv2di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv4_df : - GCCBuiltin<"__builtin_ia32_scatterdiv4df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv4_di : - GCCBuiltin<"__builtin_ia32_scatterdiv4di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv4_sf : - GCCBuiltin<"__builtin_ia32_scatterdiv4sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv4_si : - GCCBuiltin<"__builtin_ia32_scatterdiv4si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv8_sf : - GCCBuiltin<"__builtin_ia32_scatterdiv8sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scatterdiv8_si : - GCCBuiltin<"__builtin_ia32_scatterdiv8si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv2_df : - GCCBuiltin<"__builtin_ia32_scattersiv2df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv2_di : - GCCBuiltin<"__builtin_ia32_scattersiv2di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv4_df : - GCCBuiltin<"__builtin_ia32_scattersiv4df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv4_di : - GCCBuiltin<"__builtin_ia32_scattersiv4di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv4_sf : - GCCBuiltin<"__builtin_ia32_scattersiv4sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv4_si : - GCCBuiltin<"__builtin_ia32_scattersiv4si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv8_sf : - GCCBuiltin<"__builtin_ia32_scattersiv8sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_scattersiv8_si : - GCCBuiltin<"__builtin_ia32_scattersiv8si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; // gather prefetch + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_gatherpf_dpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfdpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; def int_x86_avx512_gatherpf_dps_512 : GCCBuiltin<"__builtin_ia32_gatherpfdps">, Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; def int_x86_avx512_gatherpf_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfqpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; def int_x86_avx512_gatherpf_qps_512 : GCCBuiltin<"__builtin_ia32_gatherpfqps">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; // scatter prefetch + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_scatterpf_dpd_512 : GCCBuiltin<"__builtin_ia32_scatterpfdpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; def int_x86_avx512_scatterpf_dps_512 : GCCBuiltin<"__builtin_ia32_scatterpfdps">, Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; def int_x86_avx512_scatterpf_qpd_512 : GCCBuiltin<"__builtin_ia32_scatterpfqpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; def int_x86_avx512_scatterpf_qps_512 : GCCBuiltin<"__builtin_ia32_scatterpfqps">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>; } // AVX512 gather/scatter intrinsics that use vXi1 masks. let TargetPrefix = "x86" in { + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_mask_gather_dpd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_dps_512 : Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_v16i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_qpd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_qps_512 : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_dpq_512 : Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_dpi_512 : Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_v16i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_qpq_512 : Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather_qpi_512 : Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div2_df : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div2_di : Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div4_df : Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div4_di : Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div4_sf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div4_si : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div8_sf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3div8_si : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv2_df : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv2_di : Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv4_df : Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv4_di : Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv4_sf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv4_si : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv8_sf : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_gather3siv8_si : Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem, ImmArg<4>]>; def int_x86_avx512_mask_scatter_dpd_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatter_dps_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v16i1_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatter_qpd_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatter_qps_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_mask_scatter_dpq_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatter_dpi_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v16i1_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatter_qpq_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatter_qpi_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv2_df : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv2_di : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv4_df : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv4_di : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv4_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv4_si : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv8_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scatterdiv8_si : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv2_df : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv2_di : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv4_df : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv4_di : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv4_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv4_si : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv8_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; def int_x86_avx512_mask_scattersiv8_si : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + [ImmArg<4>]>; } // 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], - [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], - [IntrNoMem]>; + def int_x86_avx512_conflict_d_128 : + GCCBuiltin<"__builtin_ia32_vpconflictsi_128">, + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512_conflict_d_256 : + GCCBuiltin<"__builtin_ia32_vpconflictsi_256">, + Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512_conflict_d_512 : + GCCBuiltin<"__builtin_ia32_vpconflictsi_512">, + Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty], [IntrNoMem]>; + + def int_x86_avx512_conflict_q_128 : + GCCBuiltin<"__builtin_ia32_vpconflictdi_128">, + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; + def int_x86_avx512_conflict_q_256 : + GCCBuiltin<"__builtin_ia32_vpconflictdi_256">, + Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; + def int_x86_avx512_conflict_q_512 : + GCCBuiltin<"__builtin_ia32_vpconflictdi_512">, + Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty], [IntrNoMem]>; } // Compares @@ -4131,164 +4123,26 @@ 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]>; + llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<3>]>; 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]>; + llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<3>]>; } // Compress, Expand let TargetPrefix = "x86" in { - def int_x86_avx512_mask_compress_ps_512 : - GCCBuiltin<"__builtin_ia32_compresssf512_mask">, - Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_pd_512 : - GCCBuiltin<"__builtin_ia32_compressdf512_mask">, - Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_ps_256 : - GCCBuiltin<"__builtin_ia32_compresssf256_mask">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_pd_256 : - GCCBuiltin<"__builtin_ia32_compressdf256_mask">, - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_ps_128 : - GCCBuiltin<"__builtin_ia32_compresssf128_mask">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_pd_128 : - GCCBuiltin<"__builtin_ia32_compressdf128_mask">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_compress_d_512 : - GCCBuiltin<"__builtin_ia32_compresssi512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_q_512 : - GCCBuiltin<"__builtin_ia32_compressdi512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_d_256 : - GCCBuiltin<"__builtin_ia32_compresssi256_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_q_256 : - GCCBuiltin<"__builtin_ia32_compressdi256_mask">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_d_128 : - GCCBuiltin<"__builtin_ia32_compresssi128_mask">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_q_128 : - GCCBuiltin<"__builtin_ia32_compressdi128_mask">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_compress_b_512 : - GCCBuiltin<"__builtin_ia32_compressqi512_mask">, - Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty, - llvm_i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_w_512 : - GCCBuiltin<"__builtin_ia32_compresshi512_mask">, - Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_b_256 : - GCCBuiltin<"__builtin_ia32_compressqi256_mask">, - Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_w_256 : - GCCBuiltin<"__builtin_ia32_compresshi256_mask">, - Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_b_128 : - GCCBuiltin<"__builtin_ia32_compressqi128_mask">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_compress_w_128 : - GCCBuiltin<"__builtin_ia32_compresshi128_mask">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, - llvm_i8_ty], [IntrNoMem]>; - -// expand - def int_x86_avx512_mask_expand_ps_512 : - GCCBuiltin<"__builtin_ia32_expandsf512_mask">, - Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_pd_512 : - GCCBuiltin<"__builtin_ia32_expanddf512_mask">, - Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_ps_256 : - GCCBuiltin<"__builtin_ia32_expandsf256_mask">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_pd_256 : - GCCBuiltin<"__builtin_ia32_expanddf256_mask">, - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_ps_128 : - GCCBuiltin<"__builtin_ia32_expandsf128_mask">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_pd_128 : - GCCBuiltin<"__builtin_ia32_expanddf128_mask">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_expand_d_512 : - GCCBuiltin<"__builtin_ia32_expandsi512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_q_512 : - GCCBuiltin<"__builtin_ia32_expanddi512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_d_256 : - GCCBuiltin<"__builtin_ia32_expandsi256_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_q_256 : - GCCBuiltin<"__builtin_ia32_expanddi256_mask">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_d_128 : - GCCBuiltin<"__builtin_ia32_expandsi128_mask">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_q_128 : - GCCBuiltin<"__builtin_ia32_expanddi128_mask">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_expand_b_512 : - GCCBuiltin<"__builtin_ia32_expandqi512_mask">, - Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty, - llvm_i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_w_512 : - GCCBuiltin<"__builtin_ia32_expandhi512_mask">, - Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_b_256 : - GCCBuiltin<"__builtin_ia32_expandqi256_mask">, - Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_w_256 : - GCCBuiltin<"__builtin_ia32_expandhi256_mask">, - Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_b_128 : - GCCBuiltin<"__builtin_ia32_expandqi128_mask">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_expand_w_128 : - GCCBuiltin<"__builtin_ia32_expandhi128_mask">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, - llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_compress : + Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], + [IntrNoMem]>; + def int_x86_avx512_mask_expand : + Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], + [IntrNoMem]>; } // truncate @@ -4502,10 +4356,6 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_qd_256 : // FIXME: Replace with trunc+select. - 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<[], @@ -4531,10 +4381,6 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_qd_512 : // FIXME: Replace with trunc+select. - 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<[], @@ -4768,10 +4614,6 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v8i16_ty, llvm_i8_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_wb_256 : // FIXME: Replace with trunc+select. - 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<[], @@ -4797,10 +4639,6 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_wb_512 : // FIXME: Replace with trunc+select. - 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<[], @@ -4834,36 +4672,64 @@ let TargetPrefix = "x86" in { GCCBuiltin<"__builtin_ia32_pternlogd128">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_pternlog_d_256 : GCCBuiltin<"__builtin_ia32_pternlogd256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_pternlog_d_512 : GCCBuiltin<"__builtin_ia32_pternlogd512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_pternlog_q_128 : GCCBuiltin<"__builtin_ia32_pternlogq128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_pternlog_q_256 : GCCBuiltin<"__builtin_ia32_pternlogq256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<3>]>; def int_x86_avx512_pternlog_q_512 : GCCBuiltin<"__builtin_ia32_pternlogq512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<3>]>; +} + +// vp2intersect +let TargetPrefix = "x86" in { + def int_x86_avx512_vp2intersect_q_512 : + Intrinsic<[llvm_v8i1_ty, llvm_v8i1_ty], + [llvm_v8i64_ty, llvm_v8i64_ty], + [IntrNoMem]>; + def int_x86_avx512_vp2intersect_q_256 : + Intrinsic<[llvm_v4i1_ty, llvm_v4i1_ty], + [llvm_v4i64_ty, llvm_v4i64_ty], + [IntrNoMem]>; + def int_x86_avx512_vp2intersect_q_128 : + Intrinsic<[llvm_v2i1_ty, llvm_v2i1_ty], + [llvm_v2i64_ty, llvm_v2i64_ty], + [IntrNoMem]>; + def int_x86_avx512_vp2intersect_d_512 : + Intrinsic<[llvm_v16i1_ty, llvm_v16i1_ty], + [llvm_v16i32_ty, llvm_v16i32_ty], + [IntrNoMem]>; + def int_x86_avx512_vp2intersect_d_256 : + Intrinsic<[llvm_v8i1_ty, llvm_v8i1_ty], + [llvm_v8i32_ty, llvm_v8i32_ty], + [IntrNoMem]>; + def int_x86_avx512_vp2intersect_d_128 : + Intrinsic<[llvm_v4i1_ty, llvm_v4i1_ty], + [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; } @@ -4873,31 +4739,35 @@ let TargetPrefix = "x86" in { // distinction in signaling behaviour is not implemented. def int_x86_avx512_cmp_ps_512 : Intrinsic<[llvm_v16i1_ty], [llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<3>]>; def int_x86_avx512_cmp_pd_512 : Intrinsic<[llvm_v8i1_ty], [llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<3>]>; def int_x86_avx512_cmp_ps_256 : Intrinsic<[llvm_v8i1_ty], [llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cmp_pd_256 : Intrinsic<[llvm_v4i1_ty], [llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cmp_ps_128 : Intrinsic<[llvm_v4i1_ty], [llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; def int_x86_avx512_cmp_pd_128 : Intrinsic<[llvm_v2i1_ty], [llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i32_ty], [IntrNoMem]>; + llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; 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]>; + llvm_i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<4>]>; 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]>; + llvm_i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<2>, ImmArg<4>]>; } //===----------------------------------------------------------------------===// @@ -4905,7 +4775,7 @@ let TargetPrefix = "x86" in { let TargetPrefix = "x86" in { def int_x86_sha1rnds4 : GCCBuiltin<"__builtin_ia32_sha1rnds4">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; + [IntrNoMem, ImmArg<2>]>; def int_x86_sha1nexte : GCCBuiltin<"__builtin_ia32_sha1nexte">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; def int_x86_sha1msg1 : GCCBuiltin<"__builtin_ia32_sha1msg1">, @@ -5000,3 +4870,51 @@ let TargetPrefix = "x86" in { def int_x86_invpcid : GCCBuiltin<"__builtin_ia32_invpcid">, Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], []>; } + +let TargetPrefix = "x86" in { + def int_x86_avx512bf16_cvtne2ps2bf16_128: + GCCBuiltin<"__builtin_ia32_cvtne2ps2bf16_128">, + Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_v4f32_ty], + [IntrNoMem]>; + def int_x86_avx512bf16_cvtne2ps2bf16_256: + GCCBuiltin<"__builtin_ia32_cvtne2ps2bf16_256">, + Intrinsic<[llvm_v16i16_ty], [llvm_v8f32_ty, llvm_v8f32_ty], + [IntrNoMem]>; + def int_x86_avx512bf16_cvtne2ps2bf16_512: + GCCBuiltin<"__builtin_ia32_cvtne2ps2bf16_512">, + Intrinsic<[llvm_v32i16_ty], [llvm_v16f32_ty, llvm_v16f32_ty], + [IntrNoMem]>; + // Intrinsic must be masked due to it producing less than 128 bits of results. + def int_x86_avx512bf16_mask_cvtneps2bf16_128: + Intrinsic<[llvm_v8i16_ty], + [llvm_v4f32_ty, llvm_v8i16_ty, llvm_v4i1_ty], + [IntrNoMem]>; + def int_x86_avx512bf16_cvtneps2bf16_256: + GCCBuiltin<"__builtin_ia32_cvtneps2bf16_256">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty], [IntrNoMem]>; + def int_x86_avx512bf16_cvtneps2bf16_512: + GCCBuiltin<"__builtin_ia32_cvtneps2bf16_512">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16f32_ty], [IntrNoMem]>; + def int_x86_avx512bf16_dpbf16ps_128: + GCCBuiltin<"__builtin_ia32_dpbf16ps_128">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512bf16_dpbf16ps_256: + GCCBuiltin<"__builtin_ia32_dpbf16ps_256">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512bf16_dpbf16ps_512: + GCCBuiltin<"__builtin_ia32_dpbf16ps_512">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_v16i32_ty], [IntrNoMem]>; +} + +//===----------------------------------------------------------------------===// +// ENQCMD - Enqueue Stores Instructions + +let TargetPrefix = "x86" in { + def int_x86_enqcmd : GCCBuiltin<"__builtin_ia32_enqcmd">, + Intrinsic<[llvm_i8_ty], [llvm_ptr_ty, llvm_ptr_ty], []>; + def int_x86_enqcmds : GCCBuiltin<"__builtin_ia32_enqcmds">, + Intrinsic<[llvm_i8_ty], [llvm_ptr_ty, llvm_ptr_ty], []>; +} diff --git a/include/llvm/IR/IntrinsicsXCore.td b/include/llvm/IR/IntrinsicsXCore.td index b614e1ed6ec0..7fe8bdfd3bd0 100644 --- a/include/llvm/IR/IntrinsicsXCore.td +++ b/include/llvm/IR/IntrinsicsXCore.td @@ -1,9 +1,8 @@ //==- IntrinsicsXCore.td - XCore intrinsics -*- tablegen -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index bd7097b39a3e..c80504500418 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -1,9 +1,8 @@ //===- llvm/LLVMContext.h - Class for managing "global" state ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -36,12 +35,8 @@ template <typename T> class SmallVectorImpl; class SMDiagnostic; class StringRef; class Twine; - -namespace yaml { - -class Output; - -} // end namespace yaml +class RemarkStreamer; +class raw_ostream; namespace SyncScope { @@ -103,6 +98,8 @@ public: MD_callees = 23, // "callees" MD_irr_loop = 24, // "irr_loop" MD_access_group = 25, // "llvm.access.group" + MD_callback = 26, // "callback" + MD_preserve_access_index = 27, // "llvm.preserve.*.access.index" }; /// Known operand bundle tag IDs, which always have the same value. All @@ -246,16 +243,23 @@ public: /// included in optimization diagnostics. void setDiagnosticsHotnessThreshold(uint64_t Threshold); - /// Return the YAML file used by the backend to save optimization - /// diagnostics. If null, diagnostics are not saved in a file but only - /// emitted via the diagnostic handler. - yaml::Output *getDiagnosticsOutputFile(); - /// Set the diagnostics output file used for optimization diagnostics. + /// Return the streamer used by the backend to save remark diagnostics. If it + /// does not exist, diagnostics are not saved in a file but only emitted via + /// the diagnostic handler. + RemarkStreamer *getRemarkStreamer(); + const RemarkStreamer *getRemarkStreamer() const; + + /// Set the diagnostics output used for optimization diagnostics. + /// This filename may be embedded in a section for tools to find the + /// diagnostics whenever they're needed. + /// + /// If a remark streamer is already set, it will be replaced with + /// \p RemarkStreamer. /// - /// By default or if invoked with null, diagnostics are not saved in a file - /// but only emitted via the diagnostic handler. Even if an output file is - /// set, the handler is invoked for each diagnostic message. - void setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F); + /// By default, diagnostics are not saved in a file but only emitted via the + /// diagnostic handler. Even if an output file is set, the handler is invoked + /// for each diagnostic message. + void setRemarkStreamer(std::unique_ptr<RemarkStreamer> RemarkStreamer); /// Get the prefix that should be printed in front of a diagnostic of /// the given \p Severity diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h index 5257a0eed488..d6bb79ab6019 100644 --- a/include/llvm/IR/LegacyPassManager.h +++ b/include/llvm/IR/LegacyPassManager.h @@ -1,9 +1,8 @@ //===- LegacyPassManager.h - Legacy Container for Passes --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/LegacyPassManagers.h b/include/llvm/IR/LegacyPassManagers.h index 51a2eb2a146d..72bc80fb5381 100644 --- a/include/llvm/IR/LegacyPassManagers.h +++ b/include/llvm/IR/LegacyPassManagers.h @@ -1,9 +1,8 @@ //===- LegacyPassManagers.h - Legacy Pass Infrastructure --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h index 4cec08196408..30820e750350 100644 --- a/include/llvm/IR/LegacyPassNameParser.h +++ b/include/llvm/IR/LegacyPassNameParser.h @@ -1,9 +1,8 @@ //===- LegacyPassNameParser.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h index 174616c7ab1d..3a2b1bddf45d 100644 --- a/include/llvm/IR/MDBuilder.h +++ b/include/llvm/IR/MDBuilder.h @@ -1,9 +1,8 @@ //===---- llvm/MDBuilder.h - Builder for LLVM metadata ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -95,6 +94,17 @@ public: MDNode *createCallees(ArrayRef<Function *> Callees); //===------------------------------------------------------------------===// + // Callback metadata. + //===------------------------------------------------------------------===// + + /// Return metadata describing a callback (see llvm::AbstractCallSite). + MDNode *createCallbackEncoding(unsigned CalleeArgNo, ArrayRef<int> Arguments, + bool VarArgsArePassed); + + /// Merge the new callback encoding \p NewCB into \p ExistingCallbacks. + MDNode *mergeCallbackEncodings(MDNode *ExistingCallbacks, MDNode *NewCB); + + //===------------------------------------------------------------------===// // AA metadata. //===------------------------------------------------------------------===// diff --git a/include/llvm/IR/Mangler.h b/include/llvm/IR/Mangler.h index 0261c00f524c..e4a05ab46a65 100644 --- a/include/llvm/IR/Mangler.h +++ b/include/llvm/IR/Mangler.h @@ -1,9 +1,8 @@ //===-- llvm/IR/Mangler.h - Self-contained name mangler ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def index 70a03f28b488..1df60cadac08 100644 --- a/include/llvm/IR/Metadata.def +++ b/include/llvm/IR/Metadata.def @@ -1,9 +1,8 @@ //===- llvm/IR/Metadata.def - Metadata definitions --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -114,6 +113,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock) #undef HANDLE_METADATA #undef HANDLE_METADATA_LEAF diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index be82c4efc115..7ca2540181ba 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -1,9 +1,8 @@ //===- llvm/IR/Metadata.h - Metadata definitions ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 9ef35f1f73cd..f458680cfe15 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -1,9 +1,8 @@ //===- llvm/Module.h - C++ class to represent a VM module -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -29,6 +28,7 @@ #include "llvm/IR/GlobalIFunc.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/ProfileSummary.h" #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/CodeGen.h" @@ -333,16 +333,18 @@ public: /// Look up the specified function in the module symbol table. Four /// possibilities: /// 1. If it does not exist, add a prototype for the function and return it. - /// 2. If it exists, and has a local linkage, the existing function is - /// renamed and a new one is inserted. - /// 3. Otherwise, if the existing function has the correct prototype, return + /// 2. Otherwise, if the existing function has the correct prototype, return /// the existing function. - /// 4. Finally, the function exists but has the wrong prototype: return the + /// 3. Finally, the function exists but has the wrong prototype: return the /// function with a constantexpr cast to the right prototype. - Constant *getOrInsertFunction(StringRef Name, FunctionType *T, - AttributeList AttributeList); + /// + /// In all cases, the returned value is a FunctionCallee wrapper around the + /// 'FunctionType *T' passed in, as well as a 'Value*' either of the Function or + /// the bitcast to the function. + FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, + AttributeList AttributeList); - Constant *getOrInsertFunction(StringRef Name, FunctionType *T); + FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T); /// Look up the specified function in the module symbol table. If it does not /// exist, add a prototype for the function and return it. This function @@ -350,11 +352,10 @@ public: /// or a ConstantExpr BitCast of that type if the named function has a /// different type. This version of the method takes a list of /// function arguments, which makes it easier for clients to use. - template<typename... ArgsTy> - Constant *getOrInsertFunction(StringRef Name, - AttributeList AttributeList, - Type *RetTy, ArgsTy... Args) - { + template <typename... ArgsTy> + FunctionCallee getOrInsertFunction(StringRef Name, + AttributeList AttributeList, Type *RetTy, + ArgsTy... Args) { SmallVector<Type*, sizeof...(ArgsTy)> ArgTys{Args...}; return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false), @@ -362,15 +363,17 @@ public: } /// Same as above, but without the attributes. - template<typename... ArgsTy> - Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ArgsTy... Args) { + template <typename... ArgsTy> + FunctionCallee getOrInsertFunction(StringRef Name, Type *RetTy, + ArgsTy... Args) { return getOrInsertFunction(Name, AttributeList{}, RetTy, Args...); } // Avoid an incorrect ordering that'd otherwise compile incorrectly. template <typename... ArgsTy> - Constant *getOrInsertFunction(StringRef Name, AttributeList AttributeList, - FunctionType *Invalid, ArgsTy... Args) = delete; + FunctionCallee + getOrInsertFunction(StringRef Name, AttributeList AttributeList, + FunctionType *Invalid, ArgsTy... Args) = delete; /// Look up the specified function in the module symbol table. If it does not /// exist, return null. @@ -866,10 +869,11 @@ public: /// @{ /// Attach profile summary metadata to this module. - void setProfileSummary(Metadata *M); + void setProfileSummary(Metadata *M, ProfileSummary::Kind Kind); - /// Returns profile summary metadata - Metadata *getProfileSummary(); + /// Returns profile summary metadata. When IsCS is true, use the context + /// sensitive profile summary. + Metadata *getProfileSummary(bool IsCS); /// @} /// Returns true if PLT should be avoided for RTLib calls. diff --git a/include/llvm/IR/ModuleSlotTracker.h b/include/llvm/IR/ModuleSlotTracker.h index eb26fba906ea..85f8ff938366 100644 --- a/include/llvm/IR/ModuleSlotTracker.h +++ b/include/llvm/IR/ModuleSlotTracker.h @@ -1,9 +1,8 @@ //===-- llvm/IR/ModuleSlotTracker.h -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index a1acee494475..aacf8cfc089f 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -1,9 +1,8 @@ //===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -120,7 +119,7 @@ class GlobalValueSummary; using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>; -struct GlobalValueSummaryInfo { +struct LLVM_ALIGNAS(8) GlobalValueSummaryInfo { union NameOrGV { NameOrGV(bool HaveGVs) { if (HaveGVs) @@ -163,7 +162,8 @@ using GlobalValueSummaryMapTy = /// Struct that holds a reference to a particular GUID in a global value /// summary. struct ValueInfo { - PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 2, int> + enum Flags { HaveGV = 1, ReadOnly = 2, WriteOnly = 4 }; + PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 3, int> RefAndFlags; ValueInfo() = default; @@ -189,15 +189,42 @@ struct ValueInfo { : getRef()->second.U.Name; } - bool haveGVs() const { return RefAndFlags.getInt() & 0x1; } - bool isReadOnly() const { return RefAndFlags.getInt() & 0x2; } - void setReadOnly() { RefAndFlags.setInt(RefAndFlags.getInt() | 0x2); } + bool haveGVs() const { return RefAndFlags.getInt() & HaveGV; } + bool isReadOnly() const { + assert(isValidAccessSpecifier()); + return RefAndFlags.getInt() & ReadOnly; + } + bool isWriteOnly() const { + assert(isValidAccessSpecifier()); + return RefAndFlags.getInt() & WriteOnly; + } + unsigned getAccessSpecifier() const { + assert(isValidAccessSpecifier()); + return RefAndFlags.getInt() & (ReadOnly | WriteOnly); + } + bool isValidAccessSpecifier() const { + unsigned BadAccessMask = ReadOnly | WriteOnly; + return (RefAndFlags.getInt() & BadAccessMask) != BadAccessMask; + } + void setReadOnly() { + // We expect ro/wo attribute to set only once during + // ValueInfo lifetime. + assert(getAccessSpecifier() == 0); + RefAndFlags.setInt(RefAndFlags.getInt() | ReadOnly); + } + void setWriteOnly() { + assert(getAccessSpecifier() == 0); + RefAndFlags.setInt(RefAndFlags.getInt() | WriteOnly); + } const GlobalValueSummaryMapTy::value_type *getRef() const { return RefAndFlags.getPointer(); } bool isDSOLocal() const; + + /// Checks if all copies are eligible for auto-hiding (have flag set). + bool canAutoHide() const; }; inline raw_ostream &operator<<(raw_ostream &OS, const ValueInfo &VI) { @@ -280,11 +307,23 @@ public: /// within the same linkage unit. unsigned DSOLocal : 1; + /// In the per-module summary, indicates that the global value is + /// linkonce_odr and global unnamed addr (so eligible for auto-hiding + /// via hidden visibility). In the combined summary, indicates that the + /// prevailing linkonce_odr copy can be auto-hidden via hidden visibility + /// when it is upgraded to weak_odr in the backend. This is legal when + /// all copies are eligible for auto-hiding (i.e. all copies were + /// linkonce_odr global unnamed addr. If any copy is not (e.g. it was + /// originally weak_odr, we cannot auto-hide the prevailing copy as it + /// means the symbol was externally visible. + unsigned CanAutoHide : 1; + /// Convenience Constructors explicit GVFlags(GlobalValue::LinkageTypes Linkage, - bool NotEligibleToImport, bool Live, bool IsLocal) + bool NotEligibleToImport, bool Live, bool IsLocal, + bool CanAutoHide) : Linkage(Linkage), NotEligibleToImport(NotEligibleToImport), - Live(Live), DSOLocal(IsLocal) {} + Live(Live), DSOLocal(IsLocal), CanAutoHide(CanAutoHide) {} }; private: @@ -365,6 +404,10 @@ public: bool isDSOLocal() const { return Flags.DSOLocal; } + void setCanAutoHide(bool CanAutoHide) { Flags.CanAutoHide = CanAutoHide; } + + bool canAutoHide() const { return Flags.CanAutoHide; } + /// Flag that this global value cannot be imported. void setNotEligibleToImport() { Flags.NotEligibleToImport = true; } @@ -381,25 +424,35 @@ public: /// Alias summary information. class AliasSummary : public GlobalValueSummary { + ValueInfo AliaseeValueInfo; + + /// This is the Aliasee in the same module as alias (could get from VI, trades + /// memory for time). Note that this pointer may be null (and the value info + /// empty) when we have a distributed index where the alias is being imported + /// (as a copy of the aliasee), but the aliasee is not. GlobalValueSummary *AliaseeSummary; - // AliaseeGUID is only set and accessed when we are building a combined index - // via the BitcodeReader. - GlobalValue::GUID AliaseeGUID; public: AliasSummary(GVFlags Flags) : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}), - AliaseeSummary(nullptr), AliaseeGUID(0) {} + AliaseeSummary(nullptr) {} /// Check if this is an alias summary. static bool classof(const GlobalValueSummary *GVS) { return GVS->getSummaryKind() == AliasKind; } - void setAliasee(GlobalValueSummary *Aliasee) { AliaseeSummary = Aliasee; } - void setAliaseeGUID(GlobalValue::GUID GUID) { AliaseeGUID = GUID; } + void setAliasee(ValueInfo &AliaseeVI, GlobalValueSummary *Aliasee) { + AliaseeValueInfo = AliaseeVI; + AliaseeSummary = Aliasee; + } - bool hasAliasee() const { return !!AliaseeSummary; } + bool hasAliasee() const { + assert(!!AliaseeSummary == (AliaseeValueInfo && + !AliaseeValueInfo.getSummaryList().empty()) && + "Expect to have both aliasee summary and summary list or neither"); + return !!AliaseeSummary; + } const GlobalValueSummary &getAliasee() const { assert(AliaseeSummary && "Unexpected missing aliasee summary"); @@ -410,10 +463,13 @@ public: return const_cast<GlobalValueSummary &>( static_cast<const AliasSummary *>(this)->getAliasee()); } - bool hasAliaseeGUID() const { return AliaseeGUID != 0; } - const GlobalValue::GUID &getAliaseeGUID() const { - assert(AliaseeGUID && "Unexpected missing aliasee GUID"); - return AliaseeGUID; + ValueInfo getAliaseeVI() const { + assert(AliaseeValueInfo && "Unexpected missing aliasee"); + return AliaseeValueInfo; + } + GlobalValue::GUID getAliaseeGUID() const { + assert(AliaseeValueInfo && "Unexpected missing aliasee"); + return AliaseeValueInfo.getGUID(); } }; @@ -500,7 +556,8 @@ public: return FunctionSummary( FunctionSummary::GVFlags( GlobalValue::LinkageTypes::AvailableExternallyLinkage, - /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false), + /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false, + /*CanAutoHide=*/false), /*InsCount=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, std::vector<ValueInfo>(), std::move(Edges), std::vector<GlobalValue::GUID>(), @@ -552,8 +609,8 @@ public: std::move(TypeTestAssumeConstVCalls), std::move(TypeCheckedLoadConstVCalls)}); } - // Gets the number of immutable refs in RefEdgeList - unsigned immutableRefCount() const; + // Gets the number of readonly and writeonly refs in RefEdgeList + std::pair<unsigned, unsigned> specialRefCounts() const; /// Check if this is a function summary. static bool classof(const GlobalValueSummary *GVS) { @@ -666,18 +723,43 @@ template <> struct DenseMapInfo<FunctionSummary::ConstVCall> { } }; +/// The ValueInfo and offset for a function within a vtable definition +/// initializer array. +struct VirtFuncOffset { + VirtFuncOffset(ValueInfo VI, uint64_t Offset) + : FuncVI(VI), VTableOffset(Offset) {} + + ValueInfo FuncVI; + uint64_t VTableOffset; +}; +/// List of functions referenced by a particular vtable definition. +using VTableFuncList = std::vector<VirtFuncOffset>; + /// Global variable summary information to aid decisions and /// implementation of importing. /// -/// Global variable summary has extra flag, telling if it is -/// modified during the program run or not. This affects ThinLTO -/// internalization +/// Global variable summary has two extra flag, telling if it is +/// readonly or writeonly. Both readonly and writeonly variables +/// can be optimized in the backed: readonly variables can be +/// const-folded, while writeonly vars can be completely eliminated +/// together with corresponding stores. We let both things happen +/// by means of internalizing such variables after ThinLTO import. class GlobalVarSummary : public GlobalValueSummary { +private: + /// For vtable definitions this holds the list of functions and + /// their corresponding offsets within the initializer array. + std::unique_ptr<VTableFuncList> VTableFuncs; + public: struct GVarFlags { - GVarFlags(bool ReadOnly = false) : ReadOnly(ReadOnly) {} - - unsigned ReadOnly : 1; + GVarFlags(bool ReadOnly, bool WriteOnly) + : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly) {} + + // In permodule summaries both MaybeReadOnly and MaybeWriteOnly + // bits are set, because attribute propagation occurs later on + // thin link phase. + unsigned MaybeReadOnly : 1; + unsigned MaybeWriteOnly : 1; } VarFlags; GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags, @@ -691,8 +773,21 @@ public: } GVarFlags varflags() const { return VarFlags; } - void setReadOnly(bool RO) { VarFlags.ReadOnly = RO; } - bool isReadOnly() const { return VarFlags.ReadOnly; } + void setReadOnly(bool RO) { VarFlags.MaybeReadOnly = RO; } + void setWriteOnly(bool WO) { VarFlags.MaybeWriteOnly = WO; } + bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; } + bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; } + + void setVTableFuncs(VTableFuncList Funcs) { + assert(!VTableFuncs); + VTableFuncs = llvm::make_unique<VTableFuncList>(std::move(Funcs)); + } + + ArrayRef<VirtFuncOffset> vTableFuncs() const { + if (VTableFuncs) + return *VTableFuncs; + return {}; + } }; struct TypeTestResolution { @@ -791,6 +886,29 @@ using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>; using TypeIdSummaryMapTy = std::multimap<GlobalValue::GUID, std::pair<std::string, TypeIdSummary>>; +/// The following data structures summarize type metadata information. +/// For type metadata overview see https://llvm.org/docs/TypeMetadata.html. +/// Each type metadata includes both the type identifier and the offset of +/// the address point of the type (the address held by objects of that type +/// which may not be the beginning of the virtual table). Vtable definitions +/// are decorated with type metadata for the types they are compatible with. +/// +/// Holds information about vtable definitions decorated with type metadata: +/// the vtable definition value and its address point offset in a type +/// identifier metadata it is decorated (compatible) with. +struct TypeIdOffsetVtableInfo { + TypeIdOffsetVtableInfo(uint64_t Offset, ValueInfo VI) + : AddressPointOffset(Offset), VTableVI(VI) {} + + uint64_t AddressPointOffset; + ValueInfo VTableVI; +}; +/// List of vtable definitions decorated by a particular type identifier, +/// and their corresponding offsets in that type identifier's metadata. +/// Note that each type identifier may be compatible with multiple vtables, due +/// to inheritance, which is why this is a vector. +using TypeIdCompatibleVtableInfo = std::vector<TypeIdOffsetVtableInfo>; + /// Class to hold module path string table and global value map, /// and encapsulate methods for operating on them. class ModuleSummaryIndex { @@ -803,9 +921,15 @@ private: ModulePathStringTableTy ModulePathStringTable; /// Mapping from type identifier GUIDs to type identifier and its summary - /// information. + /// information. Produced by thin link. TypeIdSummaryMapTy TypeIdMap; + /// Mapping from type identifier to information about vtables decorated + /// with that type identifier's metadata. Produced by per module summary + /// analysis and consumed by thin link. For more information, see description + /// above where TypeIdCompatibleVtableInfo is defined. + std::map<std::string, TypeIdCompatibleVtableInfo> TypeIdCompatibleVtableMap; + /// Mapping from original ID to GUID. If original ID can map to multiple /// GUIDs, it will be mapped to 0. std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap; @@ -1044,24 +1168,30 @@ public: OidGuidMap[OrigGUID] = ValueGUID; } - /// Find the summary for global \p GUID in module \p ModuleId, or nullptr if + /// Find the summary for ValueInfo \p VI in module \p ModuleId, or nullptr if /// not found. - GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID, - StringRef ModuleId) const { - auto CalleeInfo = getValueInfo(ValueGUID); - if (!CalleeInfo) { - return nullptr; // This function does not have a summary - } + GlobalValueSummary *findSummaryInModule(ValueInfo VI, StringRef ModuleId) const { + auto SummaryList = VI.getSummaryList(); auto Summary = - llvm::find_if(CalleeInfo.getSummaryList(), + llvm::find_if(SummaryList, [&](const std::unique_ptr<GlobalValueSummary> &Summary) { return Summary->modulePath() == ModuleId; }); - if (Summary == CalleeInfo.getSummaryList().end()) + if (Summary == SummaryList.end()) return nullptr; return Summary->get(); } + /// Find the summary for global \p GUID in module \p ModuleId, or nullptr if + /// not found. + GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID, + StringRef ModuleId) const { + auto CalleeInfo = getValueInfo(ValueGUID); + if (!CalleeInfo) + return nullptr; // This function does not have a summary + return findSummaryInModule(CalleeInfo, ModuleId); + } + /// Returns the first GlobalValueSummary for \p GV, asserting that there /// is only one if \p PerModuleIndex. GlobalValueSummary *getGlobalValueSummary(const GlobalValue &GV, @@ -1163,6 +1293,29 @@ public: return nullptr; } + const std::map<std::string, TypeIdCompatibleVtableInfo> & + typeIdCompatibleVtableMap() const { + return TypeIdCompatibleVtableMap; + } + + /// Return an existing or new TypeIdCompatibleVtableMap entry for \p TypeId. + /// This accessor can mutate the map and therefore should not be used in + /// the ThinLTO backends. + TypeIdCompatibleVtableInfo & + getOrInsertTypeIdCompatibleVtableSummary(StringRef TypeId) { + return TypeIdCompatibleVtableMap[TypeId]; + } + + /// For the given \p TypeId, this returns the TypeIdCompatibleVtableMap + /// entry if present in the summary map. This may be used when importing. + Optional<TypeIdCompatibleVtableInfo> + getTypeIdCompatibleVtableSummary(StringRef TypeId) const { + auto I = TypeIdCompatibleVtableMap.find(TypeId); + if (I == TypeIdCompatibleVtableMap.end()) + return None; + return I->second; + } + /// Collect for the given module the list of functions it defines /// (GUID -> Summary). void collectDefinedFunctionsForModule(StringRef ModulePath, @@ -1170,8 +1323,16 @@ public: /// Collect for each module the list of Summaries it defines (GUID -> /// Summary). - void collectDefinedGVSummariesPerModule( - StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const; + template <class Map> + void + collectDefinedGVSummariesPerModule(Map &ModuleToDefinedGVSummaries) const { + for (auto &GlobalList : *this) { + auto GUID = GlobalList.first; + for (auto &Summary : GlobalList.second.SummaryList) { + ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get(); + } + } + } /// Print to an output stream. void print(raw_ostream &OS, bool IsForDebug = false) const; @@ -1186,7 +1347,7 @@ public: void dumpSCCs(raw_ostream &OS); /// Analyze index and detect unmodified globals - void propagateConstants(const DenseSet<GlobalValue::GUID> &PreservedSymbols); + void propagateAttributes(const DenseSet<GlobalValue::GUID> &PreservedSymbols); }; /// GraphTraits definition to build SCC for the index diff --git a/include/llvm/IR/ModuleSummaryIndexYAML.h b/include/llvm/IR/ModuleSummaryIndexYAML.h index a88ee26b51c3..26d9c43fabf1 100644 --- a/include/llvm/IR/ModuleSummaryIndexYAML.h +++ b/include/llvm/IR/ModuleSummaryIndexYAML.h @@ -1,9 +1,8 @@ //===-- llvm/ModuleSummaryIndexYAML.h - YAML I/O for summary ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -137,7 +136,7 @@ template <> struct MappingTraits<TypeIdSummary> { struct FunctionSummaryYaml { unsigned Linkage; - bool NotEligibleToImport, Live, IsLocal; + bool NotEligibleToImport, Live, IsLocal, CanAutoHide; std::vector<uint64_t> Refs; std::vector<uint64_t> TypeTests; std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls, @@ -181,6 +180,7 @@ template <> struct MappingTraits<FunctionSummaryYaml> { io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport); io.mapOptional("Live", summary.Live); io.mapOptional("Local", summary.IsLocal); + io.mapOptional("CanAutoHide", summary.CanAutoHide); io.mapOptional("Refs", summary.Refs); io.mapOptional("TypeTests", summary.TypeTests); io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls); @@ -223,7 +223,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>( GlobalValueSummary::GVFlags( static_cast<GlobalValue::LinkageTypes>(FSum.Linkage), - FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal), + FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal, FSum.CanAutoHide), /*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, Refs, ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests), std::move(FSum.TypeTestAssumeVCalls), @@ -244,7 +244,8 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { FSum->flags().Linkage, static_cast<bool>(FSum->flags().NotEligibleToImport), static_cast<bool>(FSum->flags().Live), - static_cast<bool>(FSum->flags().DSOLocal), Refs, + static_cast<bool>(FSum->flags().DSOLocal), + static_cast<bool>(FSum->flags().CanAutoHide), Refs, FSum->type_tests(), FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(), FSum->type_test_assume_const_vcalls(), diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h index def07ffe2ff6..0e3c19f4947f 100644 --- a/include/llvm/IR/NoFolder.h +++ b/include/llvm/IR/NoFolder.h @@ -1,9 +1,8 @@ //===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -204,6 +203,10 @@ public: return BinaryOperator::CreateNot(C); } + Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return UnaryOperator::Create(Opc, C); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/OperandTraits.h b/include/llvm/IR/OperandTraits.h index c618aff3df9a..979ad35019f8 100644 --- a/include/llvm/IR/OperandTraits.h +++ b/include/llvm/IR/OperandTraits.h @@ -1,9 +1,8 @@ //===-- llvm/OperandTraits.h - OperandTraits class definition ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 6b387bbcccb1..8199c65ca8a0 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -1,9 +1,8 @@ //===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -188,6 +187,12 @@ public: FastMathFlags() = default; + static FastMathFlags getFast() { + FastMathFlags FMF; + FMF.setFast(); + return FMF; + } + bool any() const { return Flags != 0; } bool none() const { return Flags == 0; } bool all() const { return Flags == ~0U; } @@ -380,6 +385,7 @@ public: case Instruction::ExtractElement: case Instruction::ShuffleVector: case Instruction::InsertElement: + case Instruction::PHI: return false; default: return V->getType()->isFPOrFPVectorTy(); diff --git a/include/llvm/IR/OptBisect.h b/include/llvm/IR/OptBisect.h index aa24c94c0130..1b2b0bd7acaa 100644 --- a/include/llvm/IR/OptBisect.h +++ b/include/llvm/IR/OptBisect.h @@ -1,9 +1,8 @@ //===- llvm/IR/OptBisect.h - LLVM Bisect support ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -20,12 +19,6 @@ namespace llvm { class Pass; -class Module; -class Function; -class BasicBlock; -class Region; -class Loop; -class CallGraphSCC; /// Extensions to this class implement mechanisms to disable passes and /// individual optimizations at compile time. @@ -33,12 +26,14 @@ class OptPassGate { public: virtual ~OptPassGate() = default; - virtual bool shouldRunPass(const Pass *P, const Module &U) { return true; } - virtual bool shouldRunPass(const Pass *P, const Function &U) {return true; } - virtual bool shouldRunPass(const Pass *P, const BasicBlock &U) { return true; } - virtual bool shouldRunPass(const Pass *P, const Region &U) { return true; } - virtual bool shouldRunPass(const Pass *P, const Loop &U) { return true; } - virtual bool shouldRunPass(const Pass *P, const CallGraphSCC &U) { return true; } + /// IRDescription is a textual description of the IR unit the pass is running + /// over. + virtual bool shouldRunPass(const Pass *P, StringRef IRDescription) { + return true; + } + + /// isEnabled should return true before calling shouldRunPass + virtual bool isEnabled() const { return false; } }; /// This class implements a mechanism to disable passes and individual @@ -60,23 +55,19 @@ public: /// Checks the bisect limit to determine if the specified pass should run. /// - /// These functions immediately return true if bisection is disabled. If the - /// bisect limit is set to -1, the functions print a message describing + /// If the bisect limit is set to -1, the function prints a message describing /// the pass and the bisect number assigned to it and return true. Otherwise, - /// the functions print a message with the bisect number assigned to the + /// the function prints a message with the bisect number assigned to the /// pass and indicating whether or not the pass will be run and return true if /// the bisect limit has not yet been exceeded or false if it has. /// - /// Most passes should not call these routines directly. Instead, they are + /// Most passes should not call this routine directly. Instead, they are /// called through helper routines provided by the pass base classes. For /// instance, function passes should call FunctionPass::skipFunction(). - bool shouldRunPass(const Pass *P, const Module &U) override; - bool shouldRunPass(const Pass *P, const Function &U) override; - bool shouldRunPass(const Pass *P, const BasicBlock &U) override; - bool shouldRunPass(const Pass *P, const Region &U) override; - bool shouldRunPass(const Pass *P, const Loop &U) override; - bool shouldRunPass(const Pass *P, const CallGraphSCC &U) override; + bool shouldRunPass(const Pass *P, StringRef IRDescription) override; + /// isEnabled should return true before calling shouldRunPass + bool isEnabled() const override { return BisectEnabled; } private: bool checkPass(const StringRef PassName, const StringRef TargetDesc); diff --git a/include/llvm/IR/PassInstrumentation.h b/include/llvm/IR/PassInstrumentation.h index 08dac1c4a274..f8a1196871cf 100644 --- a/include/llvm/IR/PassInstrumentation.h +++ b/include/llvm/IR/PassInstrumentation.h @@ -1,9 +1,8 @@ //===- llvm/IR/PassInstrumentation.h ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 738a2242eea0..37fe2a5b01ad 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -1,9 +1,8 @@ //===- PassManager.h - Pass management infrastructure -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -287,6 +286,13 @@ public: PA.PreservedIDs.count(ID)); } + /// Return true if the checker's analysis was not abandoned, i.e. it was not + /// explicitly invalidated. Even if the analysis is not explicitly + /// preserved, if the analysis is known stateless, then it is preserved. + bool preservedWhenStateless() { + return !IsAbandoned; + } + /// Returns true if the checker's analysis was not abandoned and either /// - \p AnalysisSetT is explicitly preserved or /// - all analyses are preserved. diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h index 5ad68be62742..58198bf67b11 100644 --- a/include/llvm/IR/PassManagerInternal.h +++ b/include/llvm/IR/PassManagerInternal.h @@ -1,9 +1,8 @@ //===- PassManager internal APIs and implementation details -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/IR/PassTimingInfo.h b/include/llvm/IR/PassTimingInfo.h index e9945f997f43..b8d8f117f73d 100644 --- a/include/llvm/IR/PassTimingInfo.h +++ b/include/llvm/IR/PassTimingInfo.h @@ -1,9 +1,8 @@ //===- PassTimingInfo.h - pass execution timing -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -27,10 +26,12 @@ namespace llvm { class Pass; class PassInstrumentationCallbacks; +class raw_ostream; /// If -time-passes has been specified, report the timings immediately and then -/// reset the timers to zero. -void reportAndResetTimings(); +/// reset the timers to zero. By default it uses the stream created by +/// CreateInfoOutputFile(). +void reportAndResetTimings(raw_ostream *OutStream = nullptr); /// Request the timer for this legacy-pass-manager's pass instance. Timer *getPassTimer(Pass *); @@ -63,18 +64,18 @@ class TimePassesHandler { /// Stack of currently active timers. SmallVector<Timer *, 8> TimerStack; + /// Custom output stream to print timing information into. + /// By default (== nullptr) we emit time report into the stream created by + /// CreateInfoOutputFile(). + raw_ostream *OutStream = nullptr; + bool Enabled; public: TimePassesHandler(bool Enabled = TimePassesIsEnabled); /// Destructor handles the print action if it has not been handled before. - ~TimePassesHandler() { - // First destroying the timers from TimingData, which deploys all their - // collected data into the TG time group member, which later prints itself - // when being destroyed. - TimingData.clear(); - } + ~TimePassesHandler() { print(); } /// Prints out timing information and then resets the timers. void print(); @@ -85,6 +86,9 @@ public: void registerCallbacks(PassInstrumentationCallbacks &PIC); + /// Set a custom output stream for subsequent reporting. + void setOutStream(raw_ostream &OutStream); + private: /// Dumps information for running/triggered timers, useful for debugging LLVM_DUMP_METHOD void dump() const; diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 120fc253b908..0f03d7cc56b8 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -1,9 +1,8 @@ //===- PatternMatch.h - Match on the LLVM IR --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -419,6 +418,46 @@ inline cst_pred_ty<is_lowbit_mask> m_LowBitMask() { return cst_pred_ty<is_lowbit_mask>(); } +struct icmp_pred_with_threshold { + ICmpInst::Predicate Pred; + const APInt *Thr; + bool isValue(const APInt &C) { + switch (Pred) { + case ICmpInst::Predicate::ICMP_EQ: + return C.eq(*Thr); + case ICmpInst::Predicate::ICMP_NE: + return C.ne(*Thr); + case ICmpInst::Predicate::ICMP_UGT: + return C.ugt(*Thr); + case ICmpInst::Predicate::ICMP_UGE: + return C.uge(*Thr); + case ICmpInst::Predicate::ICMP_ULT: + return C.ult(*Thr); + case ICmpInst::Predicate::ICMP_ULE: + return C.ule(*Thr); + case ICmpInst::Predicate::ICMP_SGT: + return C.sgt(*Thr); + case ICmpInst::Predicate::ICMP_SGE: + return C.sge(*Thr); + case ICmpInst::Predicate::ICMP_SLT: + return C.slt(*Thr); + case ICmpInst::Predicate::ICMP_SLE: + return C.sle(*Thr); + default: + llvm_unreachable("Unhandled ICmp predicate"); + } + } +}; +/// Match an integer or vector with every element comparing 'pred' (eg/ne/...) +/// to Threshold. For vectors, this includes constants with undefined elements. +inline cst_pred_ty<icmp_pred_with_threshold> +m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold) { + cst_pred_ty<icmp_pred_with_threshold> P; + P.Pred = Predicate; + P.Thr = &Threshold; + return P; +} + struct is_nan { bool isValue(const APFloat &C) { return C.isNaN(); } }; @@ -668,18 +707,26 @@ template <typename Op_t> struct FNeg_match { FNeg_match(const Op_t &Op) : X(Op) {} template <typename OpTy> bool match(OpTy *V) { auto *FPMO = dyn_cast<FPMathOperator>(V); - if (!FPMO || FPMO->getOpcode() != Instruction::FSub) - return false; - if (FPMO->hasNoSignedZeros()) { - // With 'nsz', any zero goes. - if (!cstfp_pred_ty<is_any_zero_fp>().match(FPMO->getOperand(0))) - return false; - } else { - // Without 'nsz', we need fsub -0.0, X exactly. - if (!cstfp_pred_ty<is_neg_zero_fp>().match(FPMO->getOperand(0))) - return false; + if (!FPMO) return false; + + if (FPMO->getOpcode() == Instruction::FNeg) + return X.match(FPMO->getOperand(0)); + + if (FPMO->getOpcode() == Instruction::FSub) { + if (FPMO->hasNoSignedZeros()) { + // With 'nsz', any zero goes. + if (!cstfp_pred_ty<is_any_zero_fp>().match(FPMO->getOperand(0))) + return false; + } else { + // Without 'nsz', we need fsub -0.0, X exactly. + if (!cstfp_pred_ty<is_neg_zero_fp>().match(FPMO->getOperand(0))) + return false; + } + + return X.match(FPMO->getOperand(1)); } - return X.match(FPMO->getOperand(1)); + + return false; } }; @@ -1464,6 +1511,20 @@ struct UAddWithOverflow_match { if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS)) return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); + // Match special-case for increment-by-1. + if (Pred == ICmpInst::ICMP_EQ) { + // (a + 1) == 0 + // (1 + a) == 0 + if (AddExpr.match(ICmpLHS) && m_ZeroInt().match(ICmpRHS) && + (m_One().match(AddLHS) || m_One().match(AddRHS))) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); + // 0 == (a + 1) + // 0 == (1 + a) + if (m_ZeroInt().match(ICmpLHS) && AddExpr.match(ICmpRHS) && + (m_One().match(AddLHS) || m_One().match(AddRHS))) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); + } + return false; } }; diff --git a/include/llvm/IR/PredIteratorCache.h b/include/llvm/IR/PredIteratorCache.h index 81f535311431..cc835277910b 100644 --- a/include/llvm/IR/PredIteratorCache.h +++ b/include/llvm/IR/PredIteratorCache.h @@ -1,9 +1,8 @@ //===- PredIteratorCache.h - pred_iterator Cache ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/ProfileSummary.h b/include/llvm/IR/ProfileSummary.h index e38663770a13..78635ec4386c 100644 --- a/include/llvm/IR/ProfileSummary.h +++ b/include/llvm/IR/ProfileSummary.h @@ -1,9 +1,8 @@ //===- ProfileSummary.h - Profile summary data structure. -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -43,11 +42,10 @@ using SummaryEntryVector = std::vector<ProfileSummaryEntry>; class ProfileSummary { public: - enum Kind { PSK_Instr, PSK_Sample }; + enum Kind { PSK_Instr, PSK_CSInstr, PSK_Sample }; private: const Kind PSK; - static const char *KindStr[2]; SummaryEntryVector DetailedSummary; uint64_t TotalCount, MaxCount, MaxInternalCount, MaxFunctionCount; uint32_t NumCounts, NumFunctions; diff --git a/include/llvm/IR/RemarkStreamer.h b/include/llvm/IR/RemarkStreamer.h new file mode 100644 index 000000000000..f34cc660b2fb --- /dev/null +++ b/include/llvm/IR/RemarkStreamer.h @@ -0,0 +1,96 @@ +//===- llvm/IR/RemarkStreamer.h - Remark Streamer ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the main interface for outputting remarks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_REMARKSTREAMER_H +#define LLVM_IR_REMARKSTREAMER_H + +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/Remarks/RemarkSerializer.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/raw_ostream.h" +#include <string> +#include <vector> + +namespace llvm { +/// Streamer for remarks. +class RemarkStreamer { + /// The filename that the remark diagnostics are emitted to. + const std::string Filename; + /// The regex used to filter remarks based on the passes that emit them. + Optional<Regex> PassFilter; + /// The object used to serialize the remarks to a specific format. + std::unique_ptr<remarks::Serializer> Serializer; + + /// Convert diagnostics into remark objects. + /// The lifetime of the members of the result is bound to the lifetime of + /// the LLVM diagnostics. + remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag); + +public: + RemarkStreamer(StringRef Filename, + std::unique_ptr<remarks::Serializer> Serializer); + /// Return the filename that the remark diagnostics are emitted to. + StringRef getFilename() const { return Filename; } + /// Return stream that the remark diagnostics are emitted to. + raw_ostream &getStream() { return Serializer->OS; } + /// Return the serializer used for this stream. + remarks::Serializer &getSerializer() { return *Serializer; } + /// Set a pass filter based on a regex \p Filter. + /// Returns an error if the regex is invalid. + Error setFilter(StringRef Filter); + /// Emit a diagnostic through the streamer. + void emit(const DiagnosticInfoOptimizationBase &Diag); +}; + +template <typename ThisError> +struct RemarkSetupErrorInfo : public ErrorInfo<ThisError> { + std::string Msg; + std::error_code EC; + + RemarkSetupErrorInfo(Error E) { + handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) { + Msg = EIB.message(); + EC = EIB.convertToErrorCode(); + }); + } + + void log(raw_ostream &OS) const override { OS << Msg; } + std::error_code convertToErrorCode() const override { return EC; } +}; + +struct RemarkSetupFileError : RemarkSetupErrorInfo<RemarkSetupFileError> { + static char ID; + using RemarkSetupErrorInfo<RemarkSetupFileError>::RemarkSetupErrorInfo; +}; + +struct RemarkSetupPatternError : RemarkSetupErrorInfo<RemarkSetupPatternError> { + static char ID; + using RemarkSetupErrorInfo<RemarkSetupPatternError>::RemarkSetupErrorInfo; +}; + +struct RemarkSetupFormatError : RemarkSetupErrorInfo<RemarkSetupFormatError> { + static char ID; + using RemarkSetupErrorInfo<RemarkSetupFormatError>::RemarkSetupErrorInfo; +}; + +/// Setup optimization remarks. +Expected<std::unique_ptr<ToolOutputFile>> +setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, + StringRef RemarksPasses, StringRef RemarksFormat, + bool RemarksWithHotness, + unsigned RemarksHotnessThreshold = 0); + +} // end namespace llvm + +#endif // LLVM_IR_REMARKSTREAMER_H diff --git a/include/llvm/IR/RuntimeLibcalls.def b/include/llvm/IR/RuntimeLibcalls.def index 89005120cdc1..f6c74d497b18 100644 --- a/include/llvm/IR/RuntimeLibcalls.def +++ b/include/llvm/IR/RuntimeLibcalls.def @@ -1,9 +1,8 @@ //===-- llvm/RuntimeLibcalls.def - File that describes libcalls -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -255,6 +254,26 @@ HANDLE_LIBCALL(FMAX_F64, "fmax") HANDLE_LIBCALL(FMAX_F80, "fmaxl") HANDLE_LIBCALL(FMAX_F128, "fmaxl") HANDLE_LIBCALL(FMAX_PPCF128, "fmaxl") +HANDLE_LIBCALL(LROUND_F32, "lroundf") +HANDLE_LIBCALL(LROUND_F64, "lround") +HANDLE_LIBCALL(LROUND_F80, "lroundl") +HANDLE_LIBCALL(LROUND_F128, "lroundl") +HANDLE_LIBCALL(LROUND_PPCF128, "lroundl") +HANDLE_LIBCALL(LLROUND_F32, "llroundf") +HANDLE_LIBCALL(LLROUND_F64, "llround") +HANDLE_LIBCALL(LLROUND_F80, "llroundl") +HANDLE_LIBCALL(LLROUND_F128, "llroundl") +HANDLE_LIBCALL(LLROUND_PPCF128, "llroundl") +HANDLE_LIBCALL(LRINT_F32, "lrintf") +HANDLE_LIBCALL(LRINT_F64, "lrint") +HANDLE_LIBCALL(LRINT_F80, "lrintl") +HANDLE_LIBCALL(LRINT_F128, "lrintl") +HANDLE_LIBCALL(LRINT_PPCF128, "lrintl") +HANDLE_LIBCALL(LLRINT_F32, "llrintf") +HANDLE_LIBCALL(LLRINT_F64, "llrint") +HANDLE_LIBCALL(LLRINT_F80, "llrintl") +HANDLE_LIBCALL(LLRINT_F128, "llrintl") +HANDLE_LIBCALL(LLRINT_PPCF128, "llrintl") // Conversion HANDLE_LIBCALL(FPEXT_F32_PPCF128, "__gcc_stoq") @@ -530,6 +549,9 @@ HANDLE_LIBCALL(STACKPROTECTOR_CHECK_FAIL, "__stack_chk_fail") // Deoptimization HANDLE_LIBCALL(DEOPTIMIZE, "__llvm_deoptimize") +// Return address +HANDLE_LIBCALL(RETURN_ADDRESS, nullptr) + HANDLE_LIBCALL(UNKNOWN_LIBCALL, nullptr) #undef HANDLE_LIBCALL diff --git a/include/llvm/IR/SafepointIRVerifier.h b/include/llvm/IR/SafepointIRVerifier.h index 092050d1d207..ec5527954adc 100644 --- a/include/llvm/IR/SafepointIRVerifier.h +++ b/include/llvm/IR/SafepointIRVerifier.h @@ -1,9 +1,8 @@ //===- SafepointIRVerifier.h - Checks for GC relocation problems *- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,8 @@ #ifndef LLVM_IR_SAFEPOINT_IR_VERIFIER #define LLVM_IR_SAFEPOINT_IR_VERIFIER +#include "llvm/IR/PassManager.h" + namespace llvm { class Function; @@ -30,6 +31,16 @@ void verifySafepointIR(Function &F); /// Create an instance of the safepoint verifier pass which can be added to /// a pass pipeline to check for relocation bugs. FunctionPass *createSafepointIRVerifierPass(); + +/// Create an instance of the safepoint verifier pass which can be added to +/// a pass pipeline to check for relocation bugs. +class SafepointIRVerifierPass : public PassInfoMixin<SafepointIRVerifierPass> { + +public: + explicit SafepointIRVerifierPass() {} + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; } #endif // LLVM_IR_SAFEPOINT_IR_VERIFIER diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index 8908e1b0d090..89f130bc3351 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -1,14 +1,13 @@ //===- llvm/IR/Statepoint.h - gc.statepoint utilities -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains utility functions and a wrapper class analogous to -// CallSite for accessing the fields of gc.statepoint, gc.relocate, +// CallBase for accessing the fields of gc.statepoint, gc.relocate, // gc.result intrinsics; and some general utilities helpful when dealing with // gc.statepoint. // @@ -21,7 +20,6 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" @@ -57,42 +55,36 @@ enum class StatepointFlags { class GCRelocateInst; class GCResultInst; -bool isStatepoint(ImmutableCallSite CS); +bool isStatepoint(const CallBase *Call); bool isStatepoint(const Value *V); bool isStatepoint(const Value &V); -bool isGCRelocate(ImmutableCallSite CS); +bool isGCRelocate(const CallBase *Call); bool isGCRelocate(const Value *V); -bool isGCResult(ImmutableCallSite CS); +bool isGCResult(const CallBase *Call); bool isGCResult(const Value *V); -/// Analogous to CallSiteBase, this provides most of the actual +/// A wrapper around a GC intrinsic call, this provides most of the actual /// functionality for Statepoint and ImmutableStatepoint. It is /// templatized to allow easily specializing of const and non-const -/// concrete subtypes. This is structured analogous to CallSite -/// rather than the IntrinsicInst.h helpers since we need to support -/// invokable statepoints. +/// concrete subtypes. template <typename FunTy, typename InstructionTy, typename ValueTy, - typename CallSiteTy> + typename CallBaseTy> class StatepointBase { - CallSiteTy StatepointCS; + CallBaseTy *StatepointCall; protected: explicit StatepointBase(InstructionTy *I) { - if (isStatepoint(I)) { - StatepointCS = CallSiteTy(I); - assert(StatepointCS && "isStatepoint implies CallSite"); - } + StatepointCall = isStatepoint(I) ? cast<CallBaseTy>(I) : nullptr; } - explicit StatepointBase(CallSiteTy CS) { - if (isStatepoint(CS)) - StatepointCS = CS; + explicit StatepointBase(CallBaseTy *Call) { + StatepointCall = isStatepoint(Call) ? Call : nullptr; } public: - using arg_iterator = typename CallSiteTy::arg_iterator; + using arg_iterator = typename CallBaseTy::const_op_iterator; enum { IDPos = 0, @@ -107,30 +99,30 @@ public: void *operator new(size_t s) = delete; explicit operator bool() const { - // We do not assign non-statepoint CallSites to StatepointCS. - return (bool)StatepointCS; + // We do not assign non-statepoint call instructions to StatepointCall. + return (bool)StatepointCall; } - /// Return the underlying CallSite. - CallSiteTy getCallSite() const { + /// Return the underlying call instruction. + CallBaseTy *getCall() const { assert(*this && "check validity first!"); - return StatepointCS; + return StatepointCall; } uint64_t getFlags() const { - return cast<ConstantInt>(getCallSite().getArgument(FlagsPos)) + return cast<ConstantInt>(getCall()->getArgOperand(FlagsPos)) ->getZExtValue(); } /// Return the ID associated with this statepoint. uint64_t getID() const { - const Value *IDVal = getCallSite().getArgument(IDPos); + const Value *IDVal = getCall()->getArgOperand(IDPos); return cast<ConstantInt>(IDVal)->getZExtValue(); } /// Return the number of patchable bytes associated with this statepoint. uint32_t getNumPatchBytes() const { - const Value *NumPatchBytesVal = getCallSite().getArgument(NumPatchBytesPos); + const Value *NumPatchBytesVal = getCall()->getArgOperand(NumPatchBytesPos); uint64_t NumPatchBytes = cast<ConstantInt>(NumPatchBytesVal)->getZExtValue(); assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!"); @@ -139,12 +131,11 @@ public: /// Return the value actually being called or invoked. ValueTy *getCalledValue() const { - return getCallSite().getArgument(CalledFunctionPos); + return getCall()->getArgOperand(CalledFunctionPos); } - InstructionTy *getInstruction() const { - return getCallSite().getInstruction(); - } + // FIXME: Migrate users of this to `getCall` and remove it. + InstructionTy *getInstruction() const { return getCall(); } /// Return the function being called if this is a direct call, otherwise /// return null (if it's an indirect call). @@ -153,12 +144,12 @@ public: } /// Return the caller function for this statepoint. - FunTy *getCaller() const { return getCallSite().getCaller(); } + FunTy *getCaller() const { return getCall()->getCaller(); } /// Determine if the statepoint cannot unwind. bool doesNotThrow() const { Function *F = getCalledFunction(); - return getCallSite().doesNotThrow() || (F ? F->doesNotThrow() : false); + return getCall()->doesNotThrow() || (F ? F->doesNotThrow() : false); } /// Return the type of the value returned by the call underlying the @@ -171,18 +162,18 @@ public: /// Number of arguments to be passed to the actual callee. int getNumCallArgs() const { - const Value *NumCallArgsVal = getCallSite().getArgument(NumCallArgsPos); + const Value *NumCallArgsVal = getCall()->getArgOperand(NumCallArgsPos); return cast<ConstantInt>(NumCallArgsVal)->getZExtValue(); } size_t arg_size() const { return getNumCallArgs(); } - typename CallSiteTy::arg_iterator arg_begin() const { - assert(CallArgsBeginPos <= (int)getCallSite().arg_size()); - return getCallSite().arg_begin() + CallArgsBeginPos; + arg_iterator arg_begin() const { + assert(CallArgsBeginPos <= (int)getCall()->arg_size()); + return getCall()->arg_begin() + CallArgsBeginPos; } - typename CallSiteTy::arg_iterator arg_end() const { + arg_iterator arg_end() const { auto I = arg_begin() + arg_size(); - assert((getCallSite().arg_end() - I) >= 0); + assert((getCall()->arg_end() - I) >= 0); return I; } @@ -199,8 +190,8 @@ public: /// Return true if the call or the callee has the given attribute. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { Function *F = getCalledFunction(); - return getCallSite().paramHasAttr(i + CallArgsBeginPos, A) || - (F ? F->getAttributes().hasAttribute(i, A) : false); + return getCall()->paramHasAttr(i + CallArgsBeginPos, A) || + (F ? F->getAttributes().hasAttribute(i, A) : false); } /// Number of GC transition args. @@ -208,14 +199,14 @@ public: const Value *NumGCTransitionArgs = *arg_end(); return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue(); } - typename CallSiteTy::arg_iterator gc_transition_args_begin() const { + arg_iterator gc_transition_args_begin() const { auto I = arg_end() + 1; - assert((getCallSite().arg_end() - I) >= 0); + assert((getCall()->arg_end() - I) >= 0); return I; } - typename CallSiteTy::arg_iterator gc_transition_args_end() const { + arg_iterator gc_transition_args_end() const { auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs(); - assert((getCallSite().arg_end() - I) >= 0); + assert((getCall()->arg_end() - I) >= 0); return I; } @@ -231,14 +222,14 @@ public: return cast<ConstantInt>(NumVMSArgs)->getZExtValue(); } - typename CallSiteTy::arg_iterator deopt_begin() const { + arg_iterator deopt_begin() const { auto I = gc_transition_args_end() + 1; - assert((getCallSite().arg_end() - I) >= 0); + assert((getCall()->arg_end() - I) >= 0); return I; } - typename CallSiteTy::arg_iterator deopt_end() const { + arg_iterator deopt_end() const { auto I = deopt_begin() + getNumTotalVMSArgs(); - assert((getCallSite().arg_end() - I) >= 0); + assert((getCall()->arg_end() - I) >= 0); return I; } @@ -247,15 +238,11 @@ public: return make_range(deopt_begin(), deopt_end()); } - typename CallSiteTy::arg_iterator gc_args_begin() const { - return deopt_end(); - } - typename CallSiteTy::arg_iterator gc_args_end() const { - return getCallSite().arg_end(); - } + arg_iterator gc_args_begin() const { return deopt_end(); } + arg_iterator gc_args_end() const { return getCall()->arg_end(); } unsigned gcArgsStartIdx() const { - return gc_args_begin() - getInstruction()->op_begin(); + return gc_args_begin() - getCall()->op_begin(); } /// range adapter for gc arguments @@ -304,25 +291,24 @@ public: /// to a gc.statepoint. class ImmutableStatepoint : public StatepointBase<const Function, const Instruction, const Value, - ImmutableCallSite> { - using Base = - StatepointBase<const Function, const Instruction, const Value, - ImmutableCallSite>; + const CallBase> { + using Base = StatepointBase<const Function, const Instruction, const Value, + const CallBase>; public: explicit ImmutableStatepoint(const Instruction *I) : Base(I) {} - explicit ImmutableStatepoint(ImmutableCallSite CS) : Base(CS) {} + explicit ImmutableStatepoint(const CallBase *Call) : Base(Call) {} }; /// A specialization of it's base class for read-write access /// to a gc.statepoint. class Statepoint - : public StatepointBase<Function, Instruction, Value, CallSite> { - using Base = StatepointBase<Function, Instruction, Value, CallSite>; + : public StatepointBase<Function, Instruction, Value, CallBase> { + using Base = StatepointBase<Function, Instruction, Value, CallBase>; public: explicit Statepoint(Instruction *I) : Base(I) {} - explicit Statepoint(CallSite CS) : Base(CS) {} + explicit Statepoint(CallBase *Call) : Base(Call) {} }; /// Common base class for representing values projected from a statepoint. @@ -347,14 +333,14 @@ public: } /// The statepoint with which this gc.relocate is associated. - const Instruction *getStatepoint() const { + const CallBase *getStatepoint() const { const Value *Token = getArgOperand(0); // This takes care both of relocates for call statepoints and relocates // on normal path of invoke statepoint. if (!isa<LandingPadInst>(Token)) { assert(isStatepoint(Token)); - return cast<Instruction>(Token); + return cast<CallBase>(Token); } // This relocate is on exceptional path of an invoke statepoint @@ -366,7 +352,7 @@ public: "safepoint block should be well formed"); assert(isStatepoint(InvokeBB->getTerminator())); - return InvokeBB->getTerminator(); + return cast<CallBase>(InvokeBB->getTerminator()); } }; @@ -395,13 +381,11 @@ public: } Value *getBasePtr() const { - ImmutableCallSite CS(getStatepoint()); - return *(CS.arg_begin() + getBasePtrIndex()); + return *(getStatepoint()->arg_begin() + getBasePtrIndex()); } Value *getDerivedPtr() const { - ImmutableCallSite CS(getStatepoint()); - return *(CS.arg_begin() + getDerivedPtrIndex()); + return *(getStatepoint()->arg_begin() + getDerivedPtrIndex()); } }; @@ -418,28 +402,25 @@ public: }; template <typename FunTy, typename InstructionTy, typename ValueTy, - typename CallSiteTy> + typename CallBaseTy> std::vector<const GCRelocateInst *> -StatepointBase<FunTy, InstructionTy, ValueTy, CallSiteTy>::getRelocates() +StatepointBase<FunTy, InstructionTy, ValueTy, CallBaseTy>::getRelocates() const { - std::vector<const GCRelocateInst *> Result; - CallSiteTy StatepointCS = getCallSite(); - // Search for relocated pointers. Note that working backwards from the // gc_relocates ensures that we only get pairs which are actually relocated // and used after the statepoint. - for (const User *U : getInstruction()->users()) + for (const User *U : StatepointCall->users()) if (auto *Relocate = dyn_cast<GCRelocateInst>(U)) Result.push_back(Relocate); - if (!StatepointCS.isInvoke()) + auto *StatepointInvoke = dyn_cast<InvokeInst>(StatepointCall); + if (!StatepointInvoke) return Result; // We need to scan thorough exceptional relocations if it is invoke statepoint - LandingPadInst *LandingPad = - cast<InvokeInst>(getInstruction())->getLandingPadInst(); + LandingPadInst *LandingPad = StatepointInvoke->getLandingPadInst(); // Search for gc relocates that are attached to this landingpad. for (const User *LandingPadUser : LandingPad->users()) { diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h index 87ce902c2811..5b793e5dbf28 100644 --- a/include/llvm/IR/SymbolTableListTraits.h +++ b/include/llvm/IR/SymbolTableListTraits.h @@ -1,9 +1,8 @@ //===- llvm/SymbolTableListTraits.h - Traits for iplist ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/TrackingMDRef.h b/include/llvm/IR/TrackingMDRef.h index 084efada221f..d7377398b91b 100644 --- a/include/llvm/IR/TrackingMDRef.h +++ b/include/llvm/IR/TrackingMDRef.h @@ -1,9 +1,8 @@ //===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index 9c1f99d1b3a2..f2aa49030aaa 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -1,9 +1,8 @@ //===- llvm/Type.h - Classes for handling data types ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -367,6 +366,7 @@ public: return ContainedTys[0]; } + inline bool getVectorIsScalable() const; inline unsigned getVectorNumElements() const; Type *getVectorElementType() const { assert(getTypeID() == VectorTyID); @@ -467,28 +467,6 @@ 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 *> { - using NodeRef = Type *; - using ChildIteratorType = Type::subtype_iterator; - - static NodeRef getEntryNode(Type *T) { return T; } - static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); } - static ChildIteratorType child_end(NodeRef N) { return N->subtype_end(); } -}; - -template <> struct GraphTraits<const Type*> { - using NodeRef = const Type *; - using ChildIteratorType = Type::subtype_iterator; - - static NodeRef getEntryNode(NodeRef T) { return T; } - static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); } - static ChildIteratorType child_end(NodeRef N) { return N->subtype_end(); } -}; - // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef) diff --git a/include/llvm/IR/TypeFinder.h b/include/llvm/IR/TypeFinder.h index c050c388d398..a83f85ea84c3 100644 --- a/include/llvm/IR/TypeFinder.h +++ b/include/llvm/IR/TypeFinder.h @@ -1,9 +1,8 @@ //===- llvm/IR/TypeFinder.h - Class to find used struct types ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 25c44e0871a9..034ca2c8ac23 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -1,9 +1,8 @@ //===- llvm/Use.h - Definition of the Use class -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -140,7 +139,7 @@ private: const Use *getImpliedUser() const LLVM_READONLY; Value *Val = nullptr; - Use *Next; + Use *Next = nullptr; PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev; void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); } diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h index b6bb0f19a0aa..a1f313e269b2 100644 --- a/include/llvm/IR/UseListOrder.h +++ b/include/llvm/IR/UseListOrder.h @@ -1,9 +1,8 @@ //===- llvm/IR/UseListOrder.h - LLVM Use List Order -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index aea31467f2fa..19d87c5c621d 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -1,9 +1,8 @@ //===- llvm/User.h - User class definition ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Value.def b/include/llvm/IR/Value.def index e2ddba0aa159..aaf1651979a9 100644 --- a/include/llvm/IR/Value.def +++ b/include/llvm/IR/Value.def @@ -1,9 +1,8 @@ //===-------- llvm/IR/Value.def - File that describes Values ---v-*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 4f3a45c684fc..b2d8e7ac4741 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -1,9 +1,8 @@ //===- llvm/Value.h - Definition of the Value class -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -494,7 +493,7 @@ public: /// swifterror attribute. bool isSwiftError() const; - /// Strip off pointer casts, all-zero GEPs, and aliases. + /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases. /// /// Returns the original uncasted value. If this is called on a non-pointer /// value, it returns 'this'. @@ -504,6 +503,17 @@ public: static_cast<const Value *>(this)->stripPointerCasts()); } + /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases + /// but ensures the representation of the result stays the same. + /// + /// Returns the original uncasted value with the same representation. If this + /// is called on a non-pointer value, it returns 'this'. + const Value *stripPointerCastsSameRepresentation() const; + Value *stripPointerCastsSameRepresentation() { + return const_cast<Value *>(static_cast<const Value *>(this) + ->stripPointerCastsSameRepresentation()); + } + /// Strip off pointer casts, all-zero GEPs, aliases and invariant group /// info. /// @@ -536,19 +546,48 @@ public: static_cast<const Value *>(this)->stripInBoundsConstantOffsets()); } - /// Accumulate offsets from \a stripInBoundsConstantOffsets(). - /// - /// Stores the resulting constant offset stripped into the APInt provided. - /// The provided APInt will be extended or truncated as needed to be the - /// correct bitwidth for an offset of this pointer type. - /// - /// If this is called on a non-pointer value, it returns 'this'. + /// Accumulate the constant offset this value has compared to a base pointer. + /// Only 'getelementptr' instructions (GEPs) with constant indices are + /// accumulated but other instructions, e.g., casts, are stripped away as + /// well. The accumulated constant offset is added to \p Offset and the base + /// pointer is returned. + /// + /// The APInt \p Offset has to have a bit-width equal to the IntPtr type for + /// the address space of 'this' pointer value, e.g., use + /// DataLayout::getIndexTypeSizeInBits(Ty). + /// + /// If \p AllowNonInbounds is true, constant offsets in GEPs are stripped and + /// accumulated even if the GEP is not "inbounds". + /// + /// If this is called on a non-pointer value, it returns 'this' and the + /// \p Offset is not modified. + /// + /// Note that this function will never return a nullptr. It will also never + /// manipulate the \p Offset in a way that would not match the difference + /// between the underlying value and the returned one. Thus, if no constant + /// offset was found, the returned value is the underlying one and \p Offset + /// is unchanged. + const Value *stripAndAccumulateConstantOffsets(const DataLayout &DL, + APInt &Offset, + bool AllowNonInbounds) const; + Value *stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, + bool AllowNonInbounds) { + return const_cast<Value *>( + static_cast<const Value *>(this)->stripAndAccumulateConstantOffsets( + DL, Offset, AllowNonInbounds)); + } + + /// This is a wrapper around stripAndAccumulateConstantOffsets with the + /// in-bounds requirement set to false. const Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, - APInt &Offset) const; + APInt &Offset) const { + return stripAndAccumulateConstantOffsets(DL, Offset, + /* AllowNonInbounds */ false); + } Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) { - return const_cast<Value *>(static_cast<const Value *>(this) - ->stripAndAccumulateInBoundsConstantOffsets(DL, Offset)); + return stripAndAccumulateConstantOffsets(DL, Offset, + /* AllowNonInbounds */ false); } /// Strip off pointer casts and inbounds GEPs. diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index d94472ce1be1..1135d796f7ed 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -1,9 +1,8 @@ //===- ValueHandle.h - Value Smart Pointer classes --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -309,15 +308,6 @@ struct DenseMapInfo<AssertingVH<T>> { } }; -template <typename T> -struct isPodLike<AssertingVH<T>> { -#ifdef NDEBUG - static const bool value = true; -#else - static const bool value = false; -#endif -}; - /// Value handle that tracks a Value across RAUW. /// /// TrackingVH is designed for situations where a client needs to hold a handle @@ -549,14 +539,6 @@ template <typename T> struct DenseMapInfo<PoisoningVH<T>> { } }; -template <typename T> struct isPodLike<PoisoningVH<T>> { -#ifdef NDEBUG - static const bool value = true; -#else - static const bool value = false; -#endif -}; - } // end namespace llvm #endif // LLVM_IR_VALUEHANDLE_H diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h index e7e33918a613..6a79b1d387f3 100644 --- a/include/llvm/IR/ValueMap.h +++ b/include/llvm/IR/ValueMap.h @@ -1,9 +1,8 @@ //===- ValueMap.h - Safe map from Values to data ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h index 012e717c7470..105ea73857af 100644 --- a/include/llvm/IR/ValueSymbolTable.h +++ b/include/llvm/IR/ValueSymbolTable.h @@ -1,9 +1,8 @@ //===- llvm/ValueSymbolTable.h - Implement a Value Symtab -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h index 7255132e1e65..62c33c8325eb 100644 --- a/include/llvm/IR/Verifier.h +++ b/include/llvm/IR/Verifier.h @@ -1,9 +1,8 @@ //===- Verifier.h - LLVM IR Verifier ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // |