[Mlir-commits] [llvm] [mlir] [LLVM] Refactor intrinsic validation (PR #194061)

Rahul Joshi llvmlistbot at llvm.org
Thu Apr 30 09:24:31 PDT 2026


https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/194061

>From 8c62a5b33cedf213b6502c22ec51dd9eb4574687 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Fri, 24 Apr 2026 11:37:48 -0700
Subject: [PATCH] [LLVM] Refactor intrinsic validation

Refactor intrinsic validation by generating an error message as a part
of validation and using this functionality in various places. The main
parts of the change are:

1. Change `matchIntrinsicSignature` to return a bool and print any error
   messages when the match fails to a `raw_ostream`. The intent is that
   `matchIntrinsicSignature` can be improved to generate more precise
   error message instead of a simple pass/fail signal.
2. Absort the validation of variadic argument into
   `matchIntrinsicSignature`.
3. Rename `getIntrinsicSignature` to `isIntrinsicSignatureValid` to
   better reflect its meaning and have it also generate an error message
   to a passed on `raw_ostream` when it returns false.
3. Change verifier to use `isIntrinsicSignatureValid` to validate the
   intrinsic declaration.

After this change, `matchIntrinsicSignature` is called only from within
Intrinsics.cpp, so we could make it a static function, but not doing
that yet.
---
 llvm/include/llvm/IR/Intrinsics.h             |  42 +++---
 llvm/lib/AsmParser/LLParser.cpp               |   9 +-
 llvm/lib/IR/AutoUpgrade.cpp                   |   2 +-
 llvm/lib/IR/Function.cpp                      |   2 +-
 llvm/lib/IR/Intrinsics.cpp                    | 120 ++++++++++--------
 llvm/lib/IR/Verifier.cpp                      |  36 ++----
 .../AMDGPU/AMDGPUImageIntrinsicOptimizer.cpp  |   2 +-
 .../AMDGPU/AMDGPUInstCombineIntrinsic.cpp     |  20 +--
 .../NumericalStabilitySanitizer.cpp           |   2 +-
 .../implicit-intrinsic-declaration-invalid.ll |   2 +-
 llvm/test/Assembler/invalid-interleave.ll     |   2 +-
 llvm/test/Assembler/invalid-vecreduce.ll      |   8 +-
 .../CodeGen/AArch64/sve-bad-intrinsics.ll     |   4 +-
 .../CodeGen/WinEH/wineh-intrinsics-invalid.ll |   2 +-
 llvm/test/Verifier/arbitrary-fp-convert.ll    |  10 +-
 llvm/test/Verifier/callbr.ll                  |   2 +-
 llvm/test/Verifier/get-active-lane-mask.ll    |   2 +-
 .../intrinsic-arg-overloading-struct-ret.ll   |  18 +--
 llvm/test/Verifier/intrinsic-bad-arg-type.ll  |   2 +-
 llvm/test/Verifier/masked-divrem.ll           |   8 +-
 llvm/test/Verifier/matrix-intrinsics.ll       |   4 +-
 llvm/test/Verifier/reduction-intrinsics.ll    |  16 +--
 llvm/test/Verifier/sat-intrinsics.ll          |  12 +-
 llvm/test/Verifier/scatter_gather.ll          |  26 ++--
 llvm/test/Verifier/stepvector-intrinsic.ll    |   2 +-
 llvm/test/Verifier/varargs-intrinsic.ll       |   7 +-
 .../LLVMIR/LLVMToLLVMIRTranslation.cpp        |   6 +-
 mlir/test/Dialect/LLVMIR/call-intrin.mlir     |   2 +-
 28 files changed, 181 insertions(+), 189 deletions(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 1efddd09b08fd..a69f23e889318 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -262,41 +262,33 @@ namespace Intrinsic {
   LLVM_ABI void getIntrinsicInfoTableEntries(ID id,
                                              SmallVectorImpl<IITDescriptor> &T);
 
-  enum MatchIntrinsicTypesResult {
-    MatchIntrinsicTypes_Match = 0,
-    MatchIntrinsicTypes_NoMatchRet = 1,
-    MatchIntrinsicTypes_NoMatchArg = 2,
-  };
-
   /// Match the specified function type with the type constraints specified by
   /// the .td file. If the given type is an overloaded type it is pushed to the
   /// OverloadTys vector.
   ///
   /// Returns false if the given type matches with the constraints, true
-  /// otherwise.
-  LLVM_ABI MatchIntrinsicTypesResult
-  matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
-                          SmallVectorImpl<Type *> &OverloadTys);
-
-  /// Verify if the intrinsic has variable arguments. This method is intended to
-  /// be called after all the fixed arguments have been matched first.
-  ///
-  /// This method returns true on error.
-  LLVM_ABI bool matchIntrinsicVarArg(bool isVarArg,
-                                     ArrayRef<IITDescriptor> &Infos);
-
-  /// Gets the overload types of an intrinsic call by matching type contraints
-  /// specified by the .td file. The overloaded types are pushed into the
+  /// otherwise. If returning true, an error message to indicate the reason of
+  /// mismatch is printed to \p OS.
+  LLVM_ABI bool matchIntrinsicSignature(FunctionType *FTy,
+                                        ArrayRef<IITDescriptor> &Infos,
+                                        SmallVectorImpl<Type *> &OverloadTys,
+                                        raw_ostream &OS);
+
+  /// Returns true if \p FT is a valid function type for intrinsic \p ID. If
+  /// `ID` is an overloaded intrinsic, the overload types are pushed into the
   /// OverloadTys vector.
   ///
   /// Returns false if the given ID and function type combination is not a
-  /// valid intrinsic call.
-  LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT,
-                                      SmallVectorImpl<Type *> &OverloadTys);
+  /// valid intrinsic call. Also prints the error message to indicate the reason
+  /// of the mismatch to \p OS.
+  LLVM_ABI bool isSignatureValid(Intrinsic::ID ID, FunctionType *FT,
+                                 SmallVectorImpl<Type *> &OverloadTys,
+                                 raw_ostream &OS = nulls());
 
   /// Same as previous, but accepts a Function instead of ID and FunctionType.
-  LLVM_ABI bool getIntrinsicSignature(Function *F,
-                                      SmallVectorImpl<Type *> &OverloadTys);
+  LLVM_ABI bool isSignatureValid(Function *F,
+                                 SmallVectorImpl<Type *> &OverloadTys,
+                                 raw_ostream &OS = nulls());
 
   // Checks if the intrinsic name matches with its signature and if not
   // returns the declaration with the same signature and remangled name.
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 697e7ab004680..dadbc510cdbd5 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -341,10 +341,13 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
         if (!CB || !CB->isCallee(&U))
           return error(Info.second, "intrinsic can only be used as callee");
 
+        std::string ErrorMsg;
+        raw_string_ostream ErrorOS(ErrorMsg);
+
         SmallVector<Type *> OverloadTys;
         if (IID != Intrinsic::not_intrinsic &&
-            Intrinsic::getIntrinsicSignature(IID, CB->getFunctionType(),
-                                             OverloadTys)) {
+            Intrinsic::isSignatureValid(IID, CB->getFunctionType(), OverloadTys,
+                                        ErrorOS)) {
           U.set(Intrinsic::getOrInsertDeclaration(M, IID, OverloadTys));
         } else {
           // Try to upgrade the intrinsic.
@@ -354,7 +357,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
           if (!UpgradeIntrinsicFunction(TmpF, NewF)) {
             if (IID == Intrinsic::not_intrinsic)
               return error(Info.second, "unknown intrinsic '" + Name + "'");
-            return error(Info.second, "invalid intrinsic signature");
+            return error(Info.second, ErrorMsg);
           }
 
           U.set(TmpF);
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 2728897372009..d539419554371 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -1906,7 +1906,7 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
   if (Intrinsic::ID id = F->getIntrinsicID()) {
     // Only do this if the intrinsic signature is valid.
     SmallVector<Type *> OverloadTys;
-    if (Intrinsic::getIntrinsicSignature(id, F->getFunctionType(), OverloadTys))
+    if (Intrinsic::isSignatureValid(id, F->getFunctionType(), OverloadTys))
       F->setAttributes(
           Intrinsic::getAttributes(F->getContext(), id, F->getFunctionType()));
   }
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index a6568bb50f0c8..de5d3f62efdc9 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -508,7 +508,7 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
     // Don't set the attributes if the intrinsic signature is invalid. This
     // case will either be auto-upgraded or fail verification.
     SmallVector<Type *> OverloadTys;
-    if (!Intrinsic::getIntrinsicSignature(IntID, Ty, OverloadTys))
+    if (!Intrinsic::isSignatureValid(IntID, Ty, OverloadTys))
       return;
 
     setAttributes(Intrinsic::getAttributes(getContext(), IntID, Ty));
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index a15cda6ecafff..c5a0531a089b6 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -779,6 +779,9 @@ Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
   return getOrInsertIntrinsicDeclarationImpl(M, id, OverloadTys, FT);
 }
 
+static bool isIntrinsicVarArg(ArrayRef<Intrinsic::IITDescriptor> &Infos,
+                              bool Consume);
+
 Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id, Type *RetTy,
                                             ArrayRef<Type *> ArgTys) {
   // If the intrinsic is not overloaded, use the non-overloaded version.
@@ -789,22 +792,15 @@ Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id, Type *RetTy,
   SmallVector<Intrinsic::IITDescriptor, 8> Table;
   getIntrinsicInfoTableEntries(id, Table);
   ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
+  bool IsVarArg = isIntrinsicVarArg(TableRef, /*Consume=*/false);
 
-  FunctionType *FTy = FunctionType::get(RetTy, ArgTys, /*isVarArg=*/false);
+  FunctionType *FTy = FunctionType::get(RetTy, ArgTys, IsVarArg);
 
   // Automatically determine the overloaded types.
   SmallVector<Type *, 4> OverloadTys;
-  [[maybe_unused]] Intrinsic::MatchIntrinsicTypesResult Res =
-      matchIntrinsicSignature(FTy, TableRef, OverloadTys);
-  assert(Res == Intrinsic::MatchIntrinsicTypes_Match &&
-         "intrinsic signature mismatch");
-
-  // If intrinsic requires vararg, recreate the FunctionType accordingly.
-  if (!matchIntrinsicVarArg(/*isVarArg=*/true, TableRef))
-    FTy = FunctionType::get(RetTy, ArgTys, /*isVarArg=*/true);
-
-  assert(TableRef.empty() && "Unprocessed descriptors remain");
-
+  [[maybe_unused]] bool MatchResult =
+      matchIntrinsicSignature(FTy, TableRef, OverloadTys, nulls());
+  assert(MatchResult == false && "intrinsic signature mismatch");
   return getOrInsertIntrinsicDeclarationImpl(M, id, OverloadTys, FTy);
 }
 
@@ -1085,52 +1081,71 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
   llvm_unreachable("unhandled");
 }
 
-Intrinsic::MatchIntrinsicTypesResult
-Intrinsic::matchIntrinsicSignature(FunctionType *FTy,
-                                   ArrayRef<Intrinsic::IITDescriptor> &Infos,
-                                   SmallVectorImpl<Type *> &OverloadTys) {
+/// Returns true if the intrinsic is a VarArg intrinsics. If \p Consume is true
+/// the IITDescriptor for the VarArg is consumed and removed from \p Infos, else
+/// it stays unchanged.
+static bool isIntrinsicVarArg(ArrayRef<Intrinsic::IITDescriptor> &Infos,
+                              bool Consume) {
+  if (!Infos.empty() && Infos.back().Kind == Intrinsic::IITDescriptor::VarArg) {
+    if (Consume)
+      Infos.consume_back();
+    return true;
+  }
+  return false;
+}
+
+bool Intrinsic::matchIntrinsicSignature(
+    FunctionType *FTy, ArrayRef<Intrinsic::IITDescriptor> &Infos,
+    SmallVectorImpl<Type *> &OverloadTys, raw_ostream &OS) {
+  bool IsVarArg = isIntrinsicVarArg(Infos, /*Consume=*/true);
+
   SmallVector<DeferredIntrinsicMatchPair, 2> DeferredChecks;
   if (matchIntrinsicType(FTy->getReturnType(), Infos, OverloadTys,
-                         DeferredChecks, false))
-    return MatchIntrinsicTypes_NoMatchRet;
+                         DeferredChecks, false)) {
+    OS << "intrinsic has incorrect return type!";
+    return true;
+  }
 
   unsigned NumDeferredReturnChecks = DeferredChecks.size();
 
-  for (auto *Ty : FTy->params())
-    if (matchIntrinsicType(Ty, Infos, OverloadTys, DeferredChecks, false))
-      return MatchIntrinsicTypes_NoMatchArg;
+  for (Type *Ty : FTy->params()) {
+    if (matchIntrinsicType(Ty, Infos, OverloadTys, DeferredChecks, false)) {
+      OS << "intrinsic has incorrect argument type!";
+      return true;
+    }
+  }
 
   for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) {
     DeferredIntrinsicMatchPair &Check = DeferredChecks[I];
-    if (matchIntrinsicType(Check.first, Check.second, OverloadTys,
-                           DeferredChecks, true))
-      return I < NumDeferredReturnChecks ? MatchIntrinsicTypes_NoMatchRet
-                                         : MatchIntrinsicTypes_NoMatchArg;
+    if (!matchIntrinsicType(Check.first, Check.second, OverloadTys,
+                            DeferredChecks, true))
+      continue;
+    if (I < NumDeferredReturnChecks)
+      OS << "intrinsic has incorrect return type!";
+    else
+      OS << "intrinsic has incorrect argument type!";
+    return true;
   }
 
-  return MatchIntrinsicTypes_Match;
-}
-
-bool Intrinsic::matchIntrinsicVarArg(
-    bool isVarArg, ArrayRef<Intrinsic::IITDescriptor> &Infos) {
-  // If there are no descriptors left, then it can't be a vararg.
-  if (Infos.empty())
-    return isVarArg;
-
-  // There should be only one descriptor remaining at this point.
-  if (Infos.size() != 1)
+  if (!Infos.empty()) {
+    OS << "intrinsic has too few arguments!";
     return true;
+  }
 
-  // Check and verify the descriptor.
-  IITDescriptor D = Infos.consume_front();
-  if (D.Kind == IITDescriptor::VarArg)
-    return !isVarArg;
+  if (FTy->isVarArg() != IsVarArg) {
+    if (IsVarArg)
+      OS << "intrinsic was not defined with variable arguments!";
+    else
+      OS << "intrinsic was defined with variable arguments!";
+    return true;
+  }
 
-  return true;
+  return false;
 }
 
-bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,
-                                      SmallVectorImpl<Type *> &OverloadTys) {
+bool Intrinsic::isSignatureValid(Intrinsic::ID ID, FunctionType *FT,
+                                 SmallVectorImpl<Type *> &OverloadTys,
+                                 raw_ostream &OS) {
   if (!ID)
     return false;
 
@@ -1138,24 +1153,19 @@ bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,
   getIntrinsicInfoTableEntries(ID, Table);
   ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
 
-  if (Intrinsic::matchIntrinsicSignature(FT, TableRef, OverloadTys) !=
-      Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
-    return false;
-  }
-  if (Intrinsic::matchIntrinsicVarArg(FT->isVarArg(), TableRef))
-    return false;
-  return true;
+  return !matchIntrinsicSignature(FT, TableRef, OverloadTys, OS);
 }
 
-bool Intrinsic::getIntrinsicSignature(Function *F,
-                                      SmallVectorImpl<Type *> &OverloadTys) {
-  return getIntrinsicSignature(F->getIntrinsicID(), F->getFunctionType(),
-                               OverloadTys);
+bool Intrinsic::isSignatureValid(Function *F,
+                                 SmallVectorImpl<Type *> &OverloadTys,
+                                 raw_ostream &OS) {
+  return isSignatureValid(F->getIntrinsicID(), F->getFunctionType(),
+                          OverloadTys, OS);
 }
 
 std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) {
   SmallVector<Type *, 4> OverloadTys;
-  if (!getIntrinsicSignature(F, OverloadTys))
+  if (!isSignatureValid(F, OverloadTys))
     return std::nullopt;
 
   Intrinsic::ID ID = F->getIntrinsicID();
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ec467e8b85739..79d4834a7a30d 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5921,38 +5921,20 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
   // Verify that the intrinsic prototype lines up with what the .td files
   // describe.
   FunctionType *IFTy = IF->getFunctionType();
-  bool IsVarArg = IFTy->isVarArg();
-
-  SmallVector<Intrinsic::IITDescriptor, 8> Table;
-  getIntrinsicInfoTableEntries(ID, Table);
-  ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
 
   // Walk the descriptors to extract overloaded types.
-  SmallVector<Type *, 4> ArgTys;
-  Intrinsic::MatchIntrinsicTypesResult Res =
-      Intrinsic::matchIntrinsicSignature(IFTy, TableRef, ArgTys);
-  Check(Res != Intrinsic::MatchIntrinsicTypes_NoMatchRet,
-        "Intrinsic has incorrect return type!", IF);
-  Check(Res != Intrinsic::MatchIntrinsicTypes_NoMatchArg,
-        "Intrinsic has incorrect argument type!", IF);
-
-  // Verify if the intrinsic call matches the vararg property.
-  if (IsVarArg)
-    Check(!Intrinsic::matchIntrinsicVarArg(IsVarArg, TableRef),
-          "Intrinsic was not defined with variable arguments!", IF);
-  else
-    Check(!Intrinsic::matchIntrinsicVarArg(IsVarArg, TableRef),
-          "Callsite was not defined with variable arguments!", IF);
-
-  // All descriptors should be absorbed by now.
-  Check(TableRef.empty(), "Intrinsic has too few arguments!", IF);
+  std::string ErrMsg;
+  raw_string_ostream ErrOS(ErrMsg);
+  SmallVector<Type *, 4> OverloadTys;
+  bool IsValid = Intrinsic::isSignatureValid(ID, IFTy, OverloadTys, ErrOS);
+  Check(IsValid, ErrMsg, IF);
 
   // Now that we have the intrinsic ID and the actual argument types (and we
   // know they are legal for the intrinsic!) get the intrinsic name through the
   // usual means.  This allows us to verify the mangling of argument types into
   // the name.
   const std::string ExpectedName =
-      Intrinsic::getName(ID, ArgTys, IF->getParent(), IFTy);
+      Intrinsic::getName(ID, OverloadTys, IF->getParent(), IFTy);
   Check(ExpectedName == IF->getName(),
         "Intrinsic name not mangled correctly for type arguments! "
         "Should be: " +
@@ -6638,14 +6620,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
   case Intrinsic::vector_reduce_umin: {
     Type *ArgTy = Call.getArgOperand(0)->getType();
     Check(ArgTy->isIntOrIntVectorTy() && ArgTy->isVectorTy(),
-          "Intrinsic has incorrect argument type!");
+          "intrinsic has incorrect argument type!");
     break;
   }
   case Intrinsic::vector_reduce_fmax:
   case Intrinsic::vector_reduce_fmin: {
     Type *ArgTy = Call.getArgOperand(0)->getType();
     Check(ArgTy->isFPOrFPVectorTy() && ArgTy->isVectorTy(),
-          "Intrinsic has incorrect argument type!");
+          "intrinsic has incorrect argument type!");
     break;
   }
   case Intrinsic::vector_reduce_fadd:
@@ -6654,7 +6636,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
     // second argument is the vector to be reduced.
     Type *ArgTy = Call.getArgOperand(1)->getType();
     Check(ArgTy->isFPOrFPVectorTy() && ArgTy->isVectorTy(),
-          "Intrinsic has incorrect argument type!");
+          "intrinsic has incorrect argument type!");
     break;
   }
   case Intrinsic::smul_fix:
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUImageIntrinsicOptimizer.cpp b/llvm/lib/Target/AMDGPU/AMDGPUImageIntrinsicOptimizer.cpp
index 639089c75a33e..dd6858a15749e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUImageIntrinsicOptimizer.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUImageIntrinsicOptimizer.cpp
@@ -188,7 +188,7 @@ bool optimizeSection(ArrayRef<SmallVector<IntrinsicInst *, 4>> MergeableInsts) {
     // types along the way.
     SmallVector<Type *, 6> OverloadTys;
     Function *F = IIList.front()->getCalledFunction();
-    if (!Intrinsic::getIntrinsicSignature(F, OverloadTys))
+    if (!Intrinsic::isSignatureValid(F, OverloadTys))
       continue;
 
     Intrinsic::ID IntrinID = IIList.front()->getIntrinsicID();
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index b973e5da87b15..c993e035b9b40 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -122,16 +122,16 @@ static std::optional<Instruction *> modifyIntrinsicCall(
     InstCombiner &IC,
     std::function<void(SmallVectorImpl<Value *> &, SmallVectorImpl<Type *> &)>
         Func) {
-  SmallVector<Type *, 4> ArgTys;
-  if (!Intrinsic::getIntrinsicSignature(OldIntr.getCalledFunction(), ArgTys))
+  SmallVector<Type *, 4> OverloadTys;
+  if (!Intrinsic::isSignatureValid(OldIntr.getCalledFunction(), OverloadTys))
     return std::nullopt;
 
   SmallVector<Value *, 8> Args(OldIntr.args());
 
   // Modify arguments and types
-  Func(Args, ArgTys);
+  Func(Args, OverloadTys);
 
-  CallInst *NewCall = IC.Builder.CreateIntrinsic(NewIntr, ArgTys, Args);
+  CallInst *NewCall = IC.Builder.CreateIntrinsic(NewIntr, OverloadTys, Args);
   NewCall->takeName(&OldIntr);
   NewCall->copyMetadata(OldIntr);
   if (isa<FPMathOperator>(NewCall))
@@ -278,13 +278,13 @@ simplifyAMDGCNImageIntrinsic(const GCNSubtarget *ST,
 
         // Obtain the original image sample intrinsic's signature
         // and replace its return type with the half-vector for D16 folding
-        SmallVector<Type *, 8> SigTys;
-        Intrinsic::getIntrinsicSignature(II.getCalledFunction(), SigTys);
-        SigTys[0] = HalfVecTy;
+        SmallVector<Type *, 8> OverloadTys;
+        Intrinsic::isSignatureValid(II.getCalledFunction(), OverloadTys);
+        OverloadTys[0] = HalfVecTy;
 
         Module *M = II.getModule();
-        Function *HalfDecl =
-            Intrinsic::getOrInsertDeclaration(M, ImageDimIntr->Intr, SigTys);
+        Function *HalfDecl = Intrinsic::getOrInsertDeclaration(
+            M, ImageDimIntr->Intr, OverloadTys);
 
         II.mutateType(HalfVecTy);
         II.setCalledFunction(HalfDecl);
@@ -2028,7 +2028,7 @@ static Value *simplifyAMDGCNMemoryIntrinsicDemanded(InstCombiner &IC,
   // Validate function argument and return types, extracting overloaded types
   // along the way.
   SmallVector<Type *, 6> OverloadTys;
-  if (!Intrinsic::getIntrinsicSignature(II.getCalledFunction(), OverloadTys))
+  if (!Intrinsic::isSignatureValid(II.getCalledFunction(), OverloadTys))
     return nullptr;
 
   Type *NewTy =
diff --git a/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
index 2b744f808e5a9..f40816d07d566 100644
--- a/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
@@ -1580,7 +1580,7 @@ Value *NumericalStabilitySanitizer::maybeHandleKnownCallBase(
   // Check that the widened intrinsic is valid.
   SmallVector<Type *, 4> OverloadTys;
   [[maybe_unused]] bool IsValid =
-      Intrinsic::getIntrinsicSignature(WidenedId, WidenedFnTy, OverloadTys);
+      Intrinsic::isSignatureValid(WidenedId, WidenedFnTy, OverloadTys);
   assert(IsValid && "invalid widened intrinsic");
   // For known intrinsic functions, we create a second call to the same
   // intrinsic with a different type.
diff --git a/llvm/test/Assembler/implicit-intrinsic-declaration-invalid.ll b/llvm/test/Assembler/implicit-intrinsic-declaration-invalid.ll
index 63566a26dfa02..f67afe2110aae 100644
--- a/llvm/test/Assembler/implicit-intrinsic-declaration-invalid.ll
+++ b/llvm/test/Assembler/implicit-intrinsic-declaration-invalid.ll
@@ -3,7 +3,7 @@
 ; Use of intrinsic without mangling suffix and invalid signature should
 ; be rejected.
 
-; CHECK: error: invalid intrinsic signature
+; CHECK: error: intrinsic has incorrect argument type!
 define void @test() {
   call i8 @llvm.umax(i8 0, i16 1)
   ret void
diff --git a/llvm/test/Assembler/invalid-interleave.ll b/llvm/test/Assembler/invalid-interleave.ll
index bc650aa35f4d1..6d5a2e40b0280 100644
--- a/llvm/test/Assembler/invalid-interleave.ll
+++ b/llvm/test/Assembler/invalid-interleave.ll
@@ -2,7 +2,7 @@
 
 ; Input element count without vscale is not a multiple of 3.
 
-; CHECK: error: invalid intrinsic signature
+; CHECK: error: intrinsic has incorrect return type
 define { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } @test(<vscale x 8 x i8> %ptr) {
   %v = tail call { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } @llvm.vector.deinterleave3.nxv6i32(<vscale x 8 x i8> %ptr)
   ret { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %v
diff --git a/llvm/test/Assembler/invalid-vecreduce.ll b/llvm/test/Assembler/invalid-vecreduce.ll
index 1a2b866dd003f..ee642879c84ab 100644
--- a/llvm/test/Assembler/invalid-vecreduce.ll
+++ b/llvm/test/Assembler/invalid-vecreduce.ll
@@ -1,27 +1,27 @@
 ; RUN: not opt -S < %s 2>&1 | FileCheck %s
 
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
 ; CHECK-NEXT: ptr @llvm.vector.reduce.fadd.f32.f64.v2f64
 define float @fadd_invalid_scalar_res(double %acc, <2 x double> %in) {
   %res = call float @llvm.vector.reduce.fadd.f32.f64.v2f64(double %acc, <2 x double> %in)
   ret float %res
 }
 
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.vector.reduce.fadd.f64.f32.v2f64
 define double @fadd_invalid_scalar_start(float %acc, <2 x double> %in) {
   %res = call double @llvm.vector.reduce.fadd.f64.f32.v2f64(float %acc, <2 x double> %in)
   ret double %res
 }
 
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
 ; CHECK-NEXT: ptr @llvm.vector.reduce.fadd.v2f64.f64.v2f64
 define <2 x double> @fadd_invalid_vector_res(double %acc, <2 x double> %in) {
   %res = call <2 x double> @llvm.vector.reduce.fadd.v2f64.f64.v2f64(double %acc, <2 x double> %in)
   ret <2 x double> %res
 }
 
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.vector.reduce.fadd.f64.v2f64.v2f64
 define double @fadd_invalid_vector_start(<2 x double> %in, <2 x double> %acc) {
   %res = call double @llvm.vector.reduce.fadd.f64.v2f64.v2f64(<2 x double> %acc, <2 x double> %in)
diff --git a/llvm/test/CodeGen/AArch64/sve-bad-intrinsics.ll b/llvm/test/CodeGen/AArch64/sve-bad-intrinsics.ll
index 1b37ea372b983..97f38f8657b86 100644
--- a/llvm/test/CodeGen/AArch64/sve-bad-intrinsics.ll
+++ b/llvm/test/CodeGen/AArch64/sve-bad-intrinsics.ll
@@ -4,13 +4,13 @@
 declare <4 x float> @llvm.arm.neon.vcvthf2fp(<vscale x 4 x i16>)
 declare <vscale x 4 x i16> @llvm.arm.neon.vcvtfp2hf(<vscale x 4 x float>)
 
-; CHECK-ERROR: Intrinsic has incorrect return type!
+; CHECK-ERROR: intrinsic has incorrect return type!
 define <vscale x 4 x i16> @bad1() {
   %r = call <vscale x 4 x i16> @llvm.arm.neon.vcvtfp2hf(<vscale x 4 x float> zeroinitializer)
   ret <vscale x 4 x i16> %r
 }
 
-; CHECK-ERROR: Intrinsic has incorrect argument type!
+; CHECK-ERROR: intrinsic has incorrect argument type!
 define <4 x float> @bad2() {
   %r = call <4 x float> @llvm.arm.neon.vcvthf2fp(<vscale x 4 x i16> zeroinitializer)
   ret <4 x float> %r
diff --git a/llvm/test/CodeGen/WinEH/wineh-intrinsics-invalid.ll b/llvm/test/CodeGen/WinEH/wineh-intrinsics-invalid.ll
index e3fdd319b69b2..5712198743bf8 100644
--- a/llvm/test/CodeGen/WinEH/wineh-intrinsics-invalid.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-intrinsics-invalid.ll
@@ -11,7 +11,7 @@ declare void @f()
 ;T1:   call ptr @llvm.eh.exceptionpointer.p0(i32 0)
 ;T1:   ret void
 ;T1: }
-;CHECK1: Intrinsic has incorrect argument type!
+;CHECK1: intrinsic has incorrect argument type!
 ;CHECK1-NEXT: ptr @llvm.eh.exceptionpointer.p0
 
 ;T2: declare ptr @llvm.eh.exceptionpointer.p0(token)
diff --git a/llvm/test/Verifier/arbitrary-fp-convert.ll b/llvm/test/Verifier/arbitrary-fp-convert.ll
index 9e3487c9c80b9..a4b0a0955ccd1 100644
--- a/llvm/test/Verifier/arbitrary-fp-convert.ll
+++ b/llvm/test/Verifier/arbitrary-fp-convert.ll
@@ -47,7 +47,7 @@ define i8 @bad_rounding(half %v) {
 }
 
 ;--- ptr-to-arbitrary-fp.ll
-; PTR-TO-FP: Intrinsic has incorrect argument type!
+; PTR-TO-FP: intrinsic has incorrect argument type!
 
 declare i8 @llvm.convert.to.arbitrary.fp.i8.ptr(ptr, metadata, metadata, i1)
 
@@ -58,7 +58,7 @@ define i8 @bad_ptr_to_fp(ptr %p) {
 }
 
 ;--- arbitrary-fp-to-ptr.ll
-; FP-TO-PTR: Intrinsic has incorrect return type!
+; FP-TO-PTR: intrinsic has incorrect return type!
 
 declare ptr @llvm.convert.from.arbitrary.fp.ptr.i8(i8, metadata)
 
@@ -69,7 +69,7 @@ define ptr @bad_fp_to_ptr(i8 %v) {
 }
 
 ;--- int-to-arbitrary-fp.ll
-; INT-TO-FP: Intrinsic has incorrect argument type!
+; INT-TO-FP: intrinsic has incorrect argument type!
 
 declare i8 @llvm.convert.to.arbitrary.fp.i8.i32(i32, metadata, metadata, i1)
 
@@ -80,7 +80,7 @@ define i8 @bad_int_to_fp(i32 %v) {
 }
 
 ;--- arbitrary-fp-to-int.ll
-; FP-TO-INT: Intrinsic has incorrect return type!
+; FP-TO-INT: intrinsic has incorrect return type!
 
 declare i32 @llvm.convert.from.arbitrary.fp.i32.i8(i8, metadata)
 
@@ -91,7 +91,7 @@ define i32 @bad_fp_to_int(i8 %v) {
 }
 
 ;--- vec-ptr-to-arbitrary-fp.ll
-; VEC-PTR-TO-FP: Intrinsic has incorrect argument type!
+; VEC-PTR-TO-FP: intrinsic has incorrect argument type!
 
 declare <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4ptr(<4 x ptr>, metadata, metadata, i1)
 
diff --git a/llvm/test/Verifier/callbr.ll b/llvm/test/Verifier/callbr.ll
index 9b819c5fed48b..eb0b6f76c64be 100644
--- a/llvm/test/Verifier/callbr.ll
+++ b/llvm/test/Verifier/callbr.ll
@@ -73,7 +73,7 @@ abnormal:
 declare i32 @llvm.callbr.landingpad.i64(i64)
 define void @callbrpad_bad_type() {
 entry:
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.callbr.landingpad.i64
   %foo = call i32 @llvm.callbr.landingpad.i64(i64 42)
   ret void
diff --git a/llvm/test/Verifier/get-active-lane-mask.ll b/llvm/test/Verifier/get-active-lane-mask.ll
index 141476e6f83d9..351b8ceef59f2 100644
--- a/llvm/test/Verifier/get-active-lane-mask.ll
+++ b/llvm/test/Verifier/get-active-lane-mask.ll
@@ -13,7 +13,7 @@ define <4 x i32> @t1(i32 %IV, i32 %TC) {
 declare i32 @llvm.get.active.lane.mask.i32.i32(i32, i32)
 
 define i32 @t2(i32 %IV, i32 %TC) {
-; CHECK:      Intrinsic has incorrect return type!
+; CHECK:      intrinsic has incorrect return type!
 ; CHECK-NEXT: ptr @llvm.get.active.lane.mask.i32.i32
 
   %res = call i32 @llvm.get.active.lane.mask.i32.i32(i32 %IV, i32 %TC)
diff --git a/llvm/test/Verifier/intrinsic-arg-overloading-struct-ret.ll b/llvm/test/Verifier/intrinsic-arg-overloading-struct-ret.ll
index 7427a01d32e74..ce2e54fff7ba1 100644
--- a/llvm/test/Verifier/intrinsic-arg-overloading-struct-ret.ll
+++ b/llvm/test/Verifier/intrinsic-arg-overloading-struct-ret.ll
@@ -2,7 +2,7 @@
 
 ; LD2 and LD2LANE
 
-; CHECK: Intrinsic has incorrect return type
+; CHECK: intrinsic has incorrect return type
 ; CHECK-NEXT: llvm.aarch64.neon.ld2.v4i32
 define { <4 x i64>, <4 x i32> } @test_ld2_ret(ptr %ptr) {
   %res = call { <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32(ptr %ptr)
@@ -10,7 +10,7 @@ define { <4 x i64>, <4 x i32> } @test_ld2_ret(ptr %ptr) {
 }
 declare { <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32(ptr %ptr)
 
-; CHECK: Intrinsic has incorrect return type
+; CHECK: intrinsic has incorrect return type
 ; CHECK-NEXT: llvm.aarch64.neon.ld2lane.v4i64
 define { <4 x i64>, <4 x i32> } @test_ld2lane_ret(ptr %ptr, <4 x i64> %a, <4 x i64> %b) {
   %res = call { <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld2lane.v4i64(<4 x i64> %a, <4 x i64> %b, i64 0, ptr %ptr)
@@ -18,7 +18,7 @@ define { <4 x i64>, <4 x i32> } @test_ld2lane_ret(ptr %ptr, <4 x i64> %a, <4 x i
 }
 declare { <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld2lane.v4i64(<4 x i64>, <4 x i64>, i64, ptr)
 
-; CHECK: Intrinsic has incorrect argument type
+; CHECK: intrinsic has incorrect argument type
 ; CHECK-NEXT: llvm.aarch64.neon.ld2lane.v4i32
 define { <4 x i32>, <4 x i32> } @test_ld2lane_arg(ptr %ptr, <4 x i64> %a, <4 x i32> %b) {
   %res = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2lane.v4i32(<4 x i64> %a, <4 x i32> %b, i64 0, ptr %ptr)
@@ -28,7 +28,7 @@ declare { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2lane.v4i32(<4 x i64>, <4
 
 ; LD3 and LD3LANE
 
-; CHECK: Intrinsic has incorrect return type
+; CHECK: intrinsic has incorrect return type
 ; CHECK-NEXT: llvm.aarch64.neon.ld3.v4i32
 define { <4 x i32>, <4 x i64>, <4 x i32> } @test_ld3_ret(ptr %ptr) {
   %res = call { <4 x i32>, <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32(ptr %ptr)
@@ -36,7 +36,7 @@ define { <4 x i32>, <4 x i64>, <4 x i32> } @test_ld3_ret(ptr %ptr) {
 }
 declare { <4 x i32>, <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32(ptr %ptr)
 
-; CHECK: Intrinsic has incorrect return type
+; CHECK: intrinsic has incorrect return type
 ; CHECK-NEXT: llvm.aarch64.neon.ld3lane.v4i64
 define { <4 x i64>, <4 x i32>, <4 x i64> } @test_ld3lane_ret(ptr %ptr, <4 x i64> %a, <4 x i64> %b, <4 x i64> %c) {
   %res = call { <4 x i64>, <4 x i32>, <4 x i64> } @llvm.aarch64.neon.ld3lane.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c, i64 0, ptr %ptr)
@@ -44,7 +44,7 @@ define { <4 x i64>, <4 x i32>, <4 x i64> } @test_ld3lane_ret(ptr %ptr, <4 x i64>
 }
 declare { <4 x i64>, <4 x i32>, <4 x i64> } @llvm.aarch64.neon.ld3lane.v4i64(<4 x i64>, <4 x i64>, <4 x i64>, i64, ptr)
 
-; CHECK: Intrinsic has incorrect argument type
+; CHECK: intrinsic has incorrect argument type
 ; CHECK-NEXT: llvm.aarch64.neon.ld3lane.v4i32
 define { <4 x i32>, <4 x i32>, <4 x i32> } @test_ld3lane_arg(ptr %ptr, <4 x i64> %a, <4 x i32> %b, <4 x i32> %c) {
   %res = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3lane.v4i32(<4 x i64> %a, <4 x i32> %b, <4 x i32> %c, i64 0, ptr %ptr)
@@ -54,7 +54,7 @@ declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3lane.v4i32(<4
 
 ; LD4 and LD4LANE
 
-; CHECK: Intrinsic has incorrect return type
+; CHECK: intrinsic has incorrect return type
 ; CHECK-NEXT: llvm.aarch64.neon.ld4.v4i32
 define { <4 x i32>, <4 x i32>, <4 x i64>, <4 x i32> } @test_ld4_ret(ptr %ptr) {
   %res = call { <4 x i32>, <4 x i32>, <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld4.v4i32(ptr %ptr)
@@ -62,7 +62,7 @@ define { <4 x i32>, <4 x i32>, <4 x i64>, <4 x i32> } @test_ld4_ret(ptr %ptr) {
 }
 declare { <4 x i32>, <4 x i32>, <4 x i64>, <4 x i32> } @llvm.aarch64.neon.ld4.v4i32(ptr %ptr)
 
-; CHECK: Intrinsic has incorrect return type
+; CHECK: intrinsic has incorrect return type
 ; CHECK-NEXT: llvm.aarch64.neon.ld4lane.v4i64
 define { <4 x i64>, <4 x i64>, <4 x i32>, <4 x i64> } @test_ld4lane_ret(ptr %ptr, <4 x i64> %a, <4 x i64> %b, <4 x i64> %c, <4 x i64> %d) {
   %res = call { <4 x i64>, <4 x i64>, <4 x i32>, <4 x i64> } @llvm.aarch64.neon.ld4lane.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c, <4 x i64> %d, i64 0, ptr %ptr)
@@ -70,7 +70,7 @@ define { <4 x i64>, <4 x i64>, <4 x i32>, <4 x i64> } @test_ld4lane_ret(ptr %ptr
 }
 declare { <4 x i64>, <4 x i64>, <4 x i32>, <4 x i64> } @llvm.aarch64.neon.ld4lane.v4i64(<4 x i64>, <4 x i64>, <4 x i64>, <4 x i64>, i64, ptr)
 
-; CHECK: Intrinsic has incorrect argument type
+; CHECK: intrinsic has incorrect argument type
 ; CHECK-NEXT: llvm.aarch64.neon.ld4lane.v4i32
 define { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @test_ld4lane_arg(ptr %ptr, <4 x i64> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {
   %res = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld4lane.v4i32(<4 x i64> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d, i64 0, ptr %ptr)
diff --git a/llvm/test/Verifier/intrinsic-bad-arg-type.ll b/llvm/test/Verifier/intrinsic-bad-arg-type.ll
index e9866173cd203..efcdedb1b54f3 100644
--- a/llvm/test/Verifier/intrinsic-bad-arg-type.ll
+++ b/llvm/test/Verifier/intrinsic-bad-arg-type.ll
@@ -1,6 +1,6 @@
 ; RUN: not opt -S -passes=verify 2>&1 < %s | FileCheck %s
 
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.load.nxv4i32.p0
 
 define <vscale x 4 x i32> @masked_load(ptr %addr, <4 x i1> %mask, <vscale x 4 x i32> %dst) {
diff --git a/llvm/test/Verifier/masked-divrem.ll b/llvm/test/Verifier/masked-divrem.ll
index 0543f17ade7f8..8bfb94efbee28 100644
--- a/llvm/test/Verifier/masked-divrem.ll
+++ b/llvm/test/Verifier/masked-divrem.ll
@@ -3,25 +3,25 @@
 ; Reject llvm.masked.{u,s}{div,rem} with a non-integer argument.
 
 define <4 x float> @udiv(<4 x float> %x, <4 x float> %y, <4 x i1> %m) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %res = call <4 x float> @llvm.masked.udiv(<4 x float> %x, <4 x float> %y, <4 x i1> %m)
   ret <4 x float> %res
 }
 
 define <4 x float> @sdiv(<4 x float> %x, <4 x float> %y, <4 x i1> %m) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %res = call <4 x float> @llvm.masked.sdiv(<4 x float> %x, <4 x float> %y, <4 x i1> %m)
   ret <4 x float> %res
 }
 
 define <4 x float> @urem(<4 x float> %x, <4 x float> %y, <4 x i1> %m) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %res = call <4 x float> @llvm.masked.urem(<4 x float> %x, <4 x float> %y, <4 x i1> %m)
   ret <4 x float> %res
 }
 
 define <4 x float> @srem(<4 x float> %x, <4 x float> %y, <4 x i1> %m) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %res = call <4 x float> @llvm.masked.srem(<4 x float> %x, <4 x float> %y, <4 x i1> %m)
   ret <4 x float> %res
 }
diff --git a/llvm/test/Verifier/matrix-intrinsics.ll b/llvm/test/Verifier/matrix-intrinsics.ll
index 43d1a79f0853f..4cabaa1bfe630 100644
--- a/llvm/test/Verifier/matrix-intrinsics.ll
+++ b/llvm/test/Verifier/matrix-intrinsics.ll
@@ -62,9 +62,9 @@ define void @column.major_store(ptr %m, ptr %n, i64 %arg) {
 
 define <4 x float> @transpose_mixed_types(<4 x float> %fvec, <4 x i32> %ivec, i32 %arg) {
 ;
-; CHECK-NEXT: Intrinsic has incorrect argument type!
+; CHECK-NEXT: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.matrix.transpose.v4f32.v4i32
-; CHECK-NEXT: Intrinsic has incorrect argument type!
+; CHECK-NEXT: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.matrix.transpose.v4i32.v4f32
 ;
   %result.0 = call <4 x float> @llvm.matrix.transpose.v4f32.v4i32(<4 x i32> %ivec, i32 0, i32 0)
diff --git a/llvm/test/Verifier/reduction-intrinsics.ll b/llvm/test/Verifier/reduction-intrinsics.ll
index f6eddf0bf3b20..c225776c37135 100644
--- a/llvm/test/Verifier/reduction-intrinsics.ll
+++ b/llvm/test/Verifier/reduction-intrinsics.ll
@@ -3,13 +3,13 @@
 ; Reject a vector reduction with a non-vector argument.
 
 define float @reduce_vector_not_vec_arg(float %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r0 = call float @llvm.vector.reduce.fmax.f32(float %x)
   ret float %r0
 }
 
 define i32 @reduce_vector_not_vec_arg2(i32 %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r0 = call i32 @llvm.vector.reduce.smax.i32(i32 %x)
   ret i32 %r0
 }
@@ -17,7 +17,7 @@ define i32 @reduce_vector_not_vec_arg2(i32 %x) {
 ; Type mismatch for start value.
 
 define float @fadd_match_arg_types(<4 x float> %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call float @llvm.vector.reduce.fadd.v4f32(double 0.0, <4 x float> %x)
   ret float %r
 }
@@ -25,7 +25,7 @@ define float @fadd_match_arg_types(<4 x float> %x) {
 ; Wrong result type.
 
 define i64 @result_too_wide(<4 x i32> %x) {
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
   %r = call i64 @llvm.vector.reduce.add.v4i32(<4 x i32> %x)
   ret i64 %r
 }
@@ -34,25 +34,25 @@ define i64 @result_too_wide(<4 x i32> %x) {
 ; for any vector reduction.
 
 define float @not_float_reduce(<4 x float> %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call float @llvm.vector.reduce.umin.v4f32(<4 x float> %x)
   ret float %r
 }
 
 define ptr @not_pointer_reduce(<4 x ptr> %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call ptr @llvm.vector.reduce.or.v4p0(<4 x ptr> %x)
   ret ptr %r
 }
 
 define i32 @not_integer_reduce(<4 x i32> %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call i32 @llvm.vector.reduce.fadd.v4i32(i32 0, <4 x i32> %x)
   ret i32 %r
 }
 
 define ptr @not_pointer_reduce2(<4 x ptr> %x) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call ptr @llvm.vector.reduce.fmin.v4p0(<4 x ptr> %x)
   ret ptr %r
 }
diff --git a/llvm/test/Verifier/sat-intrinsics.ll b/llvm/test/Verifier/sat-intrinsics.ll
index 44b8d338fc008..bd5ff6c03a769 100644
--- a/llvm/test/Verifier/sat-intrinsics.ll
+++ b/llvm/test/Verifier/sat-intrinsics.ll
@@ -1,37 +1,37 @@
 ; RUN: not opt -S -passes=verify < %s 2>&1 | FileCheck %s
 
 define i32 @sadd_arg_int(float %x, i32 %y) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call i32 @llvm.sadd.sat.i32(float %x, i32 %y)
   ret i32 %r
 }
 
 define i37 @uadd_arg_int(half %x, i37 %y) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call i37 @llvm.uadd.sat.i37(i37 %y, half %x)
   ret i37 %r
 }
 
 define <4 x i32> @ssub_arg_int(<5 x i32> %x, <4 x i32> %y) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call <4 x i32> @llvm.ssub.sat.v4i32(<5 x i32> %x, <4 x i32> %y)
   ret <4 x i32> %r
 }
 
 define <3 x i37> @usub_arg_int(<3 x i37> %x, <3 x i32> %y) {
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
   %r = call <3 x i37> @llvm.usub.sat.v3i37(<3 x i37> %x, <3 x i32> %y)
   ret <3 x i37> %r
 }
 
 define float @ushl_return_int(i32 %x, i32 %y) {
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
   %r = call float @llvm.ushl.sat.i32(i32 %x, i32 %y)
   ret float %r
 }
 
 define <4 x float> @sshl_return_int_vec(<4 x i32> %x, <4 x i32> %y) {
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
   %r = call <4 x float> @llvm.sshl.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
   ret <4 x float> %r
 }
diff --git a/llvm/test/Verifier/scatter_gather.ll b/llvm/test/Verifier/scatter_gather.ll
index 1d6c36b7c5f05..47ca27b7fa89c 100644
--- a/llvm/test/Verifier/scatter_gather.ll
+++ b/llvm/test/Verifier/scatter_gather.ll
@@ -1,7 +1,7 @@
 ; RUN: not opt -passes=verify < %s 2>&1 | FileCheck %s
 
 ; Mask is not a vector
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 define <16 x float> @gather2(<16 x ptr> %ptrs, ptr %mask, <16 x float> %passthru) {
   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0(<16 x ptr> %ptrs, ptr %mask, <16 x float> %passthru)
   ret <16 x float> %res
@@ -9,7 +9,7 @@ define <16 x float> @gather2(<16 x ptr> %ptrs, ptr %mask, <16 x float> %passthru
 declare <16 x float> @llvm.masked.gather.v16f32.v16p0(<16 x ptr>, ptr, <16 x float>)
 
 ; Mask length != return length
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 define <8 x float> @gather3(<8 x ptr> %ptrs, <16 x i1> %mask, <8 x float> %passthru) {
   %res = call <8 x float> @llvm.masked.gather.v8f32.v8p0(<8 x ptr> %ptrs, <16 x i1> %mask, <8 x float> %passthru)
   ret <8 x float> %res
@@ -17,7 +17,7 @@ define <8 x float> @gather3(<8 x ptr> %ptrs, <16 x i1> %mask, <8 x float> %passt
 declare <8 x float> @llvm.masked.gather.v8f32.v8p0(<8 x ptr>, <16 x i1>, <8 x float>)
 
 ; Return type is not a vector
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
 define ptr @gather4(<8 x ptr> %ptrs, <8 x i1> %mask, <8 x float> %passthru) {
   %res = call ptr @llvm.masked.gather.p0.v8p0(<8 x ptr> %ptrs, <8 x i1> %mask, <8 x float> %passthru)
   ret ptr %res
@@ -25,7 +25,7 @@ define ptr @gather4(<8 x ptr> %ptrs, <8 x i1> %mask, <8 x float> %passthru) {
 declare ptr @llvm.masked.gather.p0.v8p0(<8 x ptr>, <8 x i1>, <8 x float>)
 
 ; Value type is not a vector
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 define <8 x float> @gather5(ptr %ptrs, <8 x i1> %mask, <8 x float> %passthru) {
   %res = call <8 x float> @llvm.masked.gather.v8f32.p0(ptr %ptrs, <8 x i1> %mask, <8 x float> %passthru)
   ret <8 x float> %res
@@ -33,7 +33,7 @@ define <8 x float> @gather5(ptr %ptrs, <8 x i1> %mask, <8 x float> %passthru) {
 declare <8 x float> @llvm.masked.gather.v8f32.p0(ptr, <8 x i1>, <8 x float>)
 
 ; Value type is not a vector of pointers
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 define <8 x float> @gather6(<8 x float> %ptrs, <8 x i1> %mask, <8 x float> %passthru) {
   %res = call <8 x float> @llvm.masked.gather.v8f32.v8f32(<8 x float> %ptrs, <8 x i1> %mask, <8 x float> %passthru)
   ret <8 x float> %res
@@ -41,7 +41,7 @@ define <8 x float> @gather6(<8 x float> %ptrs, <8 x i1> %mask, <8 x float> %pass
 declare <8 x float> @llvm.masked.gather.v8f32.v8f32(<8 x float>, <8 x i1>, <8 x float>)
 
 ; Value length!= vector of pointers length
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.gather.v8f32.v16p0
 define <8 x float> @gather8(<16 x ptr> %ptrs, <8 x i1> %mask, <8 x float> %passthru) {
   %res = call <8 x float> @llvm.masked.gather.v8f32.v16p0(<16 x ptr> %ptrs, <8 x i1> %mask, <8 x float> %passthru)
@@ -50,7 +50,7 @@ define <8 x float> @gather8(<16 x ptr> %ptrs, <8 x i1> %mask, <8 x float> %passt
 declare <8 x float> @llvm.masked.gather.v8f32.v16p0(<16 x ptr>, <8 x i1>, <8 x float>)
 
 ; Passthru type doesn't match return type
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.gather.v16i32.v16p0
 define <16 x i32> @gather9(<16 x ptr> %ptrs, <16 x i1> %mask, <8 x i32> %passthru) {
   %res = call <16 x i32> @llvm.masked.gather.v16i32.v16p0(<16 x ptr> %ptrs, <16 x i1> %mask, <8 x i32> %passthru)
@@ -59,7 +59,7 @@ define <16 x i32> @gather9(<16 x ptr> %ptrs, <16 x i1> %mask, <8 x i32> %passthr
 declare <16 x i32> @llvm.masked.gather.v16i32.v16p0(<16 x ptr>, <16 x i1>, <8 x i32>)
 
 ; Mask is not a vector
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.scatter.v16f32.v16p0
 define void @scatter2(<16 x float> %value, <16 x ptr> %ptrs, ptr %mask) {
   call void @llvm.masked.scatter.v16f32.v16p0(<16 x float> %value, <16 x ptr> %ptrs, ptr %mask)
@@ -68,7 +68,7 @@ define void @scatter2(<16 x float> %value, <16 x ptr> %ptrs, ptr %mask) {
 declare void @llvm.masked.scatter.v16f32.v16p0(<16 x float>, <16 x ptr>, ptr)
 
 ; Mask length != value length
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.scatter.v8f32.v8p0
 define void @scatter3(<8 x float> %value, <8 x ptr> %ptrs, <16 x i1> %mask) {
   call void @llvm.masked.scatter.v8f32.v8p0(<8 x float> %value, <8 x ptr> %ptrs, <16 x i1> %mask)
@@ -77,7 +77,7 @@ define void @scatter3(<8 x float> %value, <8 x ptr> %ptrs, <16 x i1> %mask) {
 declare void @llvm.masked.scatter.v8f32.v8p0(<8 x float>, <8 x ptr>, <16 x i1>)
 
 ; Value type is not a vector
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.scatter.p0.v8p0
 define void @scatter4(ptr %value, <8 x ptr> %ptrs, <8 x i1> %mask) {
   call void @llvm.masked.scatter.p0.v8p0(ptr %value, <8 x ptr> %ptrs, <8 x i1> %mask)
@@ -86,7 +86,7 @@ define void @scatter4(ptr %value, <8 x ptr> %ptrs, <8 x i1> %mask) {
 declare void @llvm.masked.scatter.p0.v8p0(ptr, <8 x ptr>, <8 x i1>)
 
 ; ptrs is not a vector
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.scatter.v8f32.p0
 define void @scatter5(<8 x float> %value, ptr %ptrs, <8 x i1> %mask) {
   call void @llvm.masked.scatter.v8f32.p0(<8 x float> %value, ptr %ptrs, <8 x i1> %mask)
@@ -95,7 +95,7 @@ define void @scatter5(<8 x float> %value, ptr %ptrs, <8 x i1> %mask) {
 declare void @llvm.masked.scatter.v8f32.p0(<8 x float>, ptr, <8 x i1>)
 
 ; Value type is not a vector of pointers
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.scatter.v8f32.v8f32
 define void @scatter6(<8 x float> %value, <8 x float> %ptrs, <8 x i1> %mask) {
   call void @llvm.masked.scatter.v8f32.v8f32(<8 x float> %value, <8 x float> %ptrs, <8 x i1> %mask)
@@ -104,7 +104,7 @@ define void @scatter6(<8 x float> %value, <8 x float> %ptrs, <8 x i1> %mask) {
 declare void @llvm.masked.scatter.v8f32.v8f32(<8 x float>, <8 x float>, <8 x i1>)
 
 ; Value length!= vector of pointers length
-; CHECK: Intrinsic has incorrect argument type!
+; CHECK: intrinsic has incorrect argument type!
 ; CHECK-NEXT: ptr @llvm.masked.scatter.v8f32.v16p0
 define void @scatter8(<8 x float> %value, <16 x ptr> %ptrs, <8 x i1> %mask) {
   call void @llvm.masked.scatter.v8f32.v16p0(<8 x float> %value, <16 x ptr> %ptrs, <8 x i1> %mask)
diff --git a/llvm/test/Verifier/stepvector-intrinsic.ll b/llvm/test/Verifier/stepvector-intrinsic.ll
index 42d0ff2c2b87a..e164873f40dcb 100644
--- a/llvm/test/Verifier/stepvector-intrinsic.ll
+++ b/llvm/test/Verifier/stepvector-intrinsic.ll
@@ -3,7 +3,7 @@
 ; Reject stepvector intrinsics that return a scalar
 
 define i32 @stepvector_i32() {
-; CHECK: Intrinsic has incorrect return type!
+; CHECK: intrinsic has incorrect return type!
   %1 = call i32 @llvm.stepvector.i32()
   ret i32 %1
 }
diff --git a/llvm/test/Verifier/varargs-intrinsic.ll b/llvm/test/Verifier/varargs-intrinsic.ll
index 26fe61fb058dc..9c665fae05216 100644
--- a/llvm/test/Verifier/varargs-intrinsic.ll
+++ b/llvm/test/Verifier/varargs-intrinsic.ll
@@ -1,16 +1,19 @@
 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
 
+; llvm.experimental.stackmap is a varg intrisic.
 declare void @llvm.experimental.stackmap(i64, i32)
+
+; llvm.donothing is *not* a vararg intrinsic.
 declare void @llvm.donothing(...)
 
 define void @foo1() {
   call void @llvm.experimental.stackmap(i64 0, i32 12)
-; CHECK: Callsite was not defined with variable arguments!
+; CHECK: intrinsic was not defined with variable arguments!
   ret void
 }
 
 define void @foo2() {
   call void (...) @llvm.donothing(i64 0, i64 1)
-; CHECK: Intrinsic was not defined with variable arguments!
+; CHECK: intrinsic was defined with variable arguments!
   ret void
 }
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 7249d0fa1358a..5474689c9b0b5 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -91,11 +91,13 @@ getOverloadedDeclaration(CallIntrinsicOp op, llvm::Intrinsic::ID id,
   // ATM we do not support variadic intrinsics.
   llvm::FunctionType *ft = llvm::FunctionType::get(resTy, allArgTys, false);
 
+  std::string errorMsg;
+  llvm::raw_string_ostream errorOS(errorMsg);
   SmallVector<llvm::Type *, 8> overloadedTys;
-  if (!llvm::Intrinsic::getIntrinsicSignature(id, ft, overloadedTys)) {
+  if (!llvm::Intrinsic::isSignatureValid(id, ft, overloadedTys, errorOS)) {
     return mlir::emitError(op.getLoc(), "call intrinsic signature ")
            << diagStr(ft) << " to overloaded intrinsic " << op.getIntrinAttr()
-           << " does not match any of the overloads";
+           << " does not match any of the overloads: " << errorMsg;
   }
 
   return llvm::Intrinsic::getOrInsertDeclaration(module, id, overloadedTys);
diff --git a/mlir/test/Dialect/LLVMIR/call-intrin.mlir b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
index bf11e07dc1b6e..81590d8c5f69d 100644
--- a/mlir/test/Dialect/LLVMIR/call-intrin.mlir
+++ b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
@@ -61,7 +61,7 @@ llvm.func @no_intrinsic() {
 
 llvm.func @bad_types() {
   %0 = llvm.mlir.constant(1 : i8) : i8
-  // expected-error at below {{call intrinsic signature i8 (i8) to overloaded intrinsic "llvm.round" does not match any of the overloads}}
+  // expected-error at below {{call intrinsic signature i8 (i8) to overloaded intrinsic "llvm.round" does not match any of the overloads: intrinsic has incorrect return type}}
   // expected-error at below {{LLVM Translation failed for operation: llvm.call_intrinsic}}
   llvm.call_intrinsic "llvm.round"(%0) {} : (i8) -> i8
   llvm.return



More information about the Mlir-commits mailing list