[llvm] [NFC][LLVM] Refactor IIT_ANY payload for vector/element constraint (PR #203506)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 04:22:58 PDT 2026


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

Change `IIT_ANY` payload from a single packed OverloadIndex + AnyKind byte to 2 bytes:
- An 8 bit OverloadIndex
- An 8 pit packed vector + element type constraint.

This will enable `IIT_ANY` to express constraints on the overload type is a more general fashion compared to a flat `AnyKind` enum.

>From 265f5587bb45f1211f2f5b158b4cd568c6809f92 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 10 Jun 2026 08:53:18 -0700
Subject: [PATCH] [NFC][LLVM] Refactor IIT_ANY payload for vector/element
 constraint

Change `IIT_ANY` payload from a single packed OverloadIndex + AnyKind
byte to 2 bytes:
- An 8 bit OverloadIndex
- An 8 pit packed vector + element type constraint.

This will enable `IIT_ANY` to express constraints on the overload type
is a more general fashion compared to a flat `AnyKind` enum.
---
 llvm/include/llvm/IR/Intrinsics.h             |  22 ++--
 llvm/include/llvm/IR/Intrinsics.td            | 119 ++++++++++--------
 llvm/lib/IR/Intrinsics.cpp                    |  81 +++++++++---
 .../TableGen/intrinsic-overload-index-oor.td  |  38 ++++++
 llvm/test/TableGen/intrinsic-struct.td        |  27 ++--
 .../utils/TableGen/Basic/IntrinsicEmitter.cpp |  41 +++---
 6 files changed, 224 insertions(+), 104 deletions(-)
 create mode 100644 llvm/test/TableGen/intrinsic-overload-index-oor.td

diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 5ccb18d7281bc..c2411c894d975 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -206,11 +206,10 @@ struct IITDescriptor {
     ElementCount VectorWidth;
   };
 
-  // AK_% : Defined in Intrinsics.td
-  enum AnyKind {
-#define GET_INTRINSIC_ANYKIND
+  // AnyKindVectorConstraint and AnyKindElementConstraint defined in
+  // Intrinsics.td
+#define GET_INTRINSIC_ANYKIND_ENUMS
 #include "llvm/IR/IntrinsicEnums.inc"
-  };
 
   unsigned getOverloadIndex() const {
     assert(Kind == Overloaded || Kind == Match || Kind == Extend ||
@@ -218,14 +217,19 @@ struct IITDescriptor {
            Kind == Subdivide2 || Kind == Subdivide4 ||
            Kind == VecOfBitcastsToInt || Kind == VecOfAnyPtrsToElt ||
            Kind == OneNthEltsVec);
-    // Overload index is packed into lower 5 bits.
-    return OverloadInfo & 0x1f;
+    // Overload index is packed into byte[0] of OverloadInfo.
+    return OverloadInfo & 0xf;
   }
 
-  AnyKind getOverloadKind() const {
-    // Overload kind is packed into upper 3 bits.
+  std::pair<AnyKindVectorConstraint, AnyKindElementConstraint>
+  getOverloadConstraints() const {
+    // Overload constraints are packed into byte[1] of OverloadInfo.
     assert(Kind == Overloaded);
-    return (AnyKind)((OverloadInfo >> 5) & 0x7);
+    uint8_t AKEnumsPacked = OverloadInfo >> 8;
+    AnyKindVectorConstraint VC = (AnyKindVectorConstraint)(AKEnumsPacked >> 4);
+    AnyKindElementConstraint EC =
+        (AnyKindElementConstraint)(AKEnumsPacked & 0xf);
+    return {VC, EC};
   }
 
   // OneNthEltsVecArguments uses both a divisor N and a reference argument for
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index b1b2bb2a72c65..0b3a79debfa59 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -238,37 +238,36 @@ def IntrTriviallyScalarizable : IntrinsicProperty;
 // IIT constants and utils
 //===----------------------------------------------------------------------===//
 
-// llvm::Intrinsic::IITDescriptor::AnyKind::AK_%
-def AnyKind {
-  int Any        = 0;
-  int AnyInteger = 1;
-  int AnyFloat   = 2;
-  int AnyVector  = 3;
-  int AnyPointer = 4;
+// llvm::Intrinsic::IITDescriptor::AnyKindVectorConstraint::VC_%
+def AnyKindVectorConstraint {
+  int None   = 0;
+  int Vector = 1;
+  int Scalar = 2;
 }
 
-// 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 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 AnyKindVal> {
-  int ID = 0x100;
-  int ret = !or(ID, AnyKindVal);
+// llvm::Intrinsic::IITDescriptor::AnyKindElementConstraint::EC_%
+def AnyKindElementConstraint {
+  int None    = 0;
+  int Integer = 1;
+  int Float   = 2;
+  int Pointer = 3;
 }
 
-// This class defines how the overload index and the arg kind are actually
-// packed into a single byte for the final IIT table encoding. Overload index is
-// packed in low 5 bits, argument kind is packed in upper 3 bits. This enables
-// 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 AnyKindVal> {
-  assert !lt(OverloadIndex, 32), "Cannot support more than 32 overload types";
-  assert !lt(AnyKindVal, 8), "Cannot support more than 8 argument kinds";
-  int ret = !or(!shl(AnyKindVal, 5), OverloadIndex);
+// Placeholder to encode the overload index of the current type. We encode a
+// value > 255 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). Note that this is just a
+// transient representation till it gets processed by `PatchOverloadIndex`
+// below, so this is *not* the encoding of the final type signature.
+defvar OverloadIndexPlaceholder = 0x100;
+
+// This class verifies that the overload index is valid for the final IIT table
+// encoding. Overload index has a single byte assigned in the IIT encoding, so
+// verify that its >= 0 and <= 255.
+class VerifyOverloadIndex<int OverloadIndex> {
+  assert !ge(OverloadIndex, 0), "overload index must be >= 0";
+  assert !lt(OverloadIndex, 256), "cannot support more than 256 overload types";
+  int ret = OverloadIndex;
 }
 
 // This class handles the actual patching of the overload index into a component
@@ -276,11 +275,11 @@ class PackOverloadIndex<int OverloadIndex, int AnyKindVal> {
 // value generated by OverloadIndexPlaceholder and patching is needed, else the
 // value is left unchanged.
 class PatchOverloadIndex<int Sig, int OverloadIndex> {
-  int AnyKindVal = !and(Sig, 0x7);
-  int ret = !cond(
-    // If the value is > 255, it indicates that patching is needed.
-    !gt(Sig, 255) : PackOverloadIndex<OverloadIndex, AnyKindVal>.ret,
-    true: Sig);
+  // If the value is equal to `OverloadIndexPlaceholder`, it indicates that
+  // patching is needed by replacing it with this type's overload index.
+  int ret = !if(!eq(Sig, OverloadIndexPlaceholder),
+                VerifyOverloadIndex<OverloadIndex>.ret,
+                Sig);
 }
 
 //===----------------------------------------------------------------------===//
@@ -400,17 +399,18 @@ class LLVMType<ValueType vt> {
     !foreach(iit, IITs,     iit.Number));
 }
 
-class LLVMAnyType<ValueType vt> : LLVMType<vt> {
-  int ArgCode = !cond(
-    !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,
-  );
+class LLVMAnyType<ValueType vt, int VecKind, int ElemKind> : LLVMType<vt> {
   let Sig = [
     IIT_ANY.Number,
-    OverloadIndexPlaceholder <ArgCode>.ret,
+
+    // The first byte of the IIT_ANY payload is the overload index of this type.
+    // Here we use `OverloadIndexPlaceholder` which will be updated to the
+    // overload index in `PatchOverloadIndex`.
+    OverloadIndexPlaceholder,
+
+    // The second byte of IIT_ANY payload is the packed AnyKindVectorConstraint
+    // and AnyKindElementConstraint.
+    !or(!shl(VecKind, 4), ElemKind)
   ];
 
   assert VT.isOverloaded, "LLVMAnyType.VT should have isOverloaded";
@@ -431,7 +431,9 @@ class LLVMQualPointerType<int addrspace>
 }
 
 // Note: CodeGenIntrinsics.cpp seems to check this class to check pointers.
-class LLVMAnyPointerType : LLVMAnyType<pAny>;
+class LLVMAnyPointerType : LLVMAnyType<pAny,
+                                       AnyKindVectorConstraint.None,
+                                       AnyKindElementConstraint.Pointer>;
 
 // Dependent types: These are types that depend on another LLVMAnyType overload
 // type. There are 2 subclasses of dependent types:
@@ -453,7 +455,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, 0>.ret
+    VerifyOverloadIndex<OverloadIndex>.ret
   ];
 }
 
@@ -464,10 +466,10 @@ class LLVMPartiallyDependentType<int oidx, IIT_Base IIT_Info>
   // overload type its depends on.
   let Sig = [
     IIT_Info.Number,
-    // This types overload index, arg kind ignored.
-    OverloadIndexPlaceholder<0>.ret,
-    // Overload index of the reference overload type, arg kind ignored.
-    PackOverloadIndex<OverloadIndex, 0>.ret,
+    // This types overload index.
+    OverloadIndexPlaceholder,
+    // Overload index of the reference overload type.
+    VerifyOverloadIndex<OverloadIndex>.ret,
   ];
 }
 
@@ -509,8 +511,8 @@ class LLVMScalarOrSameVectorWidth<int oidx, LLVMType elty>
   : LLVMFullyDependentType<oidx, IIT_SAME_VEC_WIDTH_ARG> {
   let Sig = !listconcat([
     IIT_SAME_VEC_WIDTH_ARG.Number,
-    // Overload index of the reference overload type, arg kind ignored.
-    PackOverloadIndex<OverloadIndex, 0>.ret,
+    // Overload index of the reference overload type.
+    VerifyOverloadIndex<OverloadIndex>.ret,
   ], elty.Sig);
 }
 
@@ -523,7 +525,7 @@ class LLVMOneNthElementsVectorType<int oidx, int n>
   : LLVMFullyDependentType<oidx, IIT_ONE_NTH_ELTS_VEC_ARG> {
   let Sig = [
     IIT_ONE_NTH_ELTS_VEC_ARG.Number,
-    PackOverloadIndex<OverloadIndex, 0>.ret,
+    VerifyOverloadIndex<OverloadIndex>.ret,
     n,
   ];
 }
@@ -550,10 +552,19 @@ class LLVMVectorOfAnyPointersToElt<int oidx>
 
 def llvm_void_ty       : LLVMType<isVoid>;
 
-def llvm_any_ty        : LLVMAnyType<Any>;
-def llvm_anyint_ty     : LLVMAnyType<iAny>;
-def llvm_anyfloat_ty   : LLVMAnyType<fAny>;
-def llvm_anyvector_ty  : LLVMAnyType<vAny>;
+def llvm_any_ty        : LLVMAnyType<Any,
+                                     AnyKindVectorConstraint.None,
+                                     AnyKindElementConstraint.None>;
+def llvm_anyint_ty     : LLVMAnyType<iAny,
+                                     AnyKindVectorConstraint.None,
+                                     AnyKindElementConstraint.Integer>;
+def llvm_anyfloat_ty   : LLVMAnyType<fAny,
+                                     AnyKindVectorConstraint.None,
+                                     AnyKindElementConstraint.Float>;
+def llvm_anyvector_ty  : LLVMAnyType<vAny,
+                                     AnyKindVectorConstraint.Vector,
+                                     AnyKindElementConstraint.None>;
+
 def llvm_anyptr_ty     : LLVMAnyPointerType;      // ptr addrspace(N)
 
 def llvm_i1_ty         : LLVMType<i1>;
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index b0bad878f0c6f..3d7f43cf1ea19 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -371,9 +371,11 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
         IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
     return;
   case IIT_ANY: {
-    unsigned OverloadInfo = Infos[NextElt++];
+    unsigned OverloadIndex = Infos[NextElt++];
+    unsigned ArgKindEnums = Infos[NextElt++];
+    unsigned Packed = (ArgKindEnums << 8) | OverloadIndex;
     OutputTable.push_back(
-        IITDescriptor::get(IITDescriptor::Overloaded, OverloadInfo));
+        IITDescriptor::get(IITDescriptor::Overloaded, Packed));
     return;
   }
   case IIT_MATCH: {
@@ -1076,20 +1078,69 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
            "Table consistency error");
     OverloadTys.push_back(Ty);
 
-    switch (D.getOverloadKind()) {
-    case IITDescriptor::AK_Any:
-      return false; // Success
-    case IITDescriptor::AK_AnyInteger:
-      return PrintMsg(Ty->isIntOrIntVectorTy(), "any integer or integer vector",
-                      OIdx);
-    case IITDescriptor::AK_AnyFloat:
-      return PrintMsg(Ty->isFPOrFPVectorTy(), "any fp or fp vector", OIdx);
-    case IITDescriptor::AK_AnyVector:
-      return PrintMsg(isa<VectorType>(Ty), "any vector type", OIdx);
-    case IITDescriptor::AK_AnyPointer:
-      return PrintMsg(isa<PointerType>(Ty), "any pointer type", OIdx);
+    IITDescriptor::AnyKindVectorConstraint VC;
+    IITDescriptor::AnyKindElementConstraint EC;
+    std::tie(VC, EC) = D.getOverloadConstraints();
+
+    bool IsValid = true;
+    switch (VC) {
+    case IITDescriptor::VC_None:
+      break;
+    case IITDescriptor::VC_Vector:
+      IsValid &= isa<VectorType>(Ty);
+      break;
+    case IITDescriptor::VC_Scalar:
+      IsValid &= !isa<VectorType>(Ty);
+      break;
+    }
+
+    Type *ETy = Ty->getScalarType();
+    switch (EC) {
+    case IITDescriptor::EC_None:
+      break;
+    case IITDescriptor::EC_Integer:
+      IsValid &= ETy->isIntegerTy();
+      break;
+    case IITDescriptor::EC_Float:
+      IsValid &= ETy->isFloatingPointTy();
+      break;
+    case IITDescriptor::EC_Pointer:
+      IsValid &= ETy->isPointerTy();
+      break;
+    }
+
+    if (IsValid)
+      return false;
+
+    static constexpr StringLiteral VectorKinds[] = {
+        "",
+        "vector",
+        "scalar",
+    };
+    static constexpr StringLiteral ElementKinds[] = {
+        "",
+        "integer",
+        "fp",
+        "pointer",
+    };
+
+    if (EC == IITDescriptor::EC_None) {
+      // No constraint on element type.
+      // Expected = any {vector | scalar} type.
+      StringLiteral VK = ArrayRef(VectorKinds)[VC];
+      return PrintMsg(false, formatv("any {} type", VK), OIdx);
+    }
+
+    StringLiteral EK = ArrayRef(ElementKinds)[EC];
+    switch (VC) {
+    case IITDescriptor::VC_None:
+      // Expected = any EK or EK vector.
+      return PrintMsg(false, formatv("any {0} or {0} vector", EK), OIdx);
+    case IITDescriptor::VC_Vector:
+      return PrintMsg(false, formatv("any {} vector", EK), OIdx);
+    case IITDescriptor::VC_Scalar:
+      return PrintMsg(false, formatv("any {} type", EK), OIdx);
     }
-    llvm_unreachable("all argument kinds not covered");
   }
 
   case IITDescriptor::Match: {
diff --git a/llvm/test/TableGen/intrinsic-overload-index-oor.td b/llvm/test/TableGen/intrinsic-overload-index-oor.td
new file mode 100644
index 0000000000000..1ff08f19c573a
--- /dev/null
+++ b/llvm/test/TableGen/intrinsic-overload-index-oor.td
@@ -0,0 +1,38 @@
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST0 2>&1 | FileCheck %s --check-prefix=CHECK-TEST0
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST1 2>&1 | FileCheck %s --check-prefix=CHECK-TEST1
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST2 2>&1 | FileCheck %s --check-prefix=CHECK-TEST2
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST3 2>&1 | FileCheck %s --check-prefix=CHECK-TEST3
+
+#define TEST_INTRINSICS_SUPPRESS_DEFS
+include "llvm/IR/Intrinsics.td"
+
+// Check for invalid overload index.
+
+#ifdef TEST0
+// Overload index inferred for argument type.
+
+// CHECK-TEST0: error: assertion failed: cannot support more than 256 overload types
+def int_tes : Intrinsic<[], !listsplat(llvm_anyint_ty, 257)>;
+#endif // TEST0
+
+#ifdef TEST1
+// Overload index inferred for return type.
+
+// CHECK-TEST1: error: assertion failed: cannot support more than 256 overload types
+def int_test : Intrinsic<!listsplat(llvm_anyint_ty, 257),[]>;
+#endif // TEST1
+
+#ifdef TEST2
+// Overload index OOR with combination of argument and return types.
+
+// CHECK-TEST2: error: assertion failed: cannot support more than 256 overload types
+def int_test : Intrinsic<!listsplat(llvm_anyint_ty, 250),
+                         !listsplat(llvm_anyint_ty, 7)>;
+#endif // TEST2
+
+#ifdef TEST3
+// Invalid negative overload index.
+// CHECK-TEST3: rror: assertion failed: overload index must be >= 0
+def int_test : Intrinsic<[llvm_anyint_ty],
+                         [LLVMMatchType<-1>]>;
+#endif // TEST3
diff --git a/llvm/test/TableGen/intrinsic-struct.td b/llvm/test/TableGen/intrinsic-struct.td
index 8ecdcc854adc3..4fdc7b0c6d5e1 100644
--- a/llvm/test/TableGen/intrinsic-struct.td
+++ b/llvm/test/TableGen/intrinsic-struct.td
@@ -1,9 +1,8 @@
-// RUN: llvm-tblgen -gen-intrinsic-enums -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS | FileCheck %s --check-prefix=CHECK-ENUM
-// RUN: llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS | FileCheck %s --check-prefix=CHECK-IMPL
-// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS -DENABLE_ERROR 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
-
-// XFAIL: vg_leak
+// RUN: llvm-tblgen -gen-intrinsic-enums -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-ENUM
+// RUN: llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s  | FileCheck %s --check-prefix=CHECK-IMPL
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DENABLE_ERROR 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
 
+#define TEST_INTRINSICS_SUPPRESS_DEFS
 include "llvm/IR/Intrinsics.td"
 
 // Make sure we can return up to 257 values. Intrinsics are in alphabetical order.
@@ -16,17 +15,21 @@ include "llvm/IR/Intrinsics.td"
 
 // Make sure the encoding table is correctly generated.
 // CHECK-IMPL: IIT_LongEncodingTable
+// CHECK-IMPL-NEXT: 21, 0
+// CHECK-IMPL-SAME: 15, 0, 1, 15, 1, 1, 0
+
+// CHECK-IMPL-NEXT: 21, 7
+// CHECK-IMPL-SAME: 15, 0, 1, 15, 1, 1, 15, 2, 1, 15, 3, 1, 15, 4, 1, 15, 5, 1
+// CHECK-IMPL-SAME: 15, 6, 1, 15, 7, 1, 15, 8, 1, 0
+
+// CHECK-IMPL-NEXT: 21, 8
+// CHECK-IMPL-SAME: 15, 0, 1, 15, 1, 1, 15, 2, 1, 15, 3, 1, 15, 4, 1, 15, 5, 1
+// CHECK-IMPL-SAME: 15, 6, 1, 15, 7, 1, 15, 8, 1, 15, 9, 1, 0
+
 // CHECK-IMPL-NEXT: 21, 255
 // There should be list of 257 '4's (IIT code for i32) followed by 0. We just
 // match the suffix that ends with 0 (IIT_Done).
 // CHECK-IMPL-SAME: 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0
-// CHECK-IMPL-NEXT: 15, 32, 0
-// CHECK-IMPL-NEXT: 21, 0
-// CHECK-IMPL-SAME: 15, 32, 15, 33, 0
-// CHECK-IMPL-NEXT: 21, 7
-// CHECK-IMPL-SAME: 15, 32, 15, 33, 15, 34, 15, 35, 15, 36, 15, 37, 15, 38, 15, 39, 15, 40, 0,
-// CHECK-IMPL-NEXT: 21, 8
-// CHECK-IMPL-SAME: 15, 32, 15, 33, 15, 34, 15, 35, 15, 36, 15, 37, 15, 38, 15, 39, 15, 40, 15, 41, 0,
 def int_returns_a0_results : Intrinsic<
                              [],
                              [], []>;
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index 02b2cd9850997..350458434a275 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 EmitAnyKind(raw_ostream &OS);
+  void EmitAnyKindEnums(raw_ostream &OS);
   void EmitIITInfo(raw_ostream &OS);
   void EmitTargetInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
   void EmitIntrinsicToNameTable(const CodeGenIntrinsicTable &Ints,
@@ -99,8 +99,8 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) {
     // Emit the enum information.
     EmitEnumInfo(Ints, OS);
 
-    // Emit AnyKind for Intrinsics.h.
-    EmitAnyKind(OS);
+    // Emit AnyKind enums for Intrinsics.h.
+    EmitAnyKindEnums(OS);
   } else {
     // Emit IIT_Info constants.
     EmitIITInfo(OS);
@@ -204,17 +204,26 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
     OS << "}; // enum\n";
 }
 
-void IntrinsicEmitter::EmitAnyKind(raw_ostream &OS) {
+void IntrinsicEmitter::EmitAnyKindEnums(raw_ostream &OS) {
   if (!IntrinsicPrefix.empty())
     return;
-  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 \"AnyKind is not defined\"\n";
-  }
+  IfDefEmitter IfDef(OS, "GET_INTRINSIC_ANYKIND_ENUMS");
+
+  auto GenerateAnyKindEnums = [&OS, this](StringRef EnumName,
+                                          StringRef Prefix) {
+    OS << "// llvm::Intrinsic::IITDescriptor::" << EnumName << "\n";
+    if (const Record *EnumDef = Records.getDef(EnumName)) {
+      OS << "enum " << EnumName << " {\n";
+      for (const auto &RV : EnumDef->getValues())
+        OS << "  " << Prefix << RV.getName() << " = " << *RV.getValue()
+           << ",\n";
+      OS << "}; // " << EnumName << "\n\n";
+    } else {
+      OS << "#error \"" << EnumName << " is not defined\"\n";
+    }
+  };
+  GenerateAnyKindEnums("AnyKindVectorConstraint", "VC_");
+  GenerateAnyKindEnums("AnyKindElementConstraint", "EC_");
 }
 
 void IntrinsicEmitter::EmitIITInfo(raw_ostream &OS) {
@@ -330,8 +339,12 @@ static TypeSigTy ComputeTypeSignature(const CodeGenIntrinsic &Int) {
   const Record *TypeInfo = Int.TheDef->getValueAsDef("TypeInfo");
   const ListInit *TypeList = TypeInfo->getValueAsListInit("TypeSig");
 
-  for (const auto *TypeListEntry : TypeList->getElements())
-    TypeSig.emplace_back(cast<IntInit>(TypeListEntry)->getValue());
+  for (const auto *TypeListEntry : TypeList->getElements()) {
+    int64_t Value = cast<IntInit>(TypeListEntry)->getValue();
+    if (Value < 0 || Value > 255)
+      PrintFatalError(Int.TheDef, "Unresolved type signature");
+    TypeSig.emplace_back(Value);
+  }
   return TypeSig;
 }
 



More information about the llvm-commits mailing list