diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -222,6 +222,13 @@ /// This method returns true on error. bool matchIntrinsicVarArg(bool isVarArg, ArrayRef &Infos); + /// Gets the type arguments of an intrinsic call by matching type contraints + /// specified by the .td file. The overloaded types are pushed into the + /// AgTys vector. + /// + /// Returns false if the given function is not a valid intrinsic call. + bool getIntrinsicSignature(Function *F, SmallVectorImpl &ArgTys); + // Checks if the intrinsic name matches with its signature and if not // returns the declaration with the same signature and remangled name. llvm::Optional remangleIntrinsicFunction(Function *F); diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1424,31 +1424,40 @@ return true; } -Optional Intrinsic::remangleIntrinsicFunction(Function *F) { +bool Intrinsic::getIntrinsicSignature(Function *F, + SmallVectorImpl &ArgTys) { Intrinsic::ID ID = F->getIntrinsicID(); if (!ID) - return None; + return false; - FunctionType *FTy = F->getFunctionType(); - // Accumulate an array of overloaded types for the given intrinsic - SmallVector ArgTys; - { - SmallVector Table; - getIntrinsicInfoTableEntries(ID, Table); - ArrayRef TableRef = Table; - - if (Intrinsic::matchIntrinsicSignature(FTy, TableRef, ArgTys)) - return None; - if (Intrinsic::matchIntrinsicVarArg(FTy->isVarArg(), TableRef)) - return None; + SmallVector Table; + getIntrinsicInfoTableEntries(ID, Table); + ArrayRef TableRef = Table; + + if (Intrinsic::matchIntrinsicSignature(F->getFunctionType(), TableRef, + ArgTys) != + Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) { + return false; } + if (Intrinsic::matchIntrinsicVarArg(F->getFunctionType()->isVarArg(), + TableRef)) + return false; + return true; +} +Optional Intrinsic::remangleIntrinsicFunction(Function *F) { + SmallVector ArgTys; + if (!getIntrinsicSignature(F, ArgTys)) + return None; + + Intrinsic::ID ID = F->getIntrinsicID(); StringRef Name = F->getName(); if (Name == Intrinsic::getName(ID, ArgTys)) return None; auto NewDecl = Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); NewDecl->setCallingConv(F->getCallingConv()); + FunctionType *FTy = F->getFunctionType(); assert(NewDecl->getFunctionType() == FTy && "Shouldn't change the signature"); return NewDecl; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1130,17 +1130,11 @@ return nullptr; } - // Determine the overload types of the original intrinsic. - auto IID = II->getIntrinsicID(); - SmallVector Table; - getIntrinsicInfoTableEntries(IID, Table); - ArrayRef TableRef = Table; - // Validate function argument and return types, extracting overloaded types // along the way. - FunctionType *FTy = II->getCalledFunction()->getFunctionType(); SmallVector OverloadTys; - Intrinsic::matchIntrinsicSignature(FTy, TableRef, OverloadTys); + if (!Intrinsic::getIntrinsicSignature(II->getCalledFunction(), OverloadTys)) + return nullptr; Module *M = II->getParent()->getParent()->getParent(); Type *EltTy = IIVTy->getElementType(); @@ -1148,7 +1142,8 @@ (NewNumElts == 1) ? EltTy : FixedVectorType::get(EltTy, NewNumElts); OverloadTys[0] = NewTy; - Function *NewIntrin = Intrinsic::getDeclaration(M, IID, OverloadTys); + Function *NewIntrin = + Intrinsic::getDeclaration(M, II->getIntrinsicID(), OverloadTys); CallInst *NewCall = Builder.CreateCall(NewIntrin, Args); NewCall->takeName(II);