Index: llvm/include/llvm/Transforms/Utils/ModuleUtils.h =================================================================== --- llvm/include/llvm/Transforms/Utils/ModuleUtils.h +++ llvm/include/llvm/Transforms/Utils/ModuleUtils.h @@ -107,7 +107,10 @@ /// If the module has no strong external symbols (such a module may still have a /// semantic effect if it performs global initialization), we cannot produce a /// unique identifier for this module, so we return the empty string. -std::string getUniqueModuleId(Module *M); +/// +/// If UseModuleId is true, we include the ModuleIdentifier string. This is +/// however not guaranteed to be unique. +std::string getUniqueModuleId(Module *M, bool UseModuleId = false); class CallInst; namespace VFABI { Index: llvm/lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -252,7 +252,7 @@ }); } -std::string llvm::getUniqueModuleId(Module *M) { +std::string llvm::getUniqueModuleId(Module *M, bool UseModuleId) { MD5 Md5; bool ExportsSymbols = false; auto AddGlobal = [&](GlobalValue &GV) { @@ -273,8 +273,18 @@ for (auto &IF : M->ifuncs()) AddGlobal(IF); - if (!ExportsSymbols) - return ""; + // When UseModuleId is true, we include the module identifier also. Module + // ID helps when there are no globals exported or when multiple definitions + // of the same globals are allowed in different modules (with "-z muldefs"). + // While it is highly likely that Module identifier is unique, it is not + // guaranteed. + if (UseModuleId && !M->getModuleIdentifier().empty()) { + Md5.update(M->getModuleIdentifier()); + Md5.update(ArrayRef{0}); + } else { + if (!ExportsSymbols) + return ""; + } MD5::MD5Result R; Md5.final(R);