[llvm] [LLVM-Tablegen] Except predicate for overloaded intrinsics with constraints (PR #175445)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 11 08:55:09 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-tablegen
Author: Dharuni R Acharya (DharuniRAcharya)
<details>
<summary>Changes</summary>
Depends on #<!-- -->172442.
This patch introduces an `Except` constraint for overloaded intrinsics to exclude specific type
combinations produced by `AnyTypeOf/NoneTypeOf` products.
This PR builds on the explicit type constraint infrastructure introduced in PR #<!-- -->172442.
The first 4 commits are from the base PR; only the final commit adds the Except predicate.
Link to the RFC, where this feature was discussed:
https://discourse.llvm.org/t/rfc-tablegen-explicit-type-constraints-for-overloaded-llvm-intrinsics/89142
---
Patch is 41.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/175445.diff
9 Files Affected:
- (modified) llvm/include/llvm/IR/Intrinsics.h (+37)
- (modified) llvm/include/llvm/IR/Intrinsics.td (+74)
- (modified) llvm/include/llvm/IR/IntrinsicsNVVM.td (+21)
- (modified) llvm/lib/IR/Intrinsics.cpp (+559-16)
- (modified) llvm/lib/IR/Verifier.cpp (+9)
- (added) llvm/test/CodeGen/NVPTX/anytypeof_constraints_invalid.ll (+65)
- (added) llvm/test/CodeGen/NVPTX/anytypeof_constraints_valid.ll (+51)
- (added) llvm/test/TableGen/overloaded-intrinsic-constraints.td (+43)
- (modified) llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp (+28)
``````````diff
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 2c86a43e114ea..89e2239028329 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -181,6 +181,10 @@ namespace Intrinsic {
AMX,
PPCQuad,
AArch64Svcount,
+ ArgumentTypeConstraint, // For AnyTypeOf - marks constrained argument
+ // types.
+ ArgumentTypeExclusion, // For NoneTypeOf - marks excluded argument types.
+ ExceptConstraint, // For Except - marks excluded combinations.
} Kind;
union {
@@ -189,6 +193,7 @@ namespace Intrinsic {
unsigned Pointer_AddressSpace;
unsigned Struct_NumElements;
unsigned Argument_Info;
+ unsigned Argument_NumConstraints;
ElementCount Vector_Width;
};
@@ -231,6 +236,26 @@ namespace Intrinsic {
return Argument_Info & 0xFFFF;
}
+ // For ArgumentTypeConstraint: get number of allowed types.
+ unsigned getArgumentNumConstraints() const {
+ assert(Kind == ArgumentTypeConstraint);
+ return Argument_NumConstraints;
+ }
+
+ // For ArgumentTypeExclusion: get number of excluded types.
+ unsigned getArgumentNumExclusions() const {
+ assert(Kind == ArgumentTypeExclusion);
+ return Argument_NumConstraints;
+ }
+
+ // For ExceptConstraint: get number of combinations and size.
+ std::pair<unsigned, unsigned> getExceptInfo() const {
+ assert(Kind == ExceptConstraint);
+ unsigned NumCombos = Argument_Info >> 16;
+ unsigned ComboSize = Argument_Info & 0xFFFF;
+ return {NumCombos, ComboSize};
+ }
+
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
IITDescriptor Result = { K, { Field } };
return Result;
@@ -248,6 +273,14 @@ namespace Intrinsic {
Result.Vector_Width = ElementCount::get(Width, IsScalable);
return Result;
}
+
+ static IITDescriptor getExcept(unsigned NumCombos, unsigned ComboSize) {
+ assert(NumCombos <= 0xFFFF && "NumCombos exceeds 16 bits");
+ assert(ComboSize <= 0xFFFF && "ComboSize exceeds 16 bits");
+ return get(ExceptConstraint,
+ static_cast<unsigned short>(NumCombos),
+ static_cast<unsigned short>(ComboSize));
+ }
};
/// Return the IIT table descriptor for the specified intrinsic into an array
@@ -278,6 +311,10 @@ namespace Intrinsic {
LLVM_ABI bool matchIntrinsicVarArg(bool isVarArg,
ArrayRef<IITDescriptor> &Infos);
+ /// Verify type constraints for AnyTypeOf constrained intrinsics.
+ LLVM_ABI bool verifyIntrinsicTypeConstraints(ID id, FunctionType *FTy,
+ std::string &ErrMsg);
+
/// Gets the type arguments of an intrinsic call by matching type contraints
/// specified by the .td file. The overloaded types are pushed into the
/// AgTys vector.
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index c56b0185b4f1e..199dd48cdfb6f 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -372,6 +372,10 @@ def IIT_V6 : IIT_Vec<6, 50>;
def IIT_V10 : IIT_Vec<10, 51>;
def IIT_V2048 : IIT_Vec<2048, 52>;
def IIT_V4096 : IIT_Vec<4096, 53>;
+// Constrained type encoding for overloaded intrinsics.
+def IIT_ANYTYPE : IIT_Base<93>;
+def IIT_NONETYPE : IIT_Base<94>;
+def IIT_EXCEPT : IIT_Base<95>;
}
defvar IIT_all_FixedTypes = !filter(iit, IIT_all,
@@ -448,6 +452,63 @@ class LLVMAnyPointerType : LLVMAnyType<pAny> {
assert isAny, "pAny should have isOverloaded";
}
+// AnyTypeOf: Constrain overloaded type to specific set of allowed types.
+// Encoding follows the pattern: [IIT_ARG, EncAny, IIT_ANYTYPE, count, type_sigs...].
+class AnyTypeOf<list<LLVMType> allowed_types> : LLVMAnyType<Any> {
+ list<LLVMType> AllowedTypes = allowed_types;
+
+ // Validation: specifying maximal 255 number of allowed types.
+ assert !le(!size(allowed_types), 255),
+ "AnyTypeOf cannot exceed 255 allowed types";
+
+ let Sig = !listconcat(
+ [IIT_ARG.Number, EncAnyType<ArgCode>.ret],
+ [IIT_ANYTYPE.Number, !size(allowed_types)],
+ !foldl([]<int>, allowed_types, accum, ty,
+ !listconcat(accum, ty.Sig))
+ );
+}
+
+// NoneTypeOf: Exclude specific types from overloaded type (inverse of AnyTypeOf).
+// Encoding follows the pattern: [IIT_ARG, EncAny, IIT_NONETYPE, count, type_sigs...].
+class NoneTypeOf<list<LLVMType> excluded_types> : LLVMAnyType<Any> {
+ list<LLVMType> ExcludedTypes = excluded_types;
+
+ // Validation: specifying maximal 255 number of excluded types.
+ assert !le(!size(excluded_types), 255),
+ "NoneTypeOf cannot exceed 255 excluded types";
+
+ let Sig = !listconcat(
+ [IIT_ARG.Number, EncAnyType<ArgCode>.ret],
+ [IIT_NONETYPE.Number, !size(excluded_types)],
+ !foldl([]<int>, excluded_types, accum, ty,
+ !listconcat(accum, ty.Sig))
+ );
+}
+
+// Except: To constraint specific combinations allowed by cartesian product of AnyTypeOfs/NoneTypeOfs.
+// Encoding: [IIT_EXCEPT, num_combinations, combo_size, type_sigs...]
+class Except<list<list<LLVMType>> invalid_combinations> {
+ list<list<LLVMType>> InvalidCombinations = invalid_combinations;
+
+ // Validate: at least one combination.
+ assert !gt(!size(invalid_combinations), 0),
+ "Except must have at least one invalid combination";
+
+ // Validate: all combinations have same size.
+ defvar first_size = !size(!head(invalid_combinations));
+ assert !foldl(1, invalid_combinations, valid, combo,
+ !and(valid, !eq(!size(combo), first_size))),
+ "All Except combinations must have the same number of types";
+
+ list<int> Sig = !listconcat(
+ [IIT_EXCEPT.Number, !size(invalid_combinations), first_size],
+ !foldl([]<int>, invalid_combinations, accum, combo,
+ !listconcat(accum, !foldl([]<int>, combo, accum2, ty,
+ !listconcat(accum2, ty.Sig))))
+ );
+}
+
// Match the type of another intrinsic parameter. Number is an index into the
// list of overloaded types for the intrinsic, excluding all the fixed types.
// The Number value must refer to a previously listed type. For example:
@@ -743,6 +804,19 @@ class DefaultAttrsIntrinsic<list<LLVMType> ret_types,
intr_properties, name,
sd_properties, /*disable_default_attributes*/ 0> {}
+class IntrinsicWithExcept<list<LLVMType> ret_types,
+ list<LLVMType> param_types = [],
+ list<IntrinsicProperty> intr_properties = [],
+ list<Except> except_constraints = [],
+ string name = "",
+ list<SDNodeProperty> sd_properties = [],
+ bit disable_default_attributes = true>
+ : Intrinsic<ret_types, param_types, intr_properties, name, sd_properties,
+ disable_default_attributes> {
+
+ list<Except> ExceptConstraints = except_constraints;
+}
+
/// ClangBuiltin - If this intrinsic exactly corresponds to a Clang builtin, this
/// specifies the name of the builtin. This provides automatic CBE and CFE
/// support.
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 76677d5741eab..4b948dea55e9d 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -3386,4 +3386,25 @@ def int_nvvm_tensormap_replace_fill_mode :
ArgInfo<ArgIndex<1>, [ArgName<"fill_mode">,
ImmArgPrinter<"printTensormapFillMode">]>]>;
+// Test intrinsic - TODO: Add the feature to existing intrinsics and remove these test intrinsics.
+// IIT_LongEncodingTable entry: /* 16662 */ 4, 15, 0, 93, 2, 3, 4, 15, 7, 15, 8, 93, 2, 15, 9, 7, 15, 16, 93, 2, 14, 24, 3, 15, 24, 94, 2, 5, 8, 15, 32, 93, 3, 3, 10, 4, 10, 7, 0,
+def int_nvvm_test_type : Intrinsic<[llvm_i32_ty],
+ [AnyTypeOf<[llvm_i16_ty, llvm_i32_ty]>, LLVMMatchType<0>, AnyTypeOf<[llvm_anyint_ty, llvm_float_ty]>, AnyTypeOf<[llvm_ptr_ty, llvm_shared_ptr_ty]>, NoneTypeOf<[llvm_i64_ty, llvm_double_ty]>, AnyTypeOf<[llvm_i16_ty, llvm_v4i32_ty, llvm_v4f32_ty]>],
+ [IntrNoMem]>;
+
+// IIT_LongEncodingTable entry: /* 15435 */ 21, 1, 4, 15, 0, 93, 3, 2, 3, 4, 5, 4, 15, 8, 93, 2, 7, 8, 95, 1, 2, 2, 7, 0,
+def int_nvvm_test_return_type : IntrinsicWithExcept<[llvm_i32_ty, AnyTypeOf<[llvm_i8_ty, llvm_i16_ty, llvm_i32_ty]>, llvm_i64_ty],
+ [llvm_i32_ty, AnyTypeOf<[llvm_float_ty, llvm_double_ty]>],
+ [IntrNoMem],
+ [Except<[[llvm_i8_ty, llvm_float_ty]]>]>;
+
+// IIT_LongEncodingTable entry: /* 16724 */ 3, 7, 15, 0, 93, 3, 3, 10, 4, 10, 7, 15, 8, 93, 2, 4, 7, 95, 2, 2, 10, 4, 7, 10, 7, 7, 0,
+def int_nvvm_except : IntrinsicWithExcept<[llvm_i16_ty],
+ [llvm_float_ty,
+ AnyTypeOf<[llvm_i16_ty, llvm_v4i32_ty, llvm_v4f32_ty]>,
+ AnyTypeOf<[llvm_i32_ty, llvm_float_ty]>],
+ [IntrNoMem],
+ [Except<[[llvm_v4i32_ty, llvm_float_ty],
+ [llvm_v4f32_ty, llvm_float_ty]]>]>;
+
} // let TargetPrefix = "nvvm"
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index f46d3e5063e43..a79fbf43a7fcd 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -353,6 +353,45 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_ARG: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
+
+ if (NextElt < Infos.size() && Infos[NextElt] == IIT_ANYTYPE) {
+ NextElt++;
+
+ unsigned NumTypes = Infos[NextElt++];
+ OutputTable.push_back(
+ IITDescriptor::get(IITDescriptor::ArgumentTypeConstraint, NumTypes));
+
+ for (unsigned i = 0; i < NumTypes; ++i)
+ DecodeIITType(NextElt, Infos, Info, OutputTable);
+ return;
+ }
+
+ if (NextElt < Infos.size() && Infos[NextElt] == IIT_NONETYPE) {
+ NextElt++;
+
+ unsigned NumTypes = Infos[NextElt++];
+ OutputTable.push_back(
+ IITDescriptor::get(IITDescriptor::ArgumentTypeExclusion, NumTypes));
+
+ for (unsigned i = 0; i < NumTypes; ++i)
+ DecodeIITType(NextElt, Infos, Info, OutputTable);
+ return;
+ }
+ return;
+ }
+ case IIT_ANYTYPE:
+ llvm_unreachable("IIT_ANYTYPE must follow IIT_ARG");
+ case IIT_NONETYPE:
+ llvm_unreachable("IIT_NONETYPE must follow IIT_ARG");
+ case IIT_EXCEPT: {
+ unsigned NumCombos = Infos[NextElt++];
+ unsigned ComboSize = Infos[NextElt++];
+
+ OutputTable.push_back(IITDescriptor::getExcept(NumCombos, ComboSize));
+
+ for (unsigned i = 0; i < NumCombos * ComboSize; ++i)
+ DecodeIITType(NextElt, Infos, Info, OutputTable);
+
return;
}
case IIT_EXTEND_ARG: {
@@ -515,8 +554,22 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
return PointerType::get(Context, D.Pointer_AddressSpace);
case IITDescriptor::Struct: {
SmallVector<Type *, 8> Elts;
- for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
+ for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) {
Elts.push_back(DecodeFixedType(Infos, Tys, Context));
+ if (!Infos.empty() &&
+ Infos.front().Kind == IITDescriptor::ArgumentTypeConstraint) {
+ unsigned NumConstraints = Infos.front().getArgumentNumConstraints();
+ Infos = Infos.slice(1);
+ for (unsigned j = 0; j < NumConstraints; ++j)
+ (void)DecodeFixedType(Infos, Tys, Context);
+ } else if (!Infos.empty() &&
+ Infos.front().Kind == IITDescriptor::ArgumentTypeExclusion) {
+ unsigned NumExclusions = Infos.front().getArgumentNumExclusions();
+ Infos = Infos.slice(1);
+ for (unsigned j = 0; j < NumExclusions; ++j)
+ (void)DecodeFixedType(Infos, Tys, Context);
+ }
+ }
return StructType::get(Context, Elts);
}
case IITDescriptor::Argument:
@@ -570,10 +623,101 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::VecOfAnyPtrsToElt:
// Return the overloaded type (which determines the pointers address space)
return Tys[D.getOverloadArgNumber()];
+ case IITDescriptor::ArgumentTypeConstraint:
+ llvm_unreachable(
+ "ArgumentTypeConstraint should not appear in DecodeFixedType");
+ case IITDescriptor::ArgumentTypeExclusion:
+ llvm_unreachable(
+ "ArgumentTypeExclusion should not appear in DecodeFixedType");
+ case IITDescriptor::ExceptConstraint:
+ llvm_unreachable("ExceptConstraint should not appear in DecodeFixedType");
}
llvm_unreachable("unhandled");
}
+// Helper to skip past descriptors for one complete type in AnyTypeOf
+// constraints.
+static unsigned
+skipDescriptorsForSingleType(ArrayRef<Intrinsic::IITDescriptor> &Infos) {
+ using namespace Intrinsic;
+
+ if (Infos.empty())
+ return 0;
+
+ IITDescriptor D = Infos[0];
+ unsigned Count = 1;
+ Infos = Infos.slice(1);
+
+ switch (D.Kind) {
+ case IITDescriptor::Vector:
+ Count += skipDescriptorsForSingleType(Infos);
+ break;
+
+ case IITDescriptor::Pointer:
+ break;
+
+ case IITDescriptor::Struct:
+ for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) {
+ Count += skipDescriptorsForSingleType(Infos);
+ if (!Infos.empty() &&
+ Infos.front().Kind == IITDescriptor::ArgumentTypeConstraint) {
+ unsigned NumConstraints = Infos.front().getArgumentNumConstraints();
+ Count++;
+ Infos = Infos.slice(1);
+ for (unsigned j = 0; j < NumConstraints; ++j)
+ Count += skipDescriptorsForSingleType(Infos);
+ } else if (!Infos.empty() &&
+ Infos.front().Kind == IITDescriptor::ArgumentTypeExclusion) {
+ unsigned NumExclusions = Infos.front().getArgumentNumExclusions();
+ Count++;
+ Infos = Infos.slice(1);
+ for (unsigned j = 0; j < NumExclusions; ++j)
+ Count += skipDescriptorsForSingleType(Infos);
+ }
+ }
+ break;
+
+ case IITDescriptor::SameVecWidthArgument:
+ Count += skipDescriptorsForSingleType(Infos);
+ break;
+
+ case IITDescriptor::Argument:
+ if (!Infos.empty() &&
+ Infos[0].Kind == IITDescriptor::ArgumentTypeConstraint) {
+ unsigned NumConstraints = Infos[0].getArgumentNumConstraints();
+ Count++;
+ Infos = Infos.slice(1);
+ for (unsigned i = 0; i < NumConstraints; ++i)
+ Count += skipDescriptorsForSingleType(Infos);
+ }
+ if (!Infos.empty() &&
+ Infos[0].Kind == IITDescriptor::ArgumentTypeExclusion) {
+ unsigned NumExclusions = Infos[0].getArgumentNumExclusions();
+ Count++;
+ Infos = Infos.slice(1);
+ for (unsigned i = 0; i < NumExclusions; ++i)
+ Count += skipDescriptorsForSingleType(Infos);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return Count;
+}
+
+// Skip Except constraint descriptors.
+static void skipExceptDescriptors(ArrayRef<Intrinsic::IITDescriptor> &Infos) {
+ if (Infos.empty() || Infos[0].Kind != Intrinsic::IITDescriptor::ExceptConstraint)
+ return;
+
+ auto [NumCombos, ComboSize] = Infos[0].getExceptInfo();
+ Infos = Infos.slice(1);
+
+ for (unsigned i = 0; i < NumCombos * ComboSize; ++i)
+ skipDescriptorsForSingleType(Infos);
+}
+
FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
ArrayRef<Type *> Tys) {
SmallVector<IITDescriptor, 8> Table;
@@ -582,10 +726,52 @@ FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
ArrayRef<IITDescriptor> TableRef = Table;
Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
+ if (!TableRef.empty() &&
+ TableRef[0].Kind == IITDescriptor::ArgumentTypeConstraint) {
+ unsigned NumConstraints = TableRef[0].getArgumentNumConstraints();
+ TableRef = TableRef.slice(1);
+
+ for (unsigned i = 0; i < NumConstraints; ++i)
+ (void)DecodeFixedType(TableRef, Tys, Context);
+ }
+
+ if (!TableRef.empty() &&
+ TableRef[0].Kind == IITDescriptor::ArgumentTypeExclusion) {
+ unsigned NumExclusions = TableRef[0].getArgumentNumExclusions();
+ TableRef = TableRef.slice(1);
+
+ for (unsigned i = 0; i < NumExclusions; ++i)
+ (void)DecodeFixedType(TableRef, Tys, Context);
+ }
+
SmallVector<Type *, 8> ArgTys;
- while (!TableRef.empty())
+ while (!TableRef.empty()) {
+ if (TableRef[0].Kind == IITDescriptor::ExceptConstraint ||
+ TableRef[0].Kind == IITDescriptor::VarArg)
+ break;
ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
+ if (!TableRef.empty() &&
+ TableRef[0].Kind == IITDescriptor::ArgumentTypeConstraint) {
+ unsigned NumConstraints = TableRef[0].getArgumentNumConstraints();
+ TableRef = TableRef.slice(1);
+
+ for (unsigned i = 0; i < NumConstraints; ++i)
+ (void)DecodeFixedType(TableRef, Tys, Context);
+ }
+
+ if (!TableRef.empty() &&
+ TableRef[0].Kind == IITDescriptor::ArgumentTypeExclusion) {
+ unsigned NumExclusions = TableRef[0].getArgumentNumExclusions();
+ TableRef = TableRef.slice(1);
+
+ for (unsigned i = 0; i < NumExclusions; ++i)
+ (void)DecodeFixedType(TableRef, Tys, Context);
+ }
+ }
+
+ skipExceptDescriptors(TableRef);
+
// 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
@@ -593,6 +779,11 @@ FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
ArgTys.pop_back();
return FunctionType::get(ResultTy, ArgTys, true);
}
+
+ // Check if VarArg descriptor is present.
+ if (!TableRef.empty() && TableRef[0].Kind == IITDescriptor::VarArg)
+ return FunctionType::get(ResultTy, ArgTys, true);
+
return FunctionType::get(ResultTy, ArgTys, false);
}
@@ -920,6 +1111,29 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
if (D.getArgumentNumber() < ArgTys.size())
return Ty != ArgTys[D.getArgumentNumber()];
+ switch (D.getArgumentKind()) {
+ case IITDescriptor::AK_Any:
+ break;
+ case IITDescriptor::AK_AnyInteger:
+ if (!Ty->isIntOrIntVectorTy())
+ return true;
+ break;
+ case IITDescriptor::AK_AnyFloat:
+ if (!Ty->isFPOrFPVectorTy())
+ return true;
+ break;
+ case IITDescriptor::AK_AnyVector:
+ if (!isa<VectorType>(Ty))
+ return true;
+ break;
+ case IITDescriptor::AK_AnyPointer:
+ if (!isa<PointerType>(Ty))
+ return true;
+ break;
+ case IITDescriptor::AK_MatchType:
+ break;
+ }
+
if (D.getArgumentNumber() > ArgTys.size() ||
D.getArgumentKind() == IITDescriptor::AK_MatchType)
return IsDeferredCheck || DeferCheck(Ty);
@@ -928,21 +1142,29 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
"Table consistency error");
ArgTys.push_back(Ty);
- switch (D.getArgumentKind()) {
- case IITDescriptor::AK_Any:
- return false; // Success
- case IITDescriptor::AK_AnyInteger:
- return !Ty->isIntOrIntVectorTy();
- case IITDescriptor::AK_AnyFloat:
- return !Ty->isFPOrFPVectorTy();
- case IITDescriptor::AK_AnyVector:
- return !isa<VectorType>(Ty);
- case IITDescriptor::AK_AnyPointer:
- return !isa<PointerType>(Ty);
- default:
- break;
+ if (!Infos.empty() &&
+ Infos[0].Kind == IITDescriptor::ArgumentTypeConstraint) {
+ unsigned NumConstraints = Infos[0].getArgumentNumConstraints();
+ Infos = Infos.slice(1);
+
+ for (unsigned i = 0; i < NumConstraints; ++i)
+ skipDescriptorsForSingleType(Infos);
+
+ return false;
}
- llvm_unreachable("all argument kinds not covered");
+
+ if (!Infos.empty() &&
+ Infos[0].Kind == IITDescriptor::ArgumentTypeExclusion) {
+ unsigned NumExclusions = Infos[0].getArgumentNumExclusions();
+ Infos = Infos.slice(1);
+
+ for (unsigned i = 0; i < NumExclusions; ++i)
+ skipDescriptorsForSingleType(Infos);
+
+ return false;
+ }
+
+ return false;
case IITDescriptor::ExtendArgument: {
// If this is a forward reference, defer the check for later.
@@ -1058,6 +1280,14 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return true;
return ThisArgVecTy != VectorType::getInteger(ReferenceType);
}
+ case IIT...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/175445
More information about the llvm-commits
mailing list