Skip to content

Commit 8890460

Browse files
committed
Move copying of global initializers below the cloning of functions.
The BlockAddress doesn't have access to the correct basic blocks until the functions have been cloned. This causes the BlockAddress to point to the old values. Just wait until the functions have been cloned before copying the initializers. PR13163 llvm-svn: 194218
1 parent 2aa81a7 commit 8890460

File tree

5 files changed

+163
-5
lines changed

5 files changed

+163
-5
lines changed

llvm/lib/Linker/LinkModules.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,10 +1251,6 @@ bool ModuleLinker::run() {
12511251
for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i)
12521252
linkAppendingVarInit(AppendingVars[i]);
12531253

1254-
// Update the initializers in the DstM module now that all globals that may
1255-
// be referenced are in DstM.
1256-
linkGlobalInits();
1257-
12581254
// Link in the function bodies that are defined in the source module into
12591255
// DstM.
12601256
for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) {
@@ -1336,6 +1332,10 @@ bool ModuleLinker::run() {
13361332
}
13371333
} while (LinkedInAnyFunctions);
13381334

1335+
// Update the initializers in the DstM module now that all globals that may
1336+
// be referenced are in DstM.
1337+
linkGlobalInits();
1338+
13391339
// Now that all of the types from the source are used, resolve any structs
13401340
// copied over to the dest that didn't exist there.
13411341
TypeMap.linkDefinedTypeBodies();

llvm/unittests/Linker/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
set(LLVM_LINK_COMPONENTS
2+
core
3+
linker
4+
)
5+
6+
set(LinkerSources
7+
LinkModulesTest.cpp
8+
)
9+
10+
add_llvm_unittest(LinkerTests
11+
${LinkerSources}
12+
)
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "llvm/Linker.h"
11+
#include "llvm/IR/IRBuilder.h"
12+
#include "llvm/IR/BasicBlock.h"
13+
#include "llvm/IR/DataLayout.h"
14+
#include "llvm/IR/Function.h"
15+
#include "llvm/IR/Module.h"
16+
#include "gtest/gtest.h"
17+
18+
using namespace llvm;
19+
20+
namespace {
21+
22+
class LinkModuleTest : public testing::Test {
23+
protected:
24+
virtual void SetUp() {
25+
LLVMContext &Ctx = getGlobalContext();
26+
M.reset(new Module("MyModule", Ctx));
27+
FunctionType *FTy = FunctionType::get(Type::getInt8PtrTy(Ctx),
28+
Type::getInt32Ty(Ctx),
29+
false /*=isVarArg*/);
30+
F = Function::Create(FTy, Function::ExternalLinkage, "ba_func", M.get());
31+
F->setCallingConv(CallingConv::C);
32+
33+
EntryBB = BasicBlock::Create(Ctx, "entry", F);
34+
SwitchCase1BB = BasicBlock::Create(Ctx, "switch.case.1", F);
35+
SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F);
36+
ExitBB = BasicBlock::Create(Ctx, "exit", F);
37+
38+
ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
39+
40+
GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/,
41+
GlobalValue::InternalLinkage,
42+
0, "switch.bas");
43+
44+
45+
// Global Initializer
46+
std::vector<Constant*> Init;
47+
Constant *SwitchCase1BA = BlockAddress::get(SwitchCase1BB);
48+
Init.push_back(SwitchCase1BA);
49+
50+
Constant *SwitchCase2BA = BlockAddress::get(SwitchCase2BB);
51+
Init.push_back(SwitchCase2BA);
52+
53+
ConstantInt *One = ConstantInt::get(Type::getInt32Ty(Ctx), 1);
54+
Constant *OnePtr = ConstantExpr::getCast(Instruction::IntToPtr,
55+
One, Type::getInt8PtrTy(Ctx));
56+
Init.push_back(OnePtr);
57+
58+
GV->setInitializer(ConstantArray::get(AT, Init));
59+
}
60+
61+
virtual void TearDown() {
62+
M.reset();
63+
}
64+
65+
OwningPtr<Module> M;
66+
Function *F;
67+
GlobalVariable *GV;
68+
BasicBlock *EntryBB;
69+
BasicBlock *SwitchCase1BB;
70+
BasicBlock *SwitchCase2BB;
71+
BasicBlock *ExitBB;
72+
};
73+
74+
TEST_F(LinkModuleTest, BlockAddress) {
75+
LLVMContext &Ctx = getGlobalContext();
76+
IRBuilder<> Builder(EntryBB);
77+
78+
std::vector<Value*> GEPIndices;
79+
GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
80+
GEPIndices.push_back(F->arg_begin());
81+
82+
Value *GEP = Builder.CreateGEP(GV, GEPIndices, "switch.gep");
83+
Value *Load = Builder.CreateLoad(GEP, "switch.load");
84+
85+
Builder.CreateRet(Load);
86+
87+
Builder.SetInsertPoint(SwitchCase1BB);
88+
Builder.CreateBr(ExitBB);
89+
90+
Builder.SetInsertPoint(SwitchCase2BB);
91+
Builder.CreateBr(ExitBB);
92+
93+
Builder.SetInsertPoint(ExitBB);
94+
Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
95+
96+
Module *LinkedModule = new Module("MyModuleLinked", getGlobalContext());
97+
Linker::LinkModules(LinkedModule, M.get(), Linker::PreserveSource, 0);
98+
99+
// Delete the original module.
100+
M.reset();
101+
102+
// Check that the global "@switch.bas" is well-formed.
103+
const GlobalVariable *LinkedGV = LinkedModule->getNamedGlobal("switch.bas");
104+
const Constant *Init = LinkedGV->getInitializer();
105+
106+
// @switch.bas = internal global [3 x i8*]
107+
// [i8* blockaddress(@ba_func, %switch.case.1),
108+
// i8* blockaddress(@ba_func, %switch.case.2),
109+
// i8* inttoptr (i32 1 to i8*)]
110+
111+
ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
112+
EXPECT_EQ(AT, Init->getType());
113+
114+
Value *Elem = Init->getOperand(0);
115+
ASSERT_TRUE(isa<BlockAddress>(Elem));
116+
EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
117+
LinkedModule->getFunction("ba_func"));
118+
EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
119+
LinkedModule->getFunction("ba_func"));
120+
121+
Elem = Init->getOperand(1);
122+
ASSERT_TRUE(isa<BlockAddress>(Elem));
123+
EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
124+
LinkedModule->getFunction("ba_func"));
125+
EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
126+
LinkedModule->getFunction("ba_func"));
127+
128+
delete LinkedModule;
129+
}
130+
131+
} // end anonymous namespace

llvm/unittests/Linker/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
##===- unittests/Linker/Makefile ---------------------------*- Makefile -*-===##
2+
#
3+
# The LLVM Compiler Infrastructure
4+
#
5+
# This file is distributed under the University of Illinois Open Source
6+
# License. See LICENSE.TXT for details.
7+
#
8+
##===----------------------------------------------------------------------===##
9+
10+
LEVEL = ../..
11+
TESTNAME = Linker
12+
LINK_COMPONENTS := core linker
13+
14+
include $(LEVEL)/Makefile.config
15+
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest

llvm/unittests/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
LEVEL = ..
1111

1212
PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo ExecutionEngine IR \
13-
MC Object Option Support Transforms
13+
Linker MC Object Option Support Transforms
1414

1515
include $(LEVEL)/Makefile.common
1616

0 commit comments

Comments
 (0)