Index: include/llvm/IR/Intrinsics.h =================================================================== --- include/llvm/IR/Intrinsics.h +++ include/llvm/IR/Intrinsics.h @@ -142,6 +142,11 @@ bool matchIntrinsicType(Type *Ty, ArrayRef &Infos, SmallVectorImpl &ArgTys); + /// Accumulates overloaded types in ArgTys for the given function type and + /// intrinsic id. + void getOverloadedTypes(FunctionType *FTy, ID id, + SmallVectorImpl &ArgTys); + } // End Intrinsic namespace } // End llvm namespace Index: lib/IR/AutoUpgrade.cpp =================================================================== --- lib/IR/AutoUpgrade.cpp +++ lib/IR/AutoUpgrade.cpp @@ -280,6 +280,21 @@ bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); assert(F != NewFn && "Intrinsic function upgraded to the same function"); + if (!Upgraded) + if (Intrinsic::ID ID = F->getIntrinsicID()) { + // Some types could be renamed during loading if several modules are + // loaded in the same LLVMContext (LTO scenario). In this case we should + // remangle intrinsics names. + SmallVector Tys; + Intrinsic::getOverloadedTypes(F->getFunctionType(), ID, Tys); + StringRef Name = F->getName(); + if (Name != Intrinsic::getName(ID, Tys)) { + F->setName(Name + ".old"); + NewFn = Intrinsic::getDeclaration(F->getParent(), ID, Tys); + Upgraded = true; + } + } + // Upgrade intrinsic attributes. This does not change the function. if (NewFn) F = NewFn; @@ -707,8 +722,13 @@ CI->setName(Name + ".old"); switch (NewFn->getIntrinsicID()) { - default: - llvm_unreachable("Unknown function for CallInst upgrade."); + default: { + SmallVector Args(CI->arg_operands().begin(), + CI->arg_operands().end()); + CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args, Name)); + CI->eraseFromParent(); + return; + } case Intrinsic::arm_neon_vld1: case Intrinsic::arm_neon_vld2: Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -1046,6 +1046,22 @@ llvm_unreachable("unhandled"); } +void Intrinsic::getOverloadedTypes(FunctionType *FTy, ID id, + SmallVectorImpl &ArgTys) { + SmallVector Table; + getIntrinsicInfoTableEntries(id, Table); + ArrayRef TableRef = Table; + + bool Failed = Intrinsic::matchIntrinsicType(FTy->getReturnType(), + TableRef, ArgTys); + assert(!Failed && "Intrinsic return type mismatch"); + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) { + Failed = Intrinsic::matchIntrinsicType(FTy->getParamType(i), + TableRef, ArgTys); + assert(!Failed && "Intrinsic argument type mismatch"); + } +} + /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool Function::hasAddressTaken(const User* *PutOffender) const { Index: lib/Linker/IRMover.cpp =================================================================== --- lib/Linker/IRMover.cpp +++ lib/Linker/IRMover.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/TypeFinder.h" #include "llvm/Transforms/Utils/Cloning.h" using namespace llvm; @@ -904,6 +905,18 @@ if (ShouldLink || !ForAlias) forceRenaming(NewGV, SGV->getName()); } + + if (Function *F = dyn_cast(NewGV)) + if (Intrinsic::ID id = F->getIntrinsicID()) { + // Overloaded intrinsics have overloaded types names as part of their + // names. If we renamed overloaded types we should rename the intrinsic + // as well. + SmallVector Tys; + Intrinsic::getOverloadedTypes(F->getFunctionType(), id, Tys); + if (F->getName() != Intrinsic::getName(id, Tys)) + NewGV = Intrinsic::getDeclaration(&DstM, id, Tys); + } + if (ShouldLink || ForAlias) { if (const Comdat *SC = SGV->getComdat()) { if (auto *GO = dyn_cast(NewGV)) {