ThinLTOBitcodeWriter: Include globals associated with type metadata globals in the merged module.

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.

Differential Revision: https://reviews.llvm.org/D65312

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367242 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Peter Collingbourne 2019-07-29 17:22:40 +00:00
parent 4f4ab9ef4c
commit 48cc4c716b
2 changed files with 25 additions and 3 deletions

View File

@ -218,10 +218,18 @@ void splitAndWriteThinLTOBitcode(
promoteTypeIds(M, ModuleId); promoteTypeIds(M, ModuleId);
// Returns whether a global has attached type metadata. Such globals may // Returns whether a global or its associated global has attached type
// participate in CFI or whole-program devirtualization, so they need to // metadata. The former may participate in CFI or whole-program
// appear in the merged module instead of the thin LTO module. // 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) { auto HasTypeMetadata = [](const GlobalObject *GO) {
if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated))
if (auto *AssocVM = dyn_cast_or_null<ValueAsMetadata>(MD->getOperand(0)))
if (auto *AssocGO = dyn_cast<GlobalObject>(AssocVM->getValue()))
if (AssocGO->hasMetadata(LLVMContext::MD_type))
return true;
return GO->hasMetadata(LLVMContext::MD_type); return GO->hasMetadata(LLVMContext::MD_type);
}; };

View File

@ -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}