[GlobalMerge] Preserve symbol visibility when merging globals

Symbols created for merged external global variables have default
visibility. This can break programs when compiling with -Oz
-fvisibility=hidden as symbols that should be hidden will be exported at
link time.

Differential Revision: https://reviews.llvm.org/D73235
This commit is contained in:
Michael Spang 2020-01-28 12:43:07 -08:00 committed by Eli Friedman
parent eaabaf7e04
commit a2fb2c0ddc
2 changed files with 28 additions and 0 deletions

View File

@ -524,6 +524,7 @@ bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
for (ssize_t k = i, idx = 0; k != j; k = GlobalSet.find_next(k), ++idx) {
GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
std::string Name = Globals[k]->getName();
GlobalValue::VisibilityTypes Visibility = Globals[k]->getVisibility();
GlobalValue::DLLStorageClassTypes DLLStorage =
Globals[k]->getDLLStorageClass();
@ -549,6 +550,7 @@ bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
if (Linkage != GlobalValue::InternalLinkage || !IsMachO) {
GlobalAlias *GA = GlobalAlias::create(Tys[StructIdxs[idx]], AddrSpace,
Linkage, Name, GEP, &M);
GA->setVisibility(Visibility);
GA->setDLLStorageClass(DLLStorage);
}

View File

@ -0,0 +1,26 @@
; RUN: llc %s -mtriple=arm-none-linux-gnu -o - | FileCheck %s
; RUN: llc %s -mtriple=aarch64-none-linux-gnu -o - | FileCheck %s
@x = hidden global i32 0, align 4
@y = hidden global i32 0, align 4
define hidden void @f() #0 {
store i32 0, i32* @x, align 4
store i32 0, i32* @y, align 4
ret void
}
attributes #0 = { minsize optsize }
; CHECK: .local .L_MergedGlobals
; CHECK: .comm .L_MergedGlobals,8,4
; CHECK: .globl x
; CHECK: .hidden x
; CHECK: .set x, .L_MergedGlobals
; CHECK: .size x, 4
; CHECK: .globl y
; CHECK: .hidden y
; CHECK: .set y, .L_MergedGlobals+4
; CHECK: .size y, 4