Index: llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -218,10 +218,18 @@ promoteTypeIds(M, ModuleId); - // Returns whether a global has attached type metadata. Such globals may - // participate in CFI or whole-program devirtualization, so they need to - // appear in the merged module instead of the thin LTO module. + // Returns whether a global or its associated global has attached type + // metadata. The former may participate in CFI or whole-program + // devirtualization, so they need to appear in the merged module instead of + // the thin LTO module. Similarly, globals that are associated with globals + // with type metadata need to appear in the merged module because they will + // reference the global's section directly. auto HasTypeMetadata = [](const GlobalObject *GO) { + if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated)) + if (auto *AssocVM = dyn_cast_or_null(MD->getOperand(0))) + if (auto *AssocGO = dyn_cast(AssocVM->getValue())) + if (AssocGO->hasMetadata(LLVMContext::MD_type)) + return true; return GO->hasMetadata(LLVMContext::MD_type); }; Index: llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/associated.ll =================================================================== --- llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/associated.ll +++ llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/associated.ll @@ -0,0 +1,14 @@ +; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t %s +; RUN: llvm-modextract -b -n 0 -o - %t | llvm-dis | FileCheck --check-prefix=M0 %s +; RUN: llvm-modextract -b -n 1 -o - %t | llvm-dis | FileCheck --check-prefix=M1 %s + +; M0: @g = external constant +; M0-NOT: @assoc +; M1: @g = constant i8 1 +; M1: @assoc = private constant i8 2 + +@g = constant i8 1, !type !0 +@assoc = private constant i8 2, !associated !1 + +!0 = !{i32 0, !"typeid"} +!1 = !{i8* @g}