Index: llvm/lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -209,13 +209,44 @@ bool ExportsSymbols = false; auto AddGlobal = [&](GlobalValue &GV) { if (GV.isDeclaration() || GV.getName().startswith("llvm.") || - !GV.hasExternalLinkage() || GV.hasComdat()) + (!GV.hasExternalLinkage() && + !(GV.hasWeakLinkage() || GV.hasWeakAnyLinkage() || + GV.hasWeakODRLinkage() || GV.hasLinkOnceLinkage() || + GV.hasLinkOnceODRLinkage() || GV.hasCommonLinkage() || + GV.hasComdat())) || + GV.hasComdat()) return; ExportsSymbols = true; Md5.update(GV.getName()); Md5.update(ArrayRef{0}); }; + if (auto *Used = M->getNamedGlobal("llvm.used")) { + if (const auto *A = dyn_cast(Used->getInitializer())) { + for (const Value *Op : A->operands()) { + if (const auto *GV = dyn_cast(Op->stripPointerCasts())) { + Md5.update(GV->getName()); + Md5.update(ArrayRef{0}); + } + } + } + } + if (auto *Used = M->getNamedGlobal("llvm.global_ctors")) { + if (const auto *A = dyn_cast(Used->getInitializer())) { + for (const Value *Op : A->operands()) { + if (const auto *GV = dyn_cast(Op)) { + auto *Elt = GV->getAggregateElement(1); + Md5.update(Elt->getName()); + Md5.update(ArrayRef{0}); + } + } + } + } + + Md5.update(M->getModuleIdentifier()); + Md5.update(ArrayRef{0}); + ExportsSymbols = true; + for (auto &F : *M) AddGlobal(F); for (auto &GV : M->globals()) @@ -233,6 +264,9 @@ SmallString<32> Str; MD5::stringifyResult(R, Str); + + LLVM_DEBUG(dbgs() << "Generated ModuleID: " << Str.str() << "\n"); + return ("." + Str).str(); } Index: llvm/test/LTO/Resolution/X86/llvm-used-moduleid.ll =================================================================== --- /dev/null +++ llvm/test/LTO/Resolution/X86/llvm-used-moduleid.ll @@ -0,0 +1,19 @@ +; RUN: opt <%s -thinlto-bc -thinlto-split-lto-unit -o %t0 +; RUN: llvm-bcanalyzer %t0 | FileCheck %s + +target triple="x86_64-pc-linux-gnu" + +@llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @a to i8*)], !type !0 + +declare i1 @llvm.type.test(i8*, metadata) +declare void @llvm.assume(i1) + +; CHECK: GLOBALVAL_SUMMARY_BLOCK +; CHECK: FULL_LTO_GLOBALVAL_SUMMARY_BLOCK +define internal void @a() { + %1 = call i1 @llvm.type.test(i8* undef, metadata !"a") + call void @llvm.assume(i1 %1) + ret void +} + +!0 = !{i64 16, !"a"} Index: llvm/test/LTO/Resolution/X86/weak-linkage-moduleid.ll =================================================================== --- /dev/null +++ llvm/test/LTO/Resolution/X86/weak-linkage-moduleid.ll @@ -0,0 +1,19 @@ +; RUN: opt <%s -thinlto-bc -thinlto-split-lto-unit -o %t0 +; RUN: llvm-bcanalyzer %t0 | FileCheck %s + +target triple="x86_64-pc-linux-gnu" + +@p = weak global void ()* @a, !type !0 + +declare i1 @llvm.type.test(i8*, metadata) +declare void @llvm.assume(i1) + +; CHECK: GLOBALVAL_SUMMARY_BLOCK +; CHECK: FULL_LTO_GLOBALVAL_SUMMARY_BLOCK +define internal void @a() { + %1 = call i1 @llvm.type.test(i8* undef, metadata !"a") + call void @llvm.assume(i1 %1) + ret void +} + +!0 = !{i64 16, !"a"} Index: llvm/test/LTO/X86/path-moduleid.ll =================================================================== --- /dev/null +++ llvm/test/LTO/X86/path-moduleid.ll @@ -0,0 +1,27 @@ +; REQUIRES: asserts +; Test that chaning the path to the module doesn't effect the ModuleID. This +; file and Inputs/path-moduleid.ll have the same content, and thus should have +; the same ModuleID. +; RUN: opt -o /dev/null -thinlto-bc -thinlto-split-lto-unit=1 --debug-only=moduleutils %s 2>%t0 +; RUN: mkdir -p %t; cp %s %t/path-moduleid.ll +; RUN: opt -o /dev/null -thinlto-bc -thinlto-split-lto-unit=1 --debug-only=moduleutils %t/path-moduleid.ll 2>%t1 +; RUN: FileCheck %s <%t0 +; RUN: FileCheck %s <%t1 +; RUN: not diff %t0 %t1 + +; CHECK: Generated ModuleID: +target triple="x86_64-pc-linux-gnu" + +@llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @a to i8*)], !type !0 + +declare i1 @llvm.type.test(i8*, metadata) +declare void @llvm.assume(i1) + +define internal void @a() { + %1 = call i1 @llvm.type.test(i8* undef, metadata !"a") + call void @llvm.assume(i1 %1) + ret void +} + + +!0 = !{i64 16, !"a"} Index: llvm/test/Transforms/Util/generate-moduleid.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/Util/generate-moduleid.ll @@ -0,0 +1,17 @@ +; REQUIRES: asserts +; RUN: opt --thinlto-split-lto-unit=1 --thinlto-bc -o %t0 -debug-only=moduleutils <%s 2>&1 | FileCheck %s +; CHECK: Generated ModuleID + +target triple="x86_64-pc-linux-gnu" + +declare i1 @llvm.type.test(i8*, metadata) + +define internal void @foo() !type !1{ +entry: + %0 = tail call i1 @llvm.type.test(i8* null, metadata !"") + ret void +} + +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 103, void ()* @foo, i8* null }] + +!1 = !{i64 0, !"foo"}