Skip to content

Commit b785c99

Browse files
authored
Avoid merging globals residing in different comdats (#172835)
The global-merge pass may merge globals residing in different comdat groups, which may later confuse linker if section GC is being used. In particular this may happen when merging instrumentation profiler counters when their corresponding __llvm_prf_cnts sections are being merged into a single one and moved out of a comdat group, containing __llvm_prf_cnts and __llvm_prf_data sections. After that __llvm_prf_data section is becoming orphaned and is garbage-collected when --gc-sections linker flag is used.
1 parent bbd60c0 commit b785c99

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

llvm/lib/CodeGen/GlobalMerge.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ bool GlobalMergeImpl::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
562562

563563
MergedGV->setAlignment(MaxAlign);
564564
MergedGV->setSection(Globals[i]->getSection());
565+
MergedGV->setComdat(Globals[i]->getComdat());
565566

566567
LLVM_DEBUG(dbgs() << "MergedGV: " << *MergedGV << "\n");
567568

@@ -677,7 +678,8 @@ bool GlobalMergeImpl::run(Module &M) {
677678
IsMachO = M.getTargetTriple().isOSBinFormatMachO();
678679

679680
auto &DL = M.getDataLayout();
680-
MapVector<std::pair<unsigned, StringRef>, SmallVector<GlobalVariable *, 0>>
681+
MapVector<std::tuple<unsigned, StringRef, Comdat *>,
682+
SmallVector<GlobalVariable *, 0>>
681683
Globals, ConstGlobals, BSSGlobals;
682684
bool Changed = false;
683685
setMustKeepGlobalVariables(M);
@@ -735,28 +737,28 @@ bool GlobalMergeImpl::run(Module &M) {
735737
if (CanMerge) {
736738
if (TM &&
737739
TargetLoweringObjectFile::getKindForGlobal(&GV, *TM).isBSS())
738-
BSSGlobals[{AddressSpace, Section}].push_back(&GV);
740+
BSSGlobals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
739741
else if (GV.isConstant())
740-
ConstGlobals[{AddressSpace, Section}].push_back(&GV);
742+
ConstGlobals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
741743
else
742-
Globals[{AddressSpace, Section}].push_back(&GV);
744+
Globals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
743745
}
744746
LLVM_DEBUG(dbgs() << "GV " << (CanMerge ? "" : "not ") << "to merge: " << GV
745747
<< "\n");
746748
}
747749

748750
for (auto &P : Globals)
749751
if (P.second.size() > 1)
750-
Changed |= doMerge(P.second, M, false, P.first.first);
752+
Changed |= doMerge(P.second, M, false, std::get<0>(P.first));
751753

752754
for (auto &P : BSSGlobals)
753755
if (P.second.size() > 1)
754-
Changed |= doMerge(P.second, M, false, P.first.first);
756+
Changed |= doMerge(P.second, M, false, std::get<0>(P.first));
755757

756758
if (Opt.MergeConstantGlobals)
757759
for (auto &P : ConstGlobals)
758760
if (P.second.size() > 1)
759-
Changed |= doMerge(P.second, M, true, P.first.first);
761+
Changed |= doMerge(P.second, M, true, std::get<0>(P.first));
760762

761763
return Changed;
762764
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-enable-global-merge -global-merge-group-by-use=false < %s | FileCheck %s
2+
; CHECK-NOT: _MergedGlobals
3+
4+
$__profc_begin = comdat nodeduplicate
5+
$__profc_end = comdat nodeduplicate
6+
7+
@__profc_begin = private global [2 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
8+
@__profd_begin = private global { i64, i64, i64, i64, ptr, ptr, i32, [3 x i16], i32 } { i64 -1301828029439649651, i64 172590168, i64 sub (i64 ptrtoint (ptr @__profc_begin to i64), i64 ptrtoint (ptr @__profd_begin to i64)), i64 0, ptr null, ptr null, i32 2, [3 x i16] zeroinitializer, i32 0 }, section "__llvm_prf_data", comdat($__profc_begin), align 8
9+
@__profc_end = private global [2 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
10+
@__profd_end = private global { i64, i64, i64, i64, ptr, ptr, i32, [3 x i16], i32 } { i64 3274037854792712831, i64 172590168, i64 sub (i64 ptrtoint (ptr @__profc_end to i64), i64 ptrtoint (ptr @__profd_end to i64)), i64 0, ptr null, ptr null, i32 2, [3 x i16] zeroinitializer, i32 0 }, section "__llvm_prf_data", comdat($__profc_end), align 8
11+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; RUN: opt -global-merge -global-merge-max-offset=16 -global-merge-group-by-use=false %s -S -o - | FileCheck %s
2+
; CHECK: @_MergedGlobals = private global <{ i64, i64 }> zeroinitializer, section "__foo", comdat($__foo), align 8
3+
4+
$__foo = comdat nodeduplicate
5+
6+
@__bar = private global i64 0, section "__foo", comdat($__foo), align 8
7+
@__baz = private global i64 0, section "__foo", comdat($__foo), align 8

0 commit comments

Comments
 (0)