[llvm] r254241 - Correctly handle llvm.global_ctors merging.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 28 19:29:42 PST 2015
Author: rafael
Date: Sat Nov 28 21:29:42 2015
New Revision: 254241
URL: http://llvm.org/viewvc/llvm-project?rev=254241&view=rev
Log:
Correctly handle llvm.global_ctors merging.
We were not handling the case where an entry must be dropped and the
destination module has no llvm.global_ctors.
Added:
llvm/trunk/test/Linker/Inputs/ctors2.ll
llvm/trunk/test/Linker/ctors2.ll
Modified:
llvm/trunk/lib/Linker/LinkModules.cpp
Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=254241&r1=254240&r2=254241&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Sat Nov 28 21:29:42 2015
@@ -1314,54 +1314,57 @@ void ModuleLinker::upgradeMismatchedGlob
/// Return true on error.
bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
const GlobalVariable *SrcGV) {
-
- if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
- return emitError("Linking globals named '" + SrcGV->getName() +
- "': can only link appending global with another appending global!");
-
- ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
ArrayType *SrcTy =
- cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
- Type *EltTy = DstTy->getElementType();
+ cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
+ Type *EltTy = SrcTy->getElementType();
- // Check to see that they two arrays agree on type.
- if (EltTy != SrcTy->getElementType())
- return emitError("Appending variables with different element types!");
- if (DstGV->isConstant() != SrcGV->isConstant())
- return emitError("Appending variables linked with different const'ness!");
-
- if (DstGV->getAlignment() != SrcGV->getAlignment())
- return emitError(
- "Appending variables with different alignment need to be linked!");
-
- if (DstGV->getVisibility() != SrcGV->getVisibility())
- return emitError(
- "Appending variables with different visibility need to be linked!");
-
- if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
- return emitError(
- "Appending variables with different unnamed_addr need to be linked!");
+ uint64_t NewSize = SrcTy->getNumElements();
+ if (DstGV) {
+ ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
+ NewSize += DstTy->getNumElements();
+
+ if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
+ return emitError(
+ "Linking globals named '" + SrcGV->getName() +
+ "': can only link appending global with another appending global!");
+
+ // Check to see that they two arrays agree on type.
+ if (EltTy != DstTy->getElementType())
+ return emitError("Appending variables with different element types!");
+ if (DstGV->isConstant() != SrcGV->isConstant())
+ return emitError("Appending variables linked with different const'ness!");
+
+ if (DstGV->getAlignment() != SrcGV->getAlignment())
+ return emitError(
+ "Appending variables with different alignment need to be linked!");
+
+ if (DstGV->getVisibility() != SrcGV->getVisibility())
+ return emitError(
+ "Appending variables with different visibility need to be linked!");
+
+ if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
+ return emitError(
+ "Appending variables with different unnamed_addr need to be linked!");
- if (StringRef(DstGV->getSection()) != SrcGV->getSection())
- return emitError(
+ if (StringRef(DstGV->getSection()) != SrcGV->getSection())
+ return emitError(
"Appending variables with different section name need to be linked!");
+ }
- uint64_t NewSize = DstTy->getNumElements() + SrcTy->getNumElements();
ArrayType *NewType = ArrayType::get(EltTy, NewSize);
// Create the new global variable.
- GlobalVariable *NG =
- new GlobalVariable(*DstGV->getParent(), NewType, SrcGV->isConstant(),
- DstGV->getLinkage(), /*init*/nullptr, /*name*/"", DstGV,
- DstGV->getThreadLocalMode(),
- DstGV->getType()->getAddressSpace());
+ GlobalVariable *NG = new GlobalVariable(
+ *DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(),
+ /*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(),
+ SrcGV->getType()->getAddressSpace());
// Propagate alignment, visibility and section info.
- copyGVAttributes(NG, DstGV);
+ copyGVAttributes(NG, SrcGV);
AppendingVarInfo AVI;
AVI.NewGV = NG;
- AVI.DstInit = DstGV->getInitializer();
+ AVI.DstInit = DstGV ? DstGV->getInitializer() : nullptr;
AVI.SrcInit = SrcGV->getInitializer();
AppendingVars.push_back(AVI);
@@ -1369,8 +1372,10 @@ bool ModuleLinker::linkAppendingVarProto
// global.
ValueMap[SrcGV] = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
- DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
- DstGV->eraseFromParent();
+ if (DstGV) {
+ DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
+ DstGV->eraseFromParent();
+ }
// Track the source variable so we don't try to link it.
DoNotLinkFromSource.insert(SrcGV);
@@ -1391,8 +1396,8 @@ bool ModuleLinker::linkGlobalValueProto(
DoNotLinkFromSource.insert(SGV);
return false;
}
- if (DGV && DGV->hasAppendingLinkage())
- return linkAppendingVarProto(cast<GlobalVariable>(DGV),
+ if (SGV->hasAppendingLinkage())
+ return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
cast<GlobalVariable>(SGV));
bool LinkFromSrc = true;
@@ -1496,7 +1501,8 @@ static void getArrayElements(const Const
void ModuleLinker::linkAppendingVarInit(AppendingVarInfo &AVI) {
// Merge the initializer.
SmallVector<Constant *, 16> DstElements;
- getArrayElements(AVI.DstInit, DstElements);
+ if (AVI.DstInit)
+ getArrayElements(AVI.DstInit, DstElements);
SmallVector<Constant *, 16> SrcElements;
getArrayElements(AVI.SrcInit, SrcElements);
Added: llvm/trunk/test/Linker/Inputs/ctors2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/ctors2.ll?rev=254241&view=auto
==============================================================================
--- llvm/trunk/test/Linker/Inputs/ctors2.ll (added)
+++ llvm/trunk/test/Linker/Inputs/ctors2.ll Sat Nov 28 21:29:42 2015
@@ -0,0 +1,6 @@
+$foo = comdat any
+ at foo = global i8 1, comdat
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* @foo }]
+define void @bar() comdat($foo) {
+ ret void
+}
Added: llvm/trunk/test/Linker/ctors2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/ctors2.ll?rev=254241&view=auto
==============================================================================
--- llvm/trunk/test/Linker/ctors2.ll (added)
+++ llvm/trunk/test/Linker/ctors2.ll Sat Nov 28 21:29:42 2015
@@ -0,0 +1,7 @@
+; RUN: llvm-link -S %s %p/Inputs/ctors2.ll -o - | FileCheck %s
+
+$foo = comdat any
+ at foo = global i8 0, comdat
+
+; CHECK: @foo = global i8 0, comdat
+; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
More information about the llvm-commits
mailing list