diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 87d075fb03e..65fe30c94f7 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -688,6 +688,9 @@ bool ModuleLinker::shouldLinkFromSource(const GlobalValue &Dest, bool SrcIsDeclaration = isDeclaration(Src); bool DestIsDeclaration = isDeclaration(Dest); + // FIXME: Make datalayout mandatory and just use getDataLayout(). + DataLayout DL(Dest.getParent()); + if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. @@ -702,14 +705,26 @@ bool ModuleLinker::shouldLinkFromSource(const GlobalValue &Dest, // If Dest is external but Src is not: return true; + if (Src.hasCommonLinkage()) { + if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) + return true; + + if (!Dest.hasCommonLinkage()) + return false; + + uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType()); + uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType()); + return SrcSize > DestSize; + } + if (Src.isWeakForLinker()) { assert(!Dest.hasExternalWeakLinkage()); assert(!Dest.hasAvailableExternallyLinkage()); + if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) return true; - return (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) && - Src.hasCommonLinkage(); + return false; } if (Dest.isWeakForLinker()) { diff --git a/test/Linker/Inputs/linkage2.ll b/test/Linker/Inputs/linkage2.ll index 6ecaeb55a0f..6f320e40e0a 100644 --- a/test/Linker/Inputs/linkage2.ll +++ b/test/Linker/Inputs/linkage2.ll @@ -1,3 +1,5 @@ @test1_a = weak global i8 1 @test2_a = external dllimport global i8 + +@test3_a = common global i16 0 diff --git a/test/Linker/linkage2.ll b/test/Linker/linkage2.ll index 99cb22c05c2..283a3b941df 100644 --- a/test/Linker/linkage2.ll +++ b/test/Linker/linkage2.ll @@ -2,7 +2,10 @@ ; RUN: llvm-link %p/Inputs/linkage2.ll %s -S | FileCheck %s @test1_a = common global i8 0 -; CHECK: @test1_a = common global i8 0 +; CHECK-DAG: @test1_a = common global i8 0 @test2_a = global i8 0 -; CHECK: @test2_a = global i8 0 +; CHECK-DAG: @test2_a = global i8 0 + +@test3_a = common global i8 0 +; CHECK-DAG: @test3_a = common global i16 0