diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index f24327a139a2..228dc95d78fa 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -202,8 +202,6 @@ void BitcodeCompiler::add(BitcodeFile &F) { continue; } SymbolBody *B = S->body(); - if (B->kind() != SymbolBody::DefinedRegularKind) - continue; if (B->File != &F) continue; @@ -221,7 +219,12 @@ void BitcodeCompiler::add(BitcodeFile &F) { // needs to be able to replace the original definition without conflicting. // In the latter case, we need to allow the combined LTO object to provide a // definition with the same name, for example when doing parallel codegen. - undefine(S); + if (auto *C = dyn_cast(B)) { + if (auto *GO = dyn_cast(GV)) + GO->setAlignment(C->Alignment); + } else { + undefine(S); + } if (!GV) // Module asm symbol. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index e99e5077d7ed..caae09787660 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -351,7 +351,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, bool WasInserted; std::tie(S, WasInserted) = insert(N, Type, StOther & 3, /*CanOmitFromDynSym*/ false, HasUnnamedAddr, - /*IsUsedInRegularObj*/ true, File); + !isa(File), File); int Cmp = compareDefined(S, WasInserted, Binding); if (Cmp > 0) { S->Binding = Binding; @@ -368,8 +368,9 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, if (Config->WarnCommon) warning("multiple common of " + S->body()->getName()); - C->Size = std::max(C->Size, Size); - C->Alignment = std::max(C->Alignment, Alignment); + Alignment = C->Alignment = std::max(C->Alignment, Alignment); + if (Size > C->Size) + replaceBody(S, N, Size, Alignment, StOther, Type, File); } return S; } diff --git a/lld/test/ELF/lto/Inputs/common3.ll b/lld/test/ELF/lto/Inputs/common3.ll new file mode 100644 index 000000000000..a4efc6591570 --- /dev/null +++ b/lld/test/ELF/lto/Inputs/common3.ll @@ -0,0 +1,3 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +@a = common hidden global i64 0, align 4 diff --git a/lld/test/ELF/lto/common2.ll b/lld/test/ELF/lto/common2.ll index 59a2676e4fc9..6b740c4be701 100644 --- a/lld/test/ELF/lto/common2.ll +++ b/lld/test/ELF/lto/common2.ll @@ -7,15 +7,18 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @a = common global i8 0, align 8 +; CHECK-DAG: @a = common global i8 0, align 8 -; Shared library case, we ensure that the bitcode generated file -; has not the a symbol but is appears in the final shared library -; produced. -; CHECK-NOT: @a = common global i8 0, align 8 +@b = common hidden global i32 0, align 4 +define i32 @f() { + %t = load i32, i32* @b, align 4 + ret i32 %t +} +; CHECK-DAG: @b = internal global i32 0, align 4 ; SHARED: Symbol { ; SHARED: Name: a -; SHARED-NEXT: Value: 0x2000 +; SHARED-NEXT: Value: ; SHARED-NEXT: Size: 1 ; SHARED-NEXT: Binding: Global ; SHARED-NEXT: Type: Object diff --git a/lld/test/ELF/lto/common3.ll b/lld/test/ELF/lto/common3.ll new file mode 100644 index 000000000000..a6020ca8c927 --- /dev/null +++ b/lld/test/ELF/lto/common3.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps +; RUN: llvm-dis < %t.lto.bc | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +@a = common hidden global i32 0, align 8 +define i32 @f() { + %t = load i32, i32* @a, align 4 + ret i32 %t +} + +; CHECK: @a = internal global i64 0, align 8