[llvm] [LLVM][Intrinsics] Refactor IITDescriptors. (PR #190011)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 10:53:14 PDT 2026


https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/190011

None

>From b5bd2cb8c4657956f9ac42edccbda1b054a0e30e Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 1 Apr 2026 09:57:47 -0700
Subject: [PATCH] [LLVM][Intrinsics] Refactor IITDescriptors.

---
 llvm/include/llvm/IR/Intrinsics.h             |  86 +++---
 llvm/include/llvm/IR/Intrinsics.td            |  44 +--
 llvm/lib/IR/Intrinsics.cpp                    | 253 +++++++++---------
 llvm/lib/Transforms/Utils/CloneFunction.cpp   |   6 +-
 .../utils/TableGen/Basic/IntrinsicEmitter.cpp |  18 +-
 5 files changed, 208 insertions(+), 199 deletions(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 73311c96b1326..8485be4ff1175 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -67,17 +67,18 @@ namespace Intrinsic {
   /// overloads are required, it is safe to use this version, but better to use
   /// the StringRef version. If one of the types is based on an unnamed type, a
   /// function type will be computed. Providing FT will avoid this computation.
-  LLVM_ABI std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
+  LLVM_ABI std::string getName(ID Id, ArrayRef<Type *> OverloadTys, Module *M,
                                FunctionType *FT = nullptr);
 
   /// Return the LLVM name for an intrinsic. This is a special version only to
   /// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
   /// based on named types.
-  LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
+  LLVM_ABI std::string getNameNoUnnamedTypes(ID Id,
+                                             ArrayRef<Type *> OverloadTys);
 
   /// Return the function type for an intrinsic.
   LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id,
-                                 ArrayRef<Type *> Tys = {});
+                                 ArrayRef<Type *> OverloadTys = {});
 
   /// Returns true if the intrinsic can be overloaded.
   LLVM_ABI bool isOverloaded(ID id);
@@ -153,6 +154,7 @@ namespace Intrinsic {
   /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
   struct IITDescriptor {
     enum IITDescriptorKind {
+      // Concrete types. Additional qualifiers listed in comments.
       Void,
       VarArg,
       MMX,
@@ -163,70 +165,72 @@ namespace Intrinsic {
       Float,
       Double,
       Quad,
-      Integer,
-      Vector,
-      Pointer,
-      Struct,
-      Argument,
-      ExtendArgument,
-      TruncArgument,
-      OneNthEltsVecArgument,
-      SameVecWidthArgument,
-      VecOfAnyPtrsToElt,
-      VecElementArgument,
-      Subdivide2Argument,
-      Subdivide4Argument,
-      VecOfBitcastsToInt,
+      Integer, // Width of the integer in IntegerWidth.
+      Vector,  // Width of the vector in VectorWidth.
+      Pointer, // Address space of the pointer in PointerAddressSpace.
+      Struct,  // Number of elements in StructNumElements.
       AMX,
       PPCQuad,
       AArch64Svcount,
+
+      // Overloaded type.
+      Overloaded, // AnyKind and overload index in OverloadInfo.
+
+      // Fully dependent types. Overload index in OverloadInfo.
+      Extend,
+      Trunc,
+      OneNthEltsVec,
+      SameVecWidth,
+      VecElement,
+      Subdivide2,
+      Subdivide4,
+      VecOfBitcastsToInt,
+
+      // Partially dependent types. Overload index (self and of the overload
+      // type it depends on) in OverloadInfo.
+      VecOfAnyPtrsToElt,
+
     } Kind;
 
     union {
       unsigned IntegerWidth;
       unsigned PointerAddressSpace;
       unsigned StructNumElements;
-      unsigned ArgumentInfo;
+      unsigned OverloadInfo;
       ElementCount VectorWidth;
     };
 
     // AK_% : Defined in Intrinsics.td
-    enum ArgKind {
-#define GET_INTRINSIC_ARGKIND
+    enum AnyKind {
+#define GET_INTRINSIC_ANYKIND
 #include "llvm/IR/IntrinsicEnums.inc"
     };
 
-    unsigned getArgumentNumber() const {
-      assert(Kind == Argument || Kind == ExtendArgument ||
-             Kind == TruncArgument || Kind == SameVecWidthArgument ||
-             Kind == VecElementArgument || Kind == Subdivide2Argument ||
-             Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
+    unsigned getOverloadIndex() const {
+      assert(Kind == Overloaded || Kind == Extend || Kind == Trunc ||
+             Kind == SameVecWidth || Kind == VecElement || Kind == Subdivide2 ||
+             Kind == Subdivide4 || Kind == VecOfBitcastsToInt ||
+             Kind == VecOfAnyPtrsToElt || Kind == OneNthEltsVec);
       // Overload index is packed into lower 5 bits.
-      return ArgumentInfo & 0x1f;
-    }
-    ArgKind getArgumentKind() const {
-      // Argument kind is packed into upper 3 bits.
-      assert(Kind == Argument);
-      return (ArgKind)((ArgumentInfo >> 5) & 0x7);
+      return OverloadInfo & 0x1f;
     }
 
-    // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
-    // and a reference argument (for matching vector width and element types)
-    unsigned getOverloadArgNumber() const {
-      assert(Kind == VecOfAnyPtrsToElt);
-      return ArgumentInfo >> 16;
+    AnyKind getOverloadKind() const {
+      // Overload kind is packed into upper 3 bits.
+      assert(Kind == Overloaded);
+      return (AnyKind)((OverloadInfo >> 5) & 0x7);
     }
 
     // OneNthEltsVecArguments uses both a divisor N and a reference argument for
     // the full-width vector to match
     unsigned getVectorDivisor() const {
-      assert(Kind == OneNthEltsVecArgument);
-      return ArgumentInfo >> 16;
+      assert(Kind == OneNthEltsVec);
+      return OverloadInfo >> 16;
     }
 
-    unsigned getRefArgNumber() const {
-      assert(Kind == VecOfAnyPtrsToElt || Kind == OneNthEltsVecArgument);
-      return ArgumentInfo & 0xFFFF;
+    unsigned getRefOverloadIndex() const {
+      assert(Kind == VecOfAnyPtrsToElt);
+      return OverloadInfo & 0xFFFF;
     }
 
     static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index abab8c3b53574..8103fe2a5f82b 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -232,8 +232,8 @@ def IntrNoCreateUndefOrPoison : IntrinsicProperty;
 // IIT constants and utils
 //===----------------------------------------------------------------------===//
 
-// llvm::Intrinsic::IITDescriptor::ArgKind::AK_%
-def ArgKind {
+// llvm::Intrinsic::IITDescriptor::AnyKind::AK_%
+def AnyKind {
   int Any        = 0;
   int AnyInteger = 1;
   int AnyFloat   = 2;
@@ -246,13 +246,13 @@ def ArgKind {
 // Placeholder to encode the overload index of the current type. We encode bit
 // 8 = 1 to indicate that this entry needs to be patched up with the overload
 // index (to prevent conflict with any valid not-to-be-patched IIT enccoding
-// byte, whose value will be <= 255). The ArgKind itself is in the lower bits.
+// byte, whose value will be <= 255). The AnyKind itself is in the lower bits.
 // Note that this is just a transient representation till its gets processed
 // by `DoPatchOverloadIndex` below, so this is *not* the encoding of the
 // final type signature.
-class OverloadIndexPlaceholder <int ArgKindVal> {
+class OverloadIndexPlaceholder <int AnyKindVal> {
   int ID = 0x100;
-  int ret = !or(ID, ArgKindVal);
+  int ret = !or(ID, AnyKindVal);
 }
 
 // This class defines how the overload index and the arg kind are actually
@@ -261,10 +261,10 @@ class OverloadIndexPlaceholder <int ArgKindVal> {
 // us to use the same packing for llvm_any* types, which use a argument kind
 // and for partially dependent types like `LLVMVectorOfAnyPointersToElt` which
 // do not use the argument kind and expect the overload index in the lower bits.
-class PackOverloadIndex<int OverloadIndex, int ArgKindVal> {
+class PackOverloadIndex<int OverloadIndex, int AnyKindVal> {
   assert !lt(OverloadIndex, 32), "Cannot support more than 32 overload types";
-  assert !lt(ArgKindVal, 8), "Cannot support more than 8 argument kinds";
-  int ret = !or(!shl(ArgKindVal, 5), OverloadIndex);
+  assert !lt(AnyKindVal, 8), "Cannot support more than 8 argument kinds";
+  int ret = !or(!shl(AnyKindVal, 5), OverloadIndex);
 }
 
 // This class handles the actual patching of the overload index into a component
@@ -272,10 +272,10 @@ class PackOverloadIndex<int OverloadIndex, int ArgKindVal> {
 // value generated by OverloadIndexPlaceholder and patching is needed, else the
 // value is left unchanged.
 class PatchOverloadIndex<int Sig, int OverloadIndex> {
-  int ArgKindVal = !and(Sig, 0x7);
+  int AnyKindVal = !and(Sig, 0x7);
   int ret = !cond(
     // If the value is > 255, it indicates that patching is needed.
-    !gt(Sig, 255) : PackOverloadIndex<OverloadIndex, ArgKindVal>.ret,
+    !gt(Sig, 255) : PackOverloadIndex<OverloadIndex, AnyKindVal>.ret,
     true: Sig);
 }
 
@@ -317,8 +317,8 @@ def IIT_V4   : IIT_Vec<4,  10>;
 def IIT_V8   : IIT_Vec<8,  11>;
 def IIT_V16  : IIT_Vec<16, 12>;
 def IIT_V32  : IIT_Vec<32, 13>;
-def IIT_PTR  : IIT_Base<   14>;
-def IIT_ARG  : IIT_Base<   15>;
+def IIT_PTR  : IIT_Base<   14>; // pointer with address space 0.
+def IIT_ANY  : IIT_Base<   15>;
 
 def IIT_V64 : IIT_Vec<64, 16>;
 def IIT_MMX : IIT_VT<x86mmx, 17>;
@@ -328,7 +328,7 @@ def IIT_EMPTYSTRUCT : IIT_VT<OtherVT, 20>;
 def IIT_STRUCT : IIT_Base<21>;
 def IIT_EXTEND_ARG : IIT_Base<22>;
 def IIT_TRUNC_ARG : IIT_Base<23>;
-def IIT_ANYPTR : IIT_Base<24>;
+def IIT_PTR_AS : IIT_Base<24>; // Pointer with address space.
 def IIT_V1 : IIT_Vec<1, 25>;
 def IIT_VARARG : IIT_VT<isVoid, 26>;
 def IIT_ONE_NTH_ELTS_VEC_ARG : IIT_Base<27>;
@@ -398,14 +398,14 @@ class LLVMType<ValueType vt> {
 
 class LLVMAnyType<ValueType vt> : LLVMType<vt> {
   int ArgCode = !cond(
-    !eq(vt, Any)     : ArgKind.Any,
-    !eq(vt, iAny)    : ArgKind.AnyInteger,
-    !eq(vt, fAny)    : ArgKind.AnyFloat,
-    !eq(vt, vAny)    : ArgKind.AnyVector,
-    !eq(vt, pAny)    : ArgKind.AnyPointer,
+    !eq(vt, Any)     : AnyKind.Any,
+    !eq(vt, iAny)    : AnyKind.AnyInteger,
+    !eq(vt, fAny)    : AnyKind.AnyFloat,
+    !eq(vt, vAny)    : AnyKind.AnyVector,
+    !eq(vt, pAny)    : AnyKind.AnyPointer,
   );
   let Sig = [
-    IIT_ARG.Number,
+    IIT_ANY.Number,
     OverloadIndexPlaceholder <ArgCode>.ret,
   ];
 
@@ -419,7 +419,7 @@ class LLVMQualPointerType<int addrspace>
 
   let Sig =
     !if(addrspace, [
-      IIT_ANYPTR.Number,
+      IIT_PTR_AS.Number,
       addrspace,
     ], [
       IIT_PTR.Number,
@@ -449,7 +449,7 @@ class LLVMFullyDependentType<int oidx, IIT_Base IIT_Info>
   // followed by the overload index of the overload type it depends on.
   let Sig = [
     IIT_Info.Number,
-    PackOverloadIndex<OverloadIndex, ArgKind.MatchType>.ret
+    PackOverloadIndex<OverloadIndex, AnyKind.MatchType>.ret
   ];
 }
 
@@ -490,7 +490,7 @@ class LLVMPartiallyDependentType<int oidx, IIT_Base IIT_Info>
 //
 // LLVMMatchType<0> therefore will match the return type, and
 // LLVMMatchType<2> will match the 3rd argument.
-class LLVMMatchType<int oidx> : LLVMFullyDependentType<oidx, IIT_ARG>;
+class LLVMMatchType<int oidx> : LLVMFullyDependentType<oidx, IIT_ANY>;
 
 // Match the type of another intrinsic parameter that is expected to be based on
 // an integral type (i.e. either iN or <N x iM>), but change the scalar size to
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index dae64cb757a33..0fe829c64ae7e 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -154,41 +154,43 @@ static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
   return Result;
 }
 
-static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
-                                        Module *M, FunctionType *FT,
+static std::string getIntrinsicNameImpl(Intrinsic::ID Id,
+                                        ArrayRef<Type *> OverloadTys, Module *M,
+                                        FunctionType *FT,
                                         bool EarlyModuleCheck) {
 
   assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
-  assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&
+  assert((OverloadTys.empty() || Intrinsic::isOverloaded(Id)) &&
          "This version of getName is for overloaded intrinsics only");
   (void)EarlyModuleCheck;
   assert((!EarlyModuleCheck || M ||
-          !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) &&
+          !any_of(OverloadTys, llvm::IsaPred<PointerType>)) &&
          "Intrinsic overloading on pointer types need to provide a Module");
   bool HasUnnamedType = false;
   std::string Result(Intrinsic::getBaseName(Id));
-  for (Type *Ty : Tys)
+  for (Type *Ty : OverloadTys)
     Result += "." + getMangledTypeStr(Ty, HasUnnamedType);
   if (HasUnnamedType) {
     assert(M && "unnamed types need a module");
     if (!FT)
-      FT = Intrinsic::getType(M->getContext(), Id, Tys);
+      FT = Intrinsic::getType(M->getContext(), Id, OverloadTys);
     else
-      assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&
+      assert(FT == Intrinsic::getType(M->getContext(), Id, OverloadTys) &&
              "Provided FunctionType must match arguments");
     return M->getUniqueIntrinsicName(Result, Id, FT);
   }
   return Result;
 }
 
-std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
+std::string Intrinsic::getName(ID Id, ArrayRef<Type *> OverloadTys, Module *M,
                                FunctionType *FT) {
   assert(M && "We need to have a Module");
-  return getIntrinsicNameImpl(Id, Tys, M, FT, true);
+  return getIntrinsicNameImpl(Id, OverloadTys, M, FT, true);
 }
 
-std::string Intrinsic::getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys) {
-  return getIntrinsicNameImpl(Id, Tys, nullptr, nullptr, false);
+std::string Intrinsic::getNameNoUnnamedTypes(ID Id,
+                                             ArrayRef<Type *> OverloadTys) {
+  return getIntrinsicNameImpl(Id, OverloadTys, nullptr, nullptr, false);
 }
 
 /// IIT_Info - These are enumerators that describe the entries returned by the
@@ -206,7 +208,7 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
               SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) {
   using namespace Intrinsic;
 
-  bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC);
+  bool IsScalableVector = LastInfo == IIT_SCALABLE_VEC;
 
   IIT_Info Info = IIT_Info(Infos[NextElt++]);
 
@@ -347,45 +349,50 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
   case IIT_PTR:
     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
     return;
-  case IIT_ANYPTR: // [ANYPTR addrspace]
+  case IIT_PTR_AS: // pointer with address space.
     OutputTable.push_back(
         IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
     return;
-  case IIT_ARG: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
-    OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
+  case IIT_ANY: {
+    unsigned OverloadInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    OutputTable.push_back(
+        IITDescriptor::get(IITDescriptor::Overloaded, OverloadInfo));
     return;
   }
   case IIT_EXTEND_ARG: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::ExtendArgument, ArgInfo));
+        IITDescriptor::get(IITDescriptor::Extend, OverloadIndex));
     return;
   }
   case IIT_TRUNC_ARG: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo));
+        IITDescriptor::get(IITDescriptor::Trunc, OverloadIndex));
     return;
   }
   case IIT_ONE_NTH_ELTS_VEC_ARG: {
-    unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned short OverloadIndex =
+        (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     unsigned short N = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
-    OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::OneNthEltsVecArgument, N, ArgNo));
+    OutputTable.push_back(IITDescriptor::get(IITDescriptor::OneNthEltsVec,
+                                             /*Hi=*/N, /*Lo=*/OverloadIndex));
     return;
   }
   case IIT_SAME_VEC_WIDTH_ARG: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::SameVecWidthArgument, ArgInfo));
+        IITDescriptor::get(IITDescriptor::SameVecWidth, OverloadIndex));
     return;
   }
   case IIT_VEC_OF_ANYPTRS_TO_ELT: {
-    unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
-    unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
-    OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));
+    unsigned short OverloadIndex =
+        (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned short RefOverloadIndex =
+        (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt,
+                                             /*Hi=*/RefOverloadIndex,
+                                             /*Lo=*/OverloadIndex));
     return;
   }
   case IIT_EMPTYSTRUCT:
@@ -402,21 +409,21 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
     return;
   }
   case IIT_SUBDIVIDE2_ARG: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::Subdivide2Argument, ArgInfo));
+        IITDescriptor::get(IITDescriptor::Subdivide2, OverloadIndex));
     return;
   }
   case IIT_SUBDIVIDE4_ARG: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::Subdivide4Argument, ArgInfo));
+        IITDescriptor::get(IITDescriptor::Subdivide4, OverloadIndex));
     return;
   }
   case IIT_VEC_ELEMENT: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::VecElementArgument, ArgInfo));
+        IITDescriptor::get(IITDescriptor::VecElement, OverloadIndex));
     return;
   }
   case IIT_SCALABLE_VEC: {
@@ -424,9 +431,9 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
     return;
   }
   case IIT_VEC_OF_BITCASTS_TO_INT: {
-    unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+    unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, ArgInfo));
+        IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, OverloadIndex));
     return;
   }
   }
@@ -482,7 +489,8 @@ void Intrinsic::getIntrinsicInfoTableEntries(
 }
 
 static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
-                             ArrayRef<Type *> Tys, LLVMContext &Context) {
+                             ArrayRef<Type *> OverloadTys,
+                             LLVMContext &Context) {
   using namespace Intrinsic;
 
   IITDescriptor D = Infos.front();
@@ -519,26 +527,30 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
   case IITDescriptor::Integer:
     return IntegerType::get(Context, D.IntegerWidth);
   case IITDescriptor::Vector:
-    return VectorType::get(DecodeFixedType(Infos, Tys, Context), D.VectorWidth);
+    return VectorType::get(DecodeFixedType(Infos, OverloadTys, Context),
+                           D.VectorWidth);
   case IITDescriptor::Pointer:
     return PointerType::get(Context, D.PointerAddressSpace);
   case IITDescriptor::Struct: {
     SmallVector<Type *, 8> Elts;
     for (unsigned i = 0, e = D.StructNumElements; i != e; ++i)
-      Elts.push_back(DecodeFixedType(Infos, Tys, Context));
+      Elts.push_back(DecodeFixedType(Infos, OverloadTys, Context));
     return StructType::get(Context, Elts);
   }
-  case IITDescriptor::Argument:
-    return Tys[D.getArgumentNumber()];
-  case IITDescriptor::ExtendArgument: {
-    Type *Ty = Tys[D.getArgumentNumber()];
+  // For any overload kind or partially dependent type, substitute it with the
+  // corresponding concrete type from OverloadTys.
+  case IITDescriptor::Overloaded:
+  case IITDescriptor::VecOfAnyPtrsToElt:
+    return OverloadTys[D.getOverloadIndex()];
+  case IITDescriptor::Extend: {
+    Type *Ty = OverloadTys[D.getOverloadIndex()];
     if (VectorType *VTy = dyn_cast<VectorType>(Ty))
       return VectorType::getExtendedElementVectorType(VTy);
 
     return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth());
   }
-  case IITDescriptor::TruncArgument: {
-    Type *Ty = Tys[D.getArgumentNumber()];
+  case IITDescriptor::Trunc: {
+    Type *Ty = OverloadTys[D.getOverloadIndex()];
     if (VectorType *VTy = dyn_cast<VectorType>(Ty))
       return VectorType::getTruncatedElementVectorType(VTy);
 
@@ -546,63 +558,61 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
     assert(ITy->getBitWidth() % 2 == 0);
     return IntegerType::get(Context, ITy->getBitWidth() / 2);
   }
-  case IITDescriptor::Subdivide2Argument:
-  case IITDescriptor::Subdivide4Argument: {
-    Type *Ty = Tys[D.getArgumentNumber()];
+  case IITDescriptor::Subdivide2:
+  case IITDescriptor::Subdivide4: {
+    Type *Ty = OverloadTys[D.getOverloadIndex()];
     VectorType *VTy = dyn_cast<VectorType>(Ty);
-    assert(VTy && "Expected an argument of Vector Type");
-    int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+    assert(VTy && "Expected overload type to be a Vector Type");
+    int SubDivs = D.Kind == IITDescriptor::Subdivide2 ? 1 : 2;
     return VectorType::getSubdividedVectorType(VTy, SubDivs);
   }
-  case IITDescriptor::OneNthEltsVecArgument:
+  case IITDescriptor::OneNthEltsVec:
     return VectorType::getOneNthElementsVectorType(
-        cast<VectorType>(Tys[D.getRefArgNumber()]), D.getVectorDivisor());
-  case IITDescriptor::SameVecWidthArgument: {
-    Type *EltTy = DecodeFixedType(Infos, Tys, Context);
-    Type *Ty = Tys[D.getArgumentNumber()];
+        cast<VectorType>(OverloadTys[D.getOverloadIndex()]),
+        D.getVectorDivisor());
+  case IITDescriptor::SameVecWidth: {
+    Type *EltTy = DecodeFixedType(Infos, OverloadTys, Context);
+    Type *Ty = OverloadTys[D.getOverloadIndex()];
     if (auto *VTy = dyn_cast<VectorType>(Ty))
       return VectorType::get(EltTy, VTy->getElementCount());
     return EltTy;
   }
-  case IITDescriptor::VecElementArgument: {
-    Type *Ty = Tys[D.getArgumentNumber()];
+  case IITDescriptor::VecElement: {
+    Type *Ty = OverloadTys[D.getOverloadIndex()];
     if (VectorType *VTy = dyn_cast<VectorType>(Ty))
       return VTy->getElementType();
-    llvm_unreachable("Expected an argument of Vector Type");
+    llvm_unreachable("Expected overload type to be a Vector Type");
   }
   case IITDescriptor::VecOfBitcastsToInt: {
-    Type *Ty = Tys[D.getArgumentNumber()];
+    Type *Ty = OverloadTys[D.getOverloadIndex()];
     VectorType *VTy = dyn_cast<VectorType>(Ty);
-    assert(VTy && "Expected an argument of Vector Type");
+    assert(VTy && "Expected overload type to be a Vector Type");
     return VectorType::getInteger(VTy);
   }
-  case IITDescriptor::VecOfAnyPtrsToElt:
-    // Return the overloaded type (which determines the pointers address space)
-    return Tys[D.getOverloadArgNumber()];
   }
   llvm_unreachable("unhandled");
 }
 
 FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
-                                 ArrayRef<Type *> Tys) {
+                                 ArrayRef<Type *> OverloadTys) {
   SmallVector<IITDescriptor, 8> Table;
   getIntrinsicInfoTableEntries(id, Table);
 
   ArrayRef<IITDescriptor> TableRef = Table;
-  Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
+  Type *ResultTy = DecodeFixedType(TableRef, OverloadTys, Context);
 
   SmallVector<Type *, 8> ArgTys;
   while (!TableRef.empty())
-    ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
+    ArgTys.push_back(DecodeFixedType(TableRef, OverloadTys, Context));
 
-  // DecodeFixedType returns Void for IITDescriptor::Void and
-  // IITDescriptor::VarArg If we see void type as the type of the last argument,
-  // it is vararg intrinsic
+  // VarArg intrinsics encode a void type as the last argument type. Detect that
+  // and then drop the void argument.
+  bool IsVarArg = false;
   if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) {
     ArgTys.pop_back();
-    return FunctionType::get(ResultTy, ArgTys, true);
+    IsVarArg = true;
   }
-  return FunctionType::get(ResultTy, ArgTys, false);
+  return FunctionType::get(ResultTy, ArgTys, IsVarArg);
 }
 
 bool Intrinsic::isOverloaded(ID id) {
@@ -732,15 +742,14 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
 #define GET_INTRINSIC_ATTRIBUTES
 #include "llvm/IR/IntrinsicImpl.inc"
 
-static Function *getOrInsertIntrinsicDeclarationImpl(Module *M,
-                                                     Intrinsic::ID id,
-                                                     ArrayRef<Type *> Tys,
-                                                     FunctionType *FT) {
-  Function *F = cast<Function>(
-      M->getOrInsertFunction(Tys.empty() ? Intrinsic::getName(id)
-                                         : Intrinsic::getName(id, Tys, M, FT),
-                             FT)
-          .getCallee());
+static Function *
+getOrInsertIntrinsicDeclarationImpl(Module *M, Intrinsic::ID id,
+                                    ArrayRef<Type *> OverloadTys,
+                                    FunctionType *FT) {
+  std::string Name = OverloadTys.empty()
+                         ? Intrinsic::getName(id).str()
+                         : Intrinsic::getName(id, OverloadTys, M, FT);
+  Function *F = cast<Function>(M->getOrInsertFunction(Name, FT).getCallee());
   if (F->getFunctionType() == FT)
     return F;
 
@@ -750,19 +759,15 @@ static Function *getOrInsertIntrinsicDeclarationImpl(Module *M,
   // invalid declaration and insert a new one with the correct signature. The
   // invalid declaration will get upgraded later.
   F->setName(F->getName() + ".invalid");
-  return cast<Function>(
-      M->getOrInsertFunction(Tys.empty() ? Intrinsic::getName(id)
-                                         : Intrinsic::getName(id, Tys, M, FT),
-                             FT)
-          .getCallee());
+  return cast<Function>(M->getOrInsertFunction(Name, FT).getCallee());
 }
 
 Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
-                                            ArrayRef<Type *> Tys) {
+                                            ArrayRef<Type *> OverloadTys) {
   // There can never be multiple globals with the same name of different types,
   // because intrinsics must be a specific type.
-  FunctionType *FT = getType(M->getContext(), id, Tys);
-  return getOrInsertIntrinsicDeclarationImpl(M, id, Tys, FT);
+  FunctionType *FT = getType(M->getContext(), id, OverloadTys);
+  return getOrInsertIntrinsicDeclarationImpl(M, id, OverloadTys, FT);
 }
 
 Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id, Type *RetTy,
@@ -799,9 +804,9 @@ Function *Intrinsic::getDeclarationIfExists(const Module *M, ID id) {
 }
 
 Function *Intrinsic::getDeclarationIfExists(Module *M, ID id,
-                                            ArrayRef<Type *> Tys,
+                                            ArrayRef<Type *> OverloadTys,
                                             FunctionType *FT) {
-  return M->getFunction(getName(id, Tys, M, FT));
+  return M->getFunction(getName(id, OverloadTys, M, FT));
 }
 
 // This defines the "Intrinsic::getIntrinsicForClangBuiltin()" method.
@@ -917,21 +922,21 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     return false;
   }
 
-  case IITDescriptor::Argument:
+  case IITDescriptor::Overloaded:
     // If this is the second occurrence of an argument,
     // verify that the later instance matches the previous instance.
-    if (D.getArgumentNumber() < ArgTys.size())
-      return Ty != ArgTys[D.getArgumentNumber()];
+    if (D.getOverloadIndex() < ArgTys.size())
+      return Ty != ArgTys[D.getOverloadIndex()];
 
-    if (D.getArgumentNumber() > ArgTys.size() ||
-        D.getArgumentKind() == IITDescriptor::AK_MatchType)
+    if (D.getOverloadIndex() > ArgTys.size() ||
+        D.getOverloadKind() == IITDescriptor::AK_MatchType)
       return IsDeferredCheck || DeferCheck(Ty);
 
-    assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&
+    assert(D.getOverloadIndex() == ArgTys.size() && !IsDeferredCheck &&
            "Table consistency error");
     ArgTys.push_back(Ty);
 
-    switch (D.getArgumentKind()) {
+    switch (D.getOverloadKind()) {
     case IITDescriptor::AK_Any:
       return false; // Success
     case IITDescriptor::AK_AnyInteger:
@@ -947,12 +952,12 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     }
     llvm_unreachable("all argument kinds not covered");
 
-  case IITDescriptor::ExtendArgument: {
+  case IITDescriptor::Extend: {
     // If this is a forward reference, defer the check for later.
-    if (D.getArgumentNumber() >= ArgTys.size())
+    if (D.getOverloadIndex() >= ArgTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
 
-    Type *NewTy = ArgTys[D.getArgumentNumber()];
+    Type *NewTy = ArgTys[D.getOverloadIndex()];
     if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
       NewTy = VectorType::getExtendedElementVectorType(VTy);
     else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
@@ -962,12 +967,12 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
 
     return Ty != NewTy;
   }
-  case IITDescriptor::TruncArgument: {
+  case IITDescriptor::Trunc: {
     // If this is a forward reference, defer the check for later.
-    if (D.getArgumentNumber() >= ArgTys.size())
+    if (D.getOverloadIndex() >= ArgTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
 
-    Type *NewTy = ArgTys[D.getArgumentNumber()];
+    Type *NewTy = ArgTys[D.getOverloadIndex()];
     if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
       NewTy = VectorType::getTruncatedElementVectorType(VTy);
     else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
@@ -977,11 +982,11 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
 
     return Ty != NewTy;
   }
-  case IITDescriptor::OneNthEltsVecArgument: {
+  case IITDescriptor::OneNthEltsVec: {
     // If this is a forward reference, defer the check for later.
-    if (D.getRefArgNumber() >= ArgTys.size())
+    if (D.getOverloadIndex() >= ArgTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
-    auto *VTy = dyn_cast<VectorType>(ArgTys[D.getRefArgNumber()]);
+    auto *VTy = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
     if (!VTy)
       return true;
     if (!VTy->getElementCount().isKnownMultipleOf(D.getVectorDivisor()))
@@ -989,13 +994,13 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     return VectorType::getOneNthElementsVectorType(VTy, D.getVectorDivisor()) !=
            Ty;
   }
-  case IITDescriptor::SameVecWidthArgument: {
-    if (D.getArgumentNumber() >= ArgTys.size()) {
+  case IITDescriptor::SameVecWidth: {
+    if (D.getOverloadIndex() >= ArgTys.size()) {
       // Defer check and subsequent check for the vector element type.
       Infos = Infos.slice(1);
       return IsDeferredCheck || DeferCheck(Ty);
     }
-    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
+    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
     auto *ThisArgType = dyn_cast<VectorType>(Ty);
     // Both must be vectors of the same number of elements or neither.
     if ((ReferenceType != nullptr) != (ThisArgType != nullptr))
@@ -1010,8 +1015,8 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
                               IsDeferredCheck);
   }
   case IITDescriptor::VecOfAnyPtrsToElt: {
-    unsigned RefArgNumber = D.getRefArgNumber();
-    if (RefArgNumber >= ArgTys.size()) {
+    unsigned RefOverloadIndex = D.getRefOverloadIndex();
+    if (RefOverloadIndex >= ArgTys.size()) {
       if (IsDeferredCheck)
         return true;
       // If forward referencing, already add the pointer-vector type and
@@ -1021,7 +1026,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     }
 
     if (!IsDeferredCheck) {
-      assert(D.getOverloadArgNumber() == ArgTys.size() &&
+      assert(D.getOverloadIndex() == ArgTys.size() &&
              "Table consistency error");
       ArgTys.push_back(Ty);
     }
@@ -1029,37 +1034,37 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
     // Verify the overloaded type "matches" the Ref type.
     // i.e. Ty is a vector with the same width as Ref.
     // Composed of pointers to the same element type as Ref.
-    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
+    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefOverloadIndex]);
     auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
     if (!ThisArgVecTy || !ReferenceType ||
         (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
       return true;
     return !ThisArgVecTy->getElementType()->isPointerTy();
   }
-  case IITDescriptor::VecElementArgument: {
-    if (D.getArgumentNumber() >= ArgTys.size())
+  case IITDescriptor::VecElement: {
+    if (D.getOverloadIndex() >= ArgTys.size())
       return IsDeferredCheck ? true : DeferCheck(Ty);
-    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
+    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
     return !ReferenceType || Ty != ReferenceType->getElementType();
   }
-  case IITDescriptor::Subdivide2Argument:
-  case IITDescriptor::Subdivide4Argument: {
+  case IITDescriptor::Subdivide2:
+  case IITDescriptor::Subdivide4: {
     // If this is a forward reference, defer the check for later.
-    if (D.getArgumentNumber() >= ArgTys.size())
+    if (D.getOverloadIndex() >= ArgTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
 
-    Type *NewTy = ArgTys[D.getArgumentNumber()];
+    Type *NewTy = ArgTys[D.getOverloadIndex()];
     if (auto *VTy = dyn_cast<VectorType>(NewTy)) {
-      int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+      int SubDivs = D.Kind == IITDescriptor::Subdivide2 ? 1 : 2;
       NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
       return Ty != NewTy;
     }
     return true;
   }
   case IITDescriptor::VecOfBitcastsToInt: {
-    if (D.getArgumentNumber() >= ArgTys.size())
+    if (D.getOverloadIndex() >= ArgTys.size())
       return IsDeferredCheck || DeferCheck(Ty);
-    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
+    auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
     auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
     if (!ThisArgVecTy || !ReferenceType)
       return true;
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 031ce978d21ce..ac78e8251df9a 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -475,8 +475,8 @@ PruningFunctionCloner::cloneInstruction(BasicBlock::const_iterator II) {
       for (unsigned I = 0, E = Descriptor.size(); I != E; ++I) {
         Intrinsic::IITDescriptor Operand = Descriptor[I];
         switch (Operand.Kind) {
-        case Intrinsic::IITDescriptor::Argument:
-          if (Operand.getArgumentKind() !=
+        case Intrinsic::IITDescriptor::Overloaded:
+          if (Operand.getOverloadKind() !=
               Intrinsic::IITDescriptor::AK_MatchType) {
             if (I == 0)
               TParams.push_back(OldInst.getType());
@@ -484,7 +484,7 @@ PruningFunctionCloner::cloneInstruction(BasicBlock::const_iterator II) {
               TParams.push_back(OldInst.getOperand(I - 1)->getType());
           }
           break;
-        case Intrinsic::IITDescriptor::SameVecWidthArgument:
+        case Intrinsic::IITDescriptor::SameVecWidth:
           ++I;
           break;
         default:
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index 5a2b2f89d5582..bda911b50d813 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -54,7 +54,7 @@ class IntrinsicEmitter {
   void run(raw_ostream &OS, bool Enums);
 
   void EmitEnumInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
-  void EmitArgKind(raw_ostream &OS);
+  void EmitAnyKind(raw_ostream &OS);
   void EmitIITInfo(raw_ostream &OS);
   void EmitTargetInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
   void EmitIntrinsicToNameTable(const CodeGenIntrinsicTable &Ints,
@@ -97,8 +97,8 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) {
     // Emit the enum information.
     EmitEnumInfo(Ints, OS);
 
-    // Emit ArgKind for Intrinsics.h.
-    EmitArgKind(OS);
+    // Emit AnyKind for Intrinsics.h.
+    EmitAnyKind(OS);
   } else {
     // Emit IIT_Info constants.
     EmitIITInfo(OS);
@@ -199,16 +199,16 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
     OS << "}; // enum\n";
 }
 
-void IntrinsicEmitter::EmitArgKind(raw_ostream &OS) {
+void IntrinsicEmitter::EmitAnyKind(raw_ostream &OS) {
   if (!IntrinsicPrefix.empty())
     return;
-  IfDefEmitter IfDef(OS, "GET_INTRINSIC_ARGKIND");
-  OS << "// llvm::Intrinsic::IITDescriptor::ArgKind.\n";
-  if (const auto RecArgKind = Records.getDef("ArgKind")) {
-    for (const auto &RV : RecArgKind->getValues())
+  IfDefEmitter IfDef(OS, "GET_INTRINSIC_ANYKIND");
+  OS << "// llvm::Intrinsic::IITDescriptor::AnyKind.\n";
+  if (const auto RecAnyKind = Records.getDef("AnyKind")) {
+    for (const auto &RV : RecAnyKind->getValues())
       OS << "    AK_" << RV.getName() << " = " << *RV.getValue() << ",\n";
   } else {
-    OS << "#error \"ArgKind is not defined\"\n";
+    OS << "#error \"AnyKind is not defined\"\n";
   }
 }
 



More information about the llvm-commits mailing list