[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