1*9880d681SAndroid Build Coastguard Worker //===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/AsmParser/Parser.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Linker/Linker.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Core.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Linker.h"
21*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker namespace {
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker class LinkModuleTest : public testing::Test {
28*9880d681SAndroid Build Coastguard Worker protected:
SetUp()29*9880d681SAndroid Build Coastguard Worker void SetUp() override {
30*9880d681SAndroid Build Coastguard Worker M.reset(new Module("MyModule", Ctx));
31*9880d681SAndroid Build Coastguard Worker FunctionType *FTy = FunctionType::get(
32*9880d681SAndroid Build Coastguard Worker Type::getInt8PtrTy(Ctx), Type::getInt32Ty(Ctx), false /*=isVarArg*/);
33*9880d681SAndroid Build Coastguard Worker F = Function::Create(FTy, Function::ExternalLinkage, "ba_func", M.get());
34*9880d681SAndroid Build Coastguard Worker F->setCallingConv(CallingConv::C);
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker EntryBB = BasicBlock::Create(Ctx, "entry", F);
37*9880d681SAndroid Build Coastguard Worker SwitchCase1BB = BasicBlock::Create(Ctx, "switch.case.1", F);
38*9880d681SAndroid Build Coastguard Worker SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F);
39*9880d681SAndroid Build Coastguard Worker ExitBB = BasicBlock::Create(Ctx, "exit", F);
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/,
44*9880d681SAndroid Build Coastguard Worker GlobalValue::InternalLinkage, nullptr,"switch.bas");
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker // Global Initializer
47*9880d681SAndroid Build Coastguard Worker std::vector<Constant *> Init;
48*9880d681SAndroid Build Coastguard Worker Constant *SwitchCase1BA = BlockAddress::get(SwitchCase1BB);
49*9880d681SAndroid Build Coastguard Worker Init.push_back(SwitchCase1BA);
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker Constant *SwitchCase2BA = BlockAddress::get(SwitchCase2BB);
52*9880d681SAndroid Build Coastguard Worker Init.push_back(SwitchCase2BA);
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker ConstantInt *One = ConstantInt::get(Type::getInt32Ty(Ctx), 1);
55*9880d681SAndroid Build Coastguard Worker Constant *OnePtr = ConstantExpr::getCast(Instruction::IntToPtr, One,
56*9880d681SAndroid Build Coastguard Worker Type::getInt8PtrTy(Ctx));
57*9880d681SAndroid Build Coastguard Worker Init.push_back(OnePtr);
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker GV->setInitializer(ConstantArray::get(AT, Init));
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
TearDown()62*9880d681SAndroid Build Coastguard Worker void TearDown() override { M.reset(); }
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker LLVMContext Ctx;
65*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> M;
66*9880d681SAndroid Build Coastguard Worker Function *F;
67*9880d681SAndroid Build Coastguard Worker ArrayType *AT;
68*9880d681SAndroid Build Coastguard Worker GlobalVariable *GV;
69*9880d681SAndroid Build Coastguard Worker BasicBlock *EntryBB;
70*9880d681SAndroid Build Coastguard Worker BasicBlock *SwitchCase1BB;
71*9880d681SAndroid Build Coastguard Worker BasicBlock *SwitchCase2BB;
72*9880d681SAndroid Build Coastguard Worker BasicBlock *ExitBB;
73*9880d681SAndroid Build Coastguard Worker };
74*9880d681SAndroid Build Coastguard Worker
expectNoDiags(const DiagnosticInfo & DI,void * C)75*9880d681SAndroid Build Coastguard Worker static void expectNoDiags(const DiagnosticInfo &DI, void *C) {
76*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(false);
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,BlockAddress)79*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, BlockAddress) {
80*9880d681SAndroid Build Coastguard Worker IRBuilder<> Builder(EntryBB);
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker std::vector<Value *> GEPIndices;
83*9880d681SAndroid Build Coastguard Worker GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
84*9880d681SAndroid Build Coastguard Worker GEPIndices.push_back(&*F->arg_begin());
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker Value *GEP = Builder.CreateGEP(AT, GV, GEPIndices, "switch.gep");
87*9880d681SAndroid Build Coastguard Worker Value *Load = Builder.CreateLoad(GEP, "switch.load");
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker Builder.CreateRet(Load);
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker Builder.SetInsertPoint(SwitchCase1BB);
92*9880d681SAndroid Build Coastguard Worker Builder.CreateBr(ExitBB);
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker Builder.SetInsertPoint(SwitchCase2BB);
95*9880d681SAndroid Build Coastguard Worker Builder.CreateBr(ExitBB);
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker Builder.SetInsertPoint(ExitBB);
98*9880d681SAndroid Build Coastguard Worker Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker Module *LinkedModule = new Module("MyModuleLinked", Ctx);
101*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(expectNoDiags);
102*9880d681SAndroid Build Coastguard Worker Linker::linkModules(*LinkedModule, std::move(M));
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker // Check that the global "@switch.bas" is well-formed.
105*9880d681SAndroid Build Coastguard Worker const GlobalVariable *LinkedGV = LinkedModule->getNamedGlobal("switch.bas");
106*9880d681SAndroid Build Coastguard Worker const Constant *Init = LinkedGV->getInitializer();
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker // @switch.bas = internal global [3 x i8*]
109*9880d681SAndroid Build Coastguard Worker // [i8* blockaddress(@ba_func, %switch.case.1),
110*9880d681SAndroid Build Coastguard Worker // i8* blockaddress(@ba_func, %switch.case.2),
111*9880d681SAndroid Build Coastguard Worker // i8* inttoptr (i32 1 to i8*)]
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
114*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(AT, Init->getType());
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker Value *Elem = Init->getOperand(0);
117*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(isa<BlockAddress>(Elem));
118*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
119*9880d681SAndroid Build Coastguard Worker LinkedModule->getFunction("ba_func"));
120*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
121*9880d681SAndroid Build Coastguard Worker LinkedModule->getFunction("ba_func"));
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker Elem = Init->getOperand(1);
124*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(isa<BlockAddress>(Elem));
125*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
126*9880d681SAndroid Build Coastguard Worker LinkedModule->getFunction("ba_func"));
127*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
128*9880d681SAndroid Build Coastguard Worker LinkedModule->getFunction("ba_func"));
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker delete LinkedModule;
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker
getExternal(LLVMContext & Ctx,StringRef FuncName)133*9880d681SAndroid Build Coastguard Worker static Module *getExternal(LLVMContext &Ctx, StringRef FuncName) {
134*9880d681SAndroid Build Coastguard Worker // Create a module with an empty externally-linked function
135*9880d681SAndroid Build Coastguard Worker Module *M = new Module("ExternalModule", Ctx);
136*9880d681SAndroid Build Coastguard Worker FunctionType *FTy = FunctionType::get(
137*9880d681SAndroid Build Coastguard Worker Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker Function *F =
140*9880d681SAndroid Build Coastguard Worker Function::Create(FTy, Function::ExternalLinkage, FuncName, M);
141*9880d681SAndroid Build Coastguard Worker F->setCallingConv(CallingConv::C);
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
144*9880d681SAndroid Build Coastguard Worker IRBuilder<> Builder(BB);
145*9880d681SAndroid Build Coastguard Worker Builder.CreateRetVoid();
146*9880d681SAndroid Build Coastguard Worker return M;
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker
getInternal(LLVMContext & Ctx)149*9880d681SAndroid Build Coastguard Worker static Module *getInternal(LLVMContext &Ctx) {
150*9880d681SAndroid Build Coastguard Worker Module *InternalM = new Module("InternalModule", Ctx);
151*9880d681SAndroid Build Coastguard Worker FunctionType *FTy = FunctionType::get(
152*9880d681SAndroid Build Coastguard Worker Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker Function *F =
155*9880d681SAndroid Build Coastguard Worker Function::Create(FTy, Function::InternalLinkage, "bar", InternalM);
156*9880d681SAndroid Build Coastguard Worker F->setCallingConv(CallingConv::C);
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
159*9880d681SAndroid Build Coastguard Worker IRBuilder<> Builder(BB);
160*9880d681SAndroid Build Coastguard Worker Builder.CreateRetVoid();
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker StructType *STy = StructType::create(Ctx, PointerType::get(FTy, 0));
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker GlobalVariable *GV =
165*9880d681SAndroid Build Coastguard Worker new GlobalVariable(*InternalM, STy, false /*=isConstant*/,
166*9880d681SAndroid Build Coastguard Worker GlobalValue::InternalLinkage, nullptr, "g");
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker GV->setInitializer(ConstantStruct::get(STy, F));
169*9880d681SAndroid Build Coastguard Worker return InternalM;
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,EmptyModule)172*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, EmptyModule) {
173*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> InternalM(getInternal(Ctx));
174*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
175*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(expectNoDiags);
176*9880d681SAndroid Build Coastguard Worker Linker::linkModules(*EmptyM, std::move(InternalM));
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,EmptyModule2)179*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, EmptyModule2) {
180*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> InternalM(getInternal(Ctx));
181*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
182*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(expectNoDiags);
183*9880d681SAndroid Build Coastguard Worker Linker::linkModules(*InternalM, std::move(EmptyM));
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,TypeMerge)186*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, TypeMerge) {
187*9880d681SAndroid Build Coastguard Worker LLVMContext C;
188*9880d681SAndroid Build Coastguard Worker SMDiagnostic Err;
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker const char *M1Str = "%t = type {i32}\n"
191*9880d681SAndroid Build Coastguard Worker "@t1 = weak global %t zeroinitializer\n";
192*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> M1 = parseAssemblyString(M1Str, Err, C);
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker const char *M2Str = "%t = type {i32}\n"
195*9880d681SAndroid Build Coastguard Worker "@t2 = weak global %t zeroinitializer\n";
196*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> M2 = parseAssemblyString(M2Str, Err, C);
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(expectNoDiags);
199*9880d681SAndroid Build Coastguard Worker Linker::linkModules(*M1, std::move(M2));
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M1->getNamedGlobal("t1")->getType(),
202*9880d681SAndroid Build Coastguard Worker M1->getNamedGlobal("t2")->getType());
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,NewCAPISuccess)205*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, NewCAPISuccess) {
206*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> DestM(getExternal(Ctx, "foo"));
207*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> SourceM(getExternal(Ctx, "bar"));
208*9880d681SAndroid Build Coastguard Worker LLVMBool Result =
209*9880d681SAndroid Build Coastguard Worker LLVMLinkModules2(wrap(DestM.get()), wrap(SourceM.release()));
210*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, Result);
211*9880d681SAndroid Build Coastguard Worker // "bar" is present in destination module
212*9880d681SAndroid Build Coastguard Worker EXPECT_NE(nullptr, DestM->getFunction("bar"));
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker
diagnosticHandler(LLVMDiagnosticInfoRef DI,void * C)215*9880d681SAndroid Build Coastguard Worker static void diagnosticHandler(LLVMDiagnosticInfoRef DI, void *C) {
216*9880d681SAndroid Build Coastguard Worker auto *Err = reinterpret_cast<std::string *>(C);
217*9880d681SAndroid Build Coastguard Worker char *CErr = LLVMGetDiagInfoDescription(DI);
218*9880d681SAndroid Build Coastguard Worker *Err = CErr;
219*9880d681SAndroid Build Coastguard Worker LLVMDisposeMessage(CErr);
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,NewCAPIFailure)222*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, NewCAPIFailure) {
223*9880d681SAndroid Build Coastguard Worker // Symbol clash between two modules
224*9880d681SAndroid Build Coastguard Worker LLVMContext Ctx;
225*9880d681SAndroid Build Coastguard Worker std::string Err;
226*9880d681SAndroid Build Coastguard Worker LLVMContextSetDiagnosticHandler(wrap(&Ctx), diagnosticHandler, &Err);
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> DestM(getExternal(Ctx, "foo"));
229*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> SourceM(getExternal(Ctx, "foo"));
230*9880d681SAndroid Build Coastguard Worker LLVMBool Result =
231*9880d681SAndroid Build Coastguard Worker LLVMLinkModules2(wrap(DestM.get()), wrap(SourceM.release()));
232*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, Result);
233*9880d681SAndroid Build Coastguard Worker EXPECT_EQ("Linking globals named 'foo': symbol multiply defined!", Err);
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,MoveDistinctMDs)236*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, MoveDistinctMDs) {
237*9880d681SAndroid Build Coastguard Worker LLVMContext C;
238*9880d681SAndroid Build Coastguard Worker SMDiagnostic Err;
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker const char *SrcStr = "define void @foo() !attach !0 {\n"
241*9880d681SAndroid Build Coastguard Worker "entry:\n"
242*9880d681SAndroid Build Coastguard Worker " call void @llvm.md(metadata !1)\n"
243*9880d681SAndroid Build Coastguard Worker " ret void, !attach !2\n"
244*9880d681SAndroid Build Coastguard Worker "}\n"
245*9880d681SAndroid Build Coastguard Worker "declare void @llvm.md(metadata)\n"
246*9880d681SAndroid Build Coastguard Worker "!named = !{!3, !4}\n"
247*9880d681SAndroid Build Coastguard Worker "!0 = distinct !{}\n"
248*9880d681SAndroid Build Coastguard Worker "!1 = distinct !{}\n"
249*9880d681SAndroid Build Coastguard Worker "!2 = distinct !{}\n"
250*9880d681SAndroid Build Coastguard Worker "!3 = distinct !{}\n"
251*9880d681SAndroid Build Coastguard Worker "!4 = !{!3}\n";
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> Src = parseAssemblyString(SrcStr, Err, C);
254*9880d681SAndroid Build Coastguard Worker assert(Src);
255*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Src.get());
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker // Get the addresses of the Metadata before merging.
258*9880d681SAndroid Build Coastguard Worker Function *F = &*Src->begin();
259*9880d681SAndroid Build Coastguard Worker ASSERT_EQ("foo", F->getName());
260*9880d681SAndroid Build Coastguard Worker BasicBlock *BB = &F->getEntryBlock();
261*9880d681SAndroid Build Coastguard Worker auto *CI = cast<CallInst>(&BB->front());
262*9880d681SAndroid Build Coastguard Worker auto *RI = cast<ReturnInst>(BB->getTerminator());
263*9880d681SAndroid Build Coastguard Worker NamedMDNode *NMD = &*Src->named_metadata_begin();
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker MDNode *M0 = F->getMetadata("attach");
266*9880d681SAndroid Build Coastguard Worker MDNode *M1 =
267*9880d681SAndroid Build Coastguard Worker cast<MDNode>(cast<MetadataAsValue>(CI->getArgOperand(0))->getMetadata());
268*9880d681SAndroid Build Coastguard Worker MDNode *M2 = RI->getMetadata("attach");
269*9880d681SAndroid Build Coastguard Worker MDNode *M3 = NMD->getOperand(0);
270*9880d681SAndroid Build Coastguard Worker MDNode *M4 = NMD->getOperand(1);
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker // Confirm a few things about the IR.
273*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M0->isDistinct());
274*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M1->isDistinct());
275*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M2->isDistinct());
276*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M3->isDistinct());
277*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M4->isUniqued());
278*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M3, M4->getOperand(0));
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker // Link into destination module.
281*9880d681SAndroid Build Coastguard Worker auto Dst = llvm::make_unique<Module>("Linked", C);
282*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Dst.get());
283*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(expectNoDiags);
284*9880d681SAndroid Build Coastguard Worker Linker::linkModules(*Dst, std::move(Src));
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker // Check that distinct metadata was moved, not cloned. Even !4, the uniqued
287*9880d681SAndroid Build Coastguard Worker // node, should effectively be moved, since its only operand hasn't changed.
288*9880d681SAndroid Build Coastguard Worker F = &*Dst->begin();
289*9880d681SAndroid Build Coastguard Worker BB = &F->getEntryBlock();
290*9880d681SAndroid Build Coastguard Worker CI = cast<CallInst>(&BB->front());
291*9880d681SAndroid Build Coastguard Worker RI = cast<ReturnInst>(BB->getTerminator());
292*9880d681SAndroid Build Coastguard Worker NMD = &*Dst->named_metadata_begin();
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M0, F->getMetadata("attach"));
295*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M1, cast<MetadataAsValue>(CI->getArgOperand(0))->getMetadata());
296*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M2, RI->getMetadata("attach"));
297*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M3, NMD->getOperand(0));
298*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M4, NMD->getOperand(1));
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker // Confirm a few things about the IR. This shouldn't have changed.
301*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M0->isDistinct());
302*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M1->isDistinct());
303*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M2->isDistinct());
304*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M3->isDistinct());
305*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(M4->isUniqued());
306*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(M3, M4->getOperand(0));
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker
TEST_F(LinkModuleTest,RemangleIntrinsics)309*9880d681SAndroid Build Coastguard Worker TEST_F(LinkModuleTest, RemangleIntrinsics) {
310*9880d681SAndroid Build Coastguard Worker LLVMContext C;
311*9880d681SAndroid Build Coastguard Worker SMDiagnostic Err;
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker // We load two modules inside the same context C. In both modules there is a
314*9880d681SAndroid Build Coastguard Worker // "struct.rtx_def" type. In the module loaded the second (Bar) this type will
315*9880d681SAndroid Build Coastguard Worker // be renamed to "struct.rtx_def.0". Check that the intrinsics which have this
316*9880d681SAndroid Build Coastguard Worker // type in the signature are properly remangled.
317*9880d681SAndroid Build Coastguard Worker const char *FooStr =
318*9880d681SAndroid Build Coastguard Worker "%struct.rtx_def = type { i16 }\n"
319*9880d681SAndroid Build Coastguard Worker "define void @foo(%struct.rtx_def* %a, i8 %b, i32 %c) {\n"
320*9880d681SAndroid Build Coastguard Worker " call void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def* %a, i8 %b, i32 %c, i32 4, i1 true)\n"
321*9880d681SAndroid Build Coastguard Worker " ret void\n"
322*9880d681SAndroid Build Coastguard Worker "}\n"
323*9880d681SAndroid Build Coastguard Worker "declare void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def*, i8, i32, i32, i1)\n";
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker const char *BarStr =
326*9880d681SAndroid Build Coastguard Worker "%struct.rtx_def = type { i16 }\n"
327*9880d681SAndroid Build Coastguard Worker "define void @bar(%struct.rtx_def* %a, i8 %b, i32 %c) {\n"
328*9880d681SAndroid Build Coastguard Worker " call void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def* %a, i8 %b, i32 %c, i32 4, i1 true)\n"
329*9880d681SAndroid Build Coastguard Worker " ret void\n"
330*9880d681SAndroid Build Coastguard Worker "}\n"
331*9880d681SAndroid Build Coastguard Worker "declare void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def*, i8, i32, i32, i1)\n";
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> Foo = parseAssemblyString(FooStr, Err, C);
334*9880d681SAndroid Build Coastguard Worker assert(Foo);
335*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Foo.get());
336*9880d681SAndroid Build Coastguard Worker // Foo is loaded first, so the type and the intrinsic have theis original
337*9880d681SAndroid Build Coastguard Worker // names.
338*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Foo->getFunction("llvm.memset.p0struct.rtx_def.i32"));
339*9880d681SAndroid Build Coastguard Worker ASSERT_FALSE(Foo->getFunction("llvm.memset.p0struct.rtx_def.0.i32"));
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> Bar = parseAssemblyString(BarStr, Err, C);
342*9880d681SAndroid Build Coastguard Worker assert(Bar);
343*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Bar.get());
344*9880d681SAndroid Build Coastguard Worker // Bar is loaded after Foo, so the type is renamed to struct.rtx_def.0. Check
345*9880d681SAndroid Build Coastguard Worker // that the intrinsic is also renamed.
346*9880d681SAndroid Build Coastguard Worker ASSERT_FALSE(Bar->getFunction("llvm.memset.p0struct.rtx_def.i32"));
347*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Bar->getFunction("llvm.memset.p0struct.rtx_def.0.i32"));
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker // Link two modules together.
350*9880d681SAndroid Build Coastguard Worker auto Dst = llvm::make_unique<Module>("Linked", C);
351*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(Dst.get());
352*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(expectNoDiags);
353*9880d681SAndroid Build Coastguard Worker bool Failed = Linker::linkModules(*Foo, std::move(Bar));
354*9880d681SAndroid Build Coastguard Worker ASSERT_FALSE(Failed);
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker // "struct.rtx_def" from Foo and "struct.rtx_def.0" from Bar are isomorphic
357*9880d681SAndroid Build Coastguard Worker // types, so they must be uniquified by linker. Check that they use the same
358*9880d681SAndroid Build Coastguard Worker // intrinsic definition.
359*9880d681SAndroid Build Coastguard Worker Function *F = Foo->getFunction("llvm.memset.p0struct.rtx_def.i32");
360*9880d681SAndroid Build Coastguard Worker ASSERT_EQ(F->getNumUses(), (unsigned)2);
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
364