forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194218 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
5 changed files
with
163 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
set(LLVM_LINK_COMPONENTS | ||
core | ||
linker | ||
) | ||
|
||
set(LinkerSources | ||
LinkModulesTest.cpp | ||
) | ||
|
||
add_llvm_unittest(LinkerTests | ||
${LinkerSources} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
//===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/Linker.h" | ||
#include "llvm/IR/IRBuilder.h" | ||
#include "llvm/IR/BasicBlock.h" | ||
#include "llvm/IR/DataLayout.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/Module.h" | ||
#include "gtest/gtest.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace { | ||
|
||
class LinkModuleTest : public testing::Test { | ||
protected: | ||
virtual void SetUp() { | ||
LLVMContext &Ctx = getGlobalContext(); | ||
M.reset(new Module("MyModule", Ctx)); | ||
FunctionType *FTy = FunctionType::get(Type::getInt8PtrTy(Ctx), | ||
Type::getInt32Ty(Ctx), | ||
false /*=isVarArg*/); | ||
F = Function::Create(FTy, Function::ExternalLinkage, "ba_func", M.get()); | ||
F->setCallingConv(CallingConv::C); | ||
|
||
EntryBB = BasicBlock::Create(Ctx, "entry", F); | ||
SwitchCase1BB = BasicBlock::Create(Ctx, "switch.case.1", F); | ||
SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F); | ||
ExitBB = BasicBlock::Create(Ctx, "exit", F); | ||
|
||
ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3); | ||
|
||
GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/, | ||
GlobalValue::InternalLinkage, | ||
0, "switch.bas"); | ||
|
||
|
||
// Global Initializer | ||
std::vector<Constant*> Init; | ||
Constant *SwitchCase1BA = BlockAddress::get(SwitchCase1BB); | ||
Init.push_back(SwitchCase1BA); | ||
|
||
Constant *SwitchCase2BA = BlockAddress::get(SwitchCase2BB); | ||
Init.push_back(SwitchCase2BA); | ||
|
||
ConstantInt *One = ConstantInt::get(Type::getInt32Ty(Ctx), 1); | ||
Constant *OnePtr = ConstantExpr::getCast(Instruction::IntToPtr, | ||
One, Type::getInt8PtrTy(Ctx)); | ||
Init.push_back(OnePtr); | ||
|
||
GV->setInitializer(ConstantArray::get(AT, Init)); | ||
} | ||
|
||
virtual void TearDown() { | ||
M.reset(); | ||
} | ||
|
||
OwningPtr<Module> M; | ||
Function *F; | ||
GlobalVariable *GV; | ||
BasicBlock *EntryBB; | ||
BasicBlock *SwitchCase1BB; | ||
BasicBlock *SwitchCase2BB; | ||
BasicBlock *ExitBB; | ||
}; | ||
|
||
TEST_F(LinkModuleTest, BlockAddress) { | ||
LLVMContext &Ctx = getGlobalContext(); | ||
IRBuilder<> Builder(EntryBB); | ||
|
||
std::vector<Value*> GEPIndices; | ||
GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0)); | ||
GEPIndices.push_back(F->arg_begin()); | ||
|
||
Value *GEP = Builder.CreateGEP(GV, GEPIndices, "switch.gep"); | ||
Value *Load = Builder.CreateLoad(GEP, "switch.load"); | ||
|
||
Builder.CreateRet(Load); | ||
|
||
Builder.SetInsertPoint(SwitchCase1BB); | ||
Builder.CreateBr(ExitBB); | ||
|
||
Builder.SetInsertPoint(SwitchCase2BB); | ||
Builder.CreateBr(ExitBB); | ||
|
||
Builder.SetInsertPoint(ExitBB); | ||
Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx))); | ||
|
||
Module *LinkedModule = new Module("MyModuleLinked", getGlobalContext()); | ||
Linker::LinkModules(LinkedModule, M.get(), Linker::PreserveSource, 0); | ||
|
||
// Delete the original module. | ||
M.reset(); | ||
|
||
// Check that the global "@switch.bas" is well-formed. | ||
const GlobalVariable *LinkedGV = LinkedModule->getNamedGlobal("switch.bas"); | ||
const Constant *Init = LinkedGV->getInitializer(); | ||
|
||
// @switch.bas = internal global [3 x i8*] | ||
// [i8* blockaddress(@ba_func, %switch.case.1), | ||
// i8* blockaddress(@ba_func, %switch.case.2), | ||
// i8* inttoptr (i32 1 to i8*)] | ||
|
||
ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3); | ||
EXPECT_EQ(AT, Init->getType()); | ||
|
||
Value *Elem = Init->getOperand(0); | ||
ASSERT_TRUE(isa<BlockAddress>(Elem)); | ||
EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(), | ||
LinkedModule->getFunction("ba_func")); | ||
EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(), | ||
LinkedModule->getFunction("ba_func")); | ||
|
||
Elem = Init->getOperand(1); | ||
ASSERT_TRUE(isa<BlockAddress>(Elem)); | ||
EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(), | ||
LinkedModule->getFunction("ba_func")); | ||
EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(), | ||
LinkedModule->getFunction("ba_func")); | ||
|
||
delete LinkedModule; | ||
} | ||
|
||
} // end anonymous namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
##===- unittests/Linker/Makefile ---------------------------*- Makefile -*-===## | ||
# | ||
# The LLVM Compiler Infrastructure | ||
# | ||
# This file is distributed under the University of Illinois Open Source | ||
# License. See LICENSE.TXT for details. | ||
# | ||
##===----------------------------------------------------------------------===## | ||
|
||
LEVEL = ../.. | ||
TESTNAME = Linker | ||
LINK_COMPONENTS := core linker | ||
|
||
include $(LEVEL)/Makefile.config | ||
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters