[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