[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