summaryrefslogtreecommitdiff
path: root/include/llvm/IR
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /include/llvm/IR
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
Notes
Diffstat (limited to 'include/llvm/IR')
-rw-r--r--include/llvm/IR/Argument.h15
-rw-r--r--include/llvm/IR/AssemblyAnnotationWriter.h7
-rw-r--r--include/llvm/IR/Attributes.h27
-rw-r--r--include/llvm/IR/Attributes.td16
-rw-r--r--include/llvm/IR/AutoUpgrade.h13
-rw-r--r--include/llvm/IR/BasicBlock.h17
-rw-r--r--include/llvm/IR/CFG.h11
-rw-r--r--include/llvm/IR/CFGDiff.h7
-rw-r--r--include/llvm/IR/CallSite.h311
-rw-r--r--include/llvm/IR/CallingConv.h7
-rw-r--r--include/llvm/IR/Comdat.h7
-rw-r--r--include/llvm/IR/Constant.h11
-rw-r--r--include/llvm/IR/ConstantFolder.h11
-rw-r--r--include/llvm/IR/ConstantRange.h191
-rw-r--r--include/llvm/IR/Constants.h7
-rw-r--r--include/llvm/IR/DIBuilder.h17
-rw-r--r--include/llvm/IR/DataLayout.h47
-rw-r--r--include/llvm/IR/DebugInfo.h7
-rw-r--r--include/llvm/IR/DebugInfoFlags.def17
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h386
-rw-r--r--include/llvm/IR/DebugLoc.h7
-rw-r--r--include/llvm/IR/DerivedTypes.h107
-rw-r--r--include/llvm/IR/DerivedUser.h7
-rw-r--r--include/llvm/IR/DiagnosticHandler.h9
-rw-r--r--include/llvm/IR/DiagnosticInfo.h20
-rw-r--r--include/llvm/IR/DiagnosticPrinter.h7
-rw-r--r--include/llvm/IR/DomTreeUpdater.h257
-rw-r--r--include/llvm/IR/Dominators.h7
-rw-r--r--include/llvm/IR/Function.h48
-rw-r--r--include/llvm/IR/GVMaterializer.h7
-rw-r--r--include/llvm/IR/GetElementPtrTypeIterator.h7
-rw-r--r--include/llvm/IR/GlobalAlias.h7
-rw-r--r--include/llvm/IR/GlobalIFunc.h7
-rw-r--r--include/llvm/IR/GlobalIndirectSymbol.h7
-rw-r--r--include/llvm/IR/GlobalObject.h7
-rw-r--r--include/llvm/IR/GlobalValue.h25
-rw-r--r--include/llvm/IR/GlobalVariable.h7
-rw-r--r--include/llvm/IR/IRBuilder.h340
-rw-r--r--include/llvm/IR/IRPrintingPasses.h7
-rw-r--r--include/llvm/IR/InlineAsm.h7
-rw-r--r--include/llvm/IR/InstIterator.h7
-rw-r--r--include/llvm/IR/InstVisitor.h20
-rw-r--r--include/llvm/IR/InstrTypes.h166
-rw-r--r--include/llvm/IR/Instruction.def146
-rw-r--r--include/llvm/IR/Instruction.h28
-rw-r--r--include/llvm/IR/Instructions.h487
-rw-r--r--include/llvm/IR/IntrinsicInst.h136
-rw-r--r--include/llvm/IR/Intrinsics.h37
-rw-r--r--include/llvm/IR/Intrinsics.td227
-rw-r--r--include/llvm/IR/IntrinsicsAArch64.td77
-rw-r--r--include/llvm/IR/IntrinsicsAMDGPU.td524
-rw-r--r--include/llvm/IR/IntrinsicsARM.td57
-rw-r--r--include/llvm/IR/IntrinsicsBPF.td7
-rw-r--r--include/llvm/IR/IntrinsicsHexagon.td513
-rw-r--r--include/llvm/IR/IntrinsicsMips.td277
-rw-r--r--include/llvm/IR/IntrinsicsNVVM.td465
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td35
-rw-r--r--include/llvm/IR/IntrinsicsRISCV.td38
-rw-r--r--include/llvm/IR/IntrinsicsSystemZ.td66
-rw-r--r--include/llvm/IR/IntrinsicsWebAssembly.td45
-rw-r--r--include/llvm/IR/IntrinsicsX86.td1266
-rw-r--r--include/llvm/IR/IntrinsicsXCore.td7
-rw-r--r--include/llvm/IR/LLVMContext.h42
-rw-r--r--include/llvm/IR/LegacyPassManager.h7
-rw-r--r--include/llvm/IR/LegacyPassManagers.h7
-rw-r--r--include/llvm/IR/LegacyPassNameParser.h7
-rw-r--r--include/llvm/IR/MDBuilder.h18
-rw-r--r--include/llvm/IR/Mangler.h7
-rw-r--r--include/llvm/IR/Metadata.def8
-rw-r--r--include/llvm/IR/Metadata.h7
-rw-r--r--include/llvm/IR/Module.h50
-rw-r--r--include/llvm/IR/ModuleSlotTracker.h7
-rw-r--r--include/llvm/IR/ModuleSummaryIndex.h253
-rw-r--r--include/llvm/IR/ModuleSummaryIndexYAML.h15
-rw-r--r--include/llvm/IR/NoFolder.h11
-rw-r--r--include/llvm/IR/OperandTraits.h7
-rw-r--r--include/llvm/IR/Operator.h14
-rw-r--r--include/llvm/IR/OptBisect.h43
-rw-r--r--include/llvm/IR/PassInstrumentation.h7
-rw-r--r--include/llvm/IR/PassManager.h14
-rw-r--r--include/llvm/IR/PassManagerInternal.h7
-rw-r--r--include/llvm/IR/PassTimingInfo.h28
-rw-r--r--include/llvm/IR/PatternMatch.h91
-rw-r--r--include/llvm/IR/PredIteratorCache.h7
-rw-r--r--include/llvm/IR/ProfileSummary.h10
-rw-r--r--include/llvm/IR/RemarkStreamer.h96
-rw-r--r--include/llvm/IR/RuntimeLibcalls.def30
-rw-r--r--include/llvm/IR/SafepointIRVerifier.h19
-rw-r--r--include/llvm/IR/Statepoint.h149
-rw-r--r--include/llvm/IR/SymbolTableListTraits.h7
-rw-r--r--include/llvm/IR/TrackingMDRef.h7
-rw-r--r--include/llvm/IR/Type.h30
-rw-r--r--include/llvm/IR/TypeFinder.h7
-rw-r--r--include/llvm/IR/Use.h9
-rw-r--r--include/llvm/IR/UseListOrder.h7
-rw-r--r--include/llvm/IR/User.h7
-rw-r--r--include/llvm/IR/Value.def7
-rw-r--r--include/llvm/IR/Value.h69
-rw-r--r--include/llvm/IR/ValueHandle.h24
-rw-r--r--include/llvm/IR/ValueMap.h7
-rw-r--r--include/llvm/IR/ValueSymbolTable.h7
-rw-r--r--include/llvm/IR/Verifier.h7
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
//
//===----------------------------------------------------------------------===//
//