diff options
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index b502e5c..4f4a8db 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1676,11 +1676,26 @@ Optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) { Intrinsic::ID ID = F->getIntrinsicID(); StringRef Name = F->getName(); - if (Name == - Intrinsic::getName(ID, ArgTys, F->getParent(), F->getFunctionType())) + std::string WantedName = + Intrinsic::getName(ID, ArgTys, F->getParent(), F->getFunctionType()); + if (Name == WantedName) return None; - auto NewDecl = Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); + Function *NewDecl = [&] { + if (auto *ExistingGV = F->getParent()->getNamedValue(WantedName)) { + if (auto *ExistingF = dyn_cast<Function>(ExistingGV)) + if (ExistingF->getFunctionType() == F->getFunctionType()) + return ExistingF; + + // The name already exists, but is not a function or has the wrong + // prototype. Make place for the new one by renaming the old version. + // Either this old version will be removed later on or the module is + // invalid and we'll get an error. + ExistingGV->setName(WantedName + ".renamed"); + } + return Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); + }(); + NewDecl->setCallingConv(F->getCallingConv()); assert(NewDecl->getFunctionType() == F->getFunctionType() && "Shouldn't change the signature"); |