blob: 3ceb84c42c7e519ef90a1bb3145efada9dc28084 [file] [log] [blame]
Nick Lewycky1f715782009-09-27 21:39:46 +00001//===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
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
Alon Mishne07d949f2014-03-12 14:42:51 +000010#include "llvm/Transforms/Utils/Cloning.h"
11#include "llvm/ADT/ArrayRef.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000012#include "llvm/ADT/STLExtras.h"
Quentin Colombet4156c982014-04-22 02:17:11 +000013#include "llvm/ADT/SmallPtrSet.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000014#include "llvm/IR/Argument.h"
15#include "llvm/IR/Constant.h"
Alon Mishne07d949f2014-03-12 14:42:51 +000016#include "llvm/IR/DIBuilder.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000017#include "llvm/IR/DebugInfo.h"
Joey Gouly81259292013-04-10 10:37:38 +000018#include "llvm/IR/Function.h"
Joey Gouly81259292013-04-10 10:37:38 +000019#include "llvm/IR/IRBuilder.h"
Alon Mishne07d949f2014-03-12 14:42:51 +000020#include "llvm/IR/InstIterator.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000021#include "llvm/IR/Instructions.h"
Alon Mishne07d949f2014-03-12 14:42:51 +000022#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000023#include "llvm/IR/LLVMContext.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000024#include "llvm/IR/Module.h"
Duncan P. N. Exon Smith4bd905e2015-03-30 21:35:14 +000025#include "llvm/IR/Verifier.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000026#include "gtest/gtest.h"
Nick Lewycky1f715782009-09-27 21:39:46 +000027
28using namespace llvm;
29
David Blaikiea379b1812011-12-20 02:50:00 +000030namespace {
Chandler Carruth35e67062012-06-20 08:39:27 +000031
Nick Lewycky84189ab2010-03-13 19:58:26 +000032class CloneInstruction : public ::testing::Test {
33protected:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000034 void SetUp() override { V = nullptr; }
Nick Lewycky84189ab2010-03-13 19:58:26 +000035
36 template <typename T>
37 T *clone(T *V1) {
38 Value *V2 = V1->clone();
Quentin Colombet4156c982014-04-22 02:17:11 +000039 Orig.insert(V1);
40 Clones.insert(V2);
Nick Lewycky84189ab2010-03-13 19:58:26 +000041 return cast<T>(V2);
42 }
43
Quentin Colombet4156c982014-04-22 02:17:11 +000044 void eraseClones() {
45 DeleteContainerPointers(Clones);
46 }
Nick Lewycky84189ab2010-03-13 19:58:26 +000047
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000048 void TearDown() override {
Nick Lewycky84189ab2010-03-13 19:58:26 +000049 eraseClones();
Quentin Colombet4156c982014-04-22 02:17:11 +000050 DeleteContainerPointers(Orig);
51 delete V;
Nick Lewycky84189ab2010-03-13 19:58:26 +000052 }
53
Quentin Colombet4156c982014-04-22 02:17:11 +000054 SmallPtrSet<Value *, 4> Orig; // Erase on exit
55 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
Nick Lewycky84189ab2010-03-13 19:58:26 +000056
Nick Lewycky1f715782009-09-27 21:39:46 +000057 LLVMContext context;
Quentin Colombet4156c982014-04-22 02:17:11 +000058 Value *V;
Nick Lewycky84189ab2010-03-13 19:58:26 +000059};
60
61TEST_F(CloneInstruction, OverflowBits) {
Quentin Colombet4156c982014-04-22 02:17:11 +000062 V = new Argument(Type::getInt32Ty(context));
Nick Lewycky1f715782009-09-27 21:39:46 +000063
Quentin Colombet4156c982014-04-22 02:17:11 +000064 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
65 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
66 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
Nick Lewycky1f715782009-09-27 21:39:46 +000067
Nick Lewycky84189ab2010-03-13 19:58:26 +000068 BinaryOperator *AddClone = this->clone(Add);
69 BinaryOperator *SubClone = this->clone(Sub);
70 BinaryOperator *MulClone = this->clone(Mul);
71
72 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
73 EXPECT_FALSE(AddClone->hasNoSignedWrap());
74 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
75 EXPECT_FALSE(SubClone->hasNoSignedWrap());
76 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
77 EXPECT_FALSE(MulClone->hasNoSignedWrap());
78
79 eraseClones();
Nick Lewycky1f715782009-09-27 21:39:46 +000080
81 Add->setHasNoUnsignedWrap();
82 Sub->setHasNoUnsignedWrap();
83 Mul->setHasNoUnsignedWrap();
84
Nick Lewycky84189ab2010-03-13 19:58:26 +000085 AddClone = this->clone(Add);
86 SubClone = this->clone(Sub);
87 MulClone = this->clone(Mul);
88
89 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
90 EXPECT_FALSE(AddClone->hasNoSignedWrap());
91 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
92 EXPECT_FALSE(SubClone->hasNoSignedWrap());
93 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
94 EXPECT_FALSE(MulClone->hasNoSignedWrap());
95
96 eraseClones();
Nick Lewycky1f715782009-09-27 21:39:46 +000097
98 Add->setHasNoSignedWrap();
99 Sub->setHasNoSignedWrap();
100 Mul->setHasNoSignedWrap();
101
Nick Lewycky84189ab2010-03-13 19:58:26 +0000102 AddClone = this->clone(Add);
103 SubClone = this->clone(Sub);
104 MulClone = this->clone(Mul);
105
106 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
107 EXPECT_TRUE(AddClone->hasNoSignedWrap());
108 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
109 EXPECT_TRUE(SubClone->hasNoSignedWrap());
110 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
111 EXPECT_TRUE(MulClone->hasNoSignedWrap());
112
113 eraseClones();
Nick Lewycky1f715782009-09-27 21:39:46 +0000114
115 Add->setHasNoUnsignedWrap(false);
116 Sub->setHasNoUnsignedWrap(false);
117 Mul->setHasNoUnsignedWrap(false);
118
Nick Lewycky84189ab2010-03-13 19:58:26 +0000119 AddClone = this->clone(Add);
120 SubClone = this->clone(Sub);
121 MulClone = this->clone(Mul);
122
123 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
124 EXPECT_TRUE(AddClone->hasNoSignedWrap());
125 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
126 EXPECT_TRUE(SubClone->hasNoSignedWrap());
127 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
128 EXPECT_TRUE(MulClone->hasNoSignedWrap());
Nick Lewycky1f715782009-09-27 21:39:46 +0000129}
130
Nick Lewycky84189ab2010-03-13 19:58:26 +0000131TEST_F(CloneInstruction, Inbounds) {
Quentin Colombet4156c982014-04-22 02:17:11 +0000132 V = new Argument(Type::getInt32PtrTy(context));
Nick Lewycky84189ab2010-03-13 19:58:26 +0000133
Nick Lewycky1f715782009-09-27 21:39:46 +0000134 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
135 std::vector<Value *> ops;
136 ops.push_back(Z);
David Blaikieb3a39062015-03-14 21:40:10 +0000137 GetElementPtrInst *GEP =
138 GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
Nick Lewycky84189ab2010-03-13 19:58:26 +0000139 EXPECT_FALSE(this->clone(GEP)->isInBounds());
Nick Lewycky1f715782009-09-27 21:39:46 +0000140
141 GEP->setIsInBounds();
Nick Lewycky84189ab2010-03-13 19:58:26 +0000142 EXPECT_TRUE(this->clone(GEP)->isInBounds());
Nick Lewycky1f715782009-09-27 21:39:46 +0000143}
144
Nick Lewycky84189ab2010-03-13 19:58:26 +0000145TEST_F(CloneInstruction, Exact) {
Quentin Colombet4156c982014-04-22 02:17:11 +0000146 V = new Argument(Type::getInt32Ty(context));
Nick Lewycky1f715782009-09-27 21:39:46 +0000147
Quentin Colombet4156c982014-04-22 02:17:11 +0000148 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
Nick Lewycky84189ab2010-03-13 19:58:26 +0000149 EXPECT_FALSE(this->clone(SDiv)->isExact());
Nick Lewycky1f715782009-09-27 21:39:46 +0000150
151 SDiv->setIsExact(true);
Nick Lewycky84189ab2010-03-13 19:58:26 +0000152 EXPECT_TRUE(this->clone(SDiv)->isExact());
Nick Lewycky1f715782009-09-27 21:39:46 +0000153}
Chandler Carruth35e67062012-06-20 08:39:27 +0000154
Joey Gouly81259292013-04-10 10:37:38 +0000155TEST_F(CloneInstruction, Attributes) {
156 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
157 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
158
159 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
160 BasicBlock *BB = BasicBlock::Create(context, "", F1);
161 IRBuilder<> Builder(BB);
162 Builder.CreateRetVoid();
163
164 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
165
166 Attribute::AttrKind AK[] = { Attribute::NoCapture };
167 AttributeSet AS = AttributeSet::get(context, 0, AK);
168 Argument *A = F1->arg_begin();
169 A->addAttr(AS);
170
171 SmallVector<ReturnInst*, 4> Returns;
172 ValueToValueMapTy VMap;
173 VMap[A] = UndefValue::get(A->getType());
174
175 CloneFunctionInto(F2, F1, VMap, false, Returns);
176 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
Joey Gouly51f6fb92013-04-10 23:21:26 +0000177
178 delete F1;
179 delete F2;
Joey Gouly81259292013-04-10 10:37:38 +0000180}
181
Reid Kleckner23798a92014-03-26 22:26:35 +0000182TEST_F(CloneInstruction, CallingConvention) {
183 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
184 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
185
186 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
187 F1->setCallingConv(CallingConv::Cold);
188 BasicBlock *BB = BasicBlock::Create(context, "", F1);
189 IRBuilder<> Builder(BB);
190 Builder.CreateRetVoid();
191
192 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
193
194 SmallVector<ReturnInst*, 4> Returns;
195 ValueToValueMapTy VMap;
196 VMap[F1->arg_begin()] = F2->arg_begin();
197
198 CloneFunctionInto(F2, F1, VMap, false, Returns);
199 EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
200
201 delete F1;
202 delete F2;
203}
204
Alon Mishne07d949f2014-03-12 14:42:51 +0000205class CloneFunc : public ::testing::Test {
206protected:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000207 void SetUp() override {
Alon Mishne07d949f2014-03-12 14:42:51 +0000208 SetupModule();
209 CreateOldFunc();
210 CreateNewFunc();
211 SetupFinder();
212 }
213
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000214 void TearDown() override { delete Finder; }
Alon Mishne07d949f2014-03-12 14:42:51 +0000215
216 void SetupModule() {
217 M = new Module("", C);
218 }
219
220 void CreateOldFunc() {
221 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
222 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
223 CreateOldFunctionBodyAndDI();
224 }
225
226 void CreateOldFunctionBodyAndDI() {
227 DIBuilder DBuilder(*M);
228 IRBuilder<> IBuilder(C);
229
230 // Function DI
Duncan P. N. Exon Smith2fbe1352015-04-20 22:10:08 +0000231 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000232 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
233 DISubroutineType *FuncType =
Duncan P. N. Exon Smith02083532015-04-16 16:36:23 +0000234 DBuilder.createSubroutineType(File, ParamTypes);
Duncan P. N. Exon Smith2fbe1352015-04-20 22:10:08 +0000235 auto *CU =
236 DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
237 "/file/dir", "CloneFunc", false, "", 0);
Alon Mishne07d949f2014-03-12 14:42:51 +0000238
Duncan P. N. Exon Smith2fbe1352015-04-20 22:10:08 +0000239 auto *Subprogram = DBuilder.createFunction(
240 CU, "f", "f", File, 4, FuncType, true, true, 3, 0, false, OldFunc);
Alon Mishne07d949f2014-03-12 14:42:51 +0000241
242 // Function body
243 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
244 IBuilder.SetInsertPoint(Entry);
245 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
246 IBuilder.SetCurrentDebugLocation(Loc);
247 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
248 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
249 Value* AllocaContent = IBuilder.getInt32(1);
250 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
251 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
252 Instruction* Terminator = IBuilder.CreateRetVoid();
253
254 // Create a local variable around the alloca
Duncan P. N. Exon Smith9928a902015-04-20 18:52:06 +0000255 auto *IntType =
256 DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed);
Duncan P. N. Exon Smith60635e32015-04-21 18:44:06 +0000257 auto *E = DBuilder.createExpression();
Duncan P. N. Exon Smith1e40dc42015-07-31 17:55:53 +0000258 auto *Variable =
259 DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000260 auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
Duncan P. N. Exon Smithcd1aecf2015-04-15 21:18:07 +0000261 DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
262 DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
263 Terminator);
Alon Mishne07d949f2014-03-12 14:42:51 +0000264 // Finalize the debug info
265 DBuilder.finalize();
266
267
268 // Create another, empty, compile unit
269 DIBuilder DBuilder2(*M);
270 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
271 "extra.c", "/file/dir", "CloneFunc", false, "", 0);
272 DBuilder2.finalize();
273 }
274
275 void CreateNewFunc() {
276 ValueToValueMapTy VMap;
Craig Topper66f09ad2014-06-08 22:29:17 +0000277 NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
Alon Mishne07d949f2014-03-12 14:42:51 +0000278 M->getFunctionList().push_back(NewFunc);
279 }
280
281 void SetupFinder() {
282 Finder = new DebugInfoFinder();
283 Finder->processModule(*M);
284 }
285
286 LLVMContext C;
287 Function* OldFunc;
288 Function* NewFunc;
289 Module* M;
290 DebugInfoFinder* Finder;
291};
292
293// Test that a new, distinct function was created.
294TEST_F(CloneFunc, NewFunctionCreated) {
295 EXPECT_NE(OldFunc, NewFunc);
296}
297
298// Test that a new subprogram entry was added and is pointing to the new
299// function, while the original subprogram still points to the old one.
300TEST_F(CloneFunc, Subprogram) {
Duncan P. N. Exon Smith4bd905e2015-03-30 21:35:14 +0000301 EXPECT_FALSE(verifyModule(*M));
302
Alon Mishne07d949f2014-03-12 14:42:51 +0000303 unsigned SubprogramCount = Finder->subprogram_count();
Justin Bognerf404b932014-03-12 17:00:52 +0000304 EXPECT_EQ(2U, SubprogramCount);
Alon Mishne07d949f2014-03-12 14:42:51 +0000305
Alon Mishnead312152014-03-18 09:41:07 +0000306 auto Iter = Finder->subprograms().begin();
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000307 auto *Sub1 = cast<DISubprogram>(*Iter);
Alon Mishne07d949f2014-03-12 14:42:51 +0000308 Iter++;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000309 auto *Sub2 = cast<DISubprogram>(*Iter);
Alon Mishne07d949f2014-03-12 14:42:51 +0000310
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000311 EXPECT_TRUE(
312 (Sub1->getFunction() == OldFunc && Sub2->getFunction() == NewFunc) ||
313 (Sub1->getFunction() == NewFunc && Sub2->getFunction() == OldFunc));
Alon Mishne07d949f2014-03-12 14:42:51 +0000314}
315
316// Test that the new subprogram entry was not added to the CU which doesn't
317// contain the old subprogram entry.
318TEST_F(CloneFunc, SubprogramInRightCU) {
Duncan P. N. Exon Smith4bd905e2015-03-30 21:35:14 +0000319 EXPECT_FALSE(verifyModule(*M));
320
Justin Bognerf404b932014-03-12 17:00:52 +0000321 EXPECT_EQ(2U, Finder->compile_unit_count());
Alon Mishne07d949f2014-03-12 14:42:51 +0000322
Alon Mishnead312152014-03-18 09:41:07 +0000323 auto Iter = Finder->compile_units().begin();
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000324 auto *CU1 = cast<DICompileUnit>(*Iter);
Alon Mishne07d949f2014-03-12 14:42:51 +0000325 Iter++;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000326 auto *CU2 = cast<DICompileUnit>(*Iter);
Duncan P. N. Exon Smith35ef22c2015-04-15 23:19:27 +0000327 EXPECT_TRUE(CU1->getSubprograms().size() == 0 ||
328 CU2->getSubprograms().size() == 0);
Alon Mishne07d949f2014-03-12 14:42:51 +0000329}
330
331// Test that instructions in the old function still belong to it in the
332// metadata, while instruction in the new function belong to the new one.
333TEST_F(CloneFunc, InstructionOwnership) {
Duncan P. N. Exon Smith4bd905e2015-03-30 21:35:14 +0000334 EXPECT_FALSE(verifyModule(*M));
335
Alon Mishne07d949f2014-03-12 14:42:51 +0000336 inst_iterator OldIter = inst_begin(OldFunc);
337 inst_iterator OldEnd = inst_end(OldFunc);
338 inst_iterator NewIter = inst_begin(NewFunc);
339 inst_iterator NewEnd = inst_end(NewFunc);
340 while (OldIter != OldEnd && NewIter != NewEnd) {
341 Instruction& OldI = *OldIter;
342 Instruction& NewI = *NewIter;
343 EXPECT_NE(&OldI, &NewI);
344
345 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
346 if (OldI.hasMetadata()) {
347 const DebugLoc& OldDL = OldI.getDebugLoc();
348 const DebugLoc& NewDL = NewI.getDebugLoc();
349
350 // Verify that the debug location data is the same
351 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
352 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
Duncan P. N. Exon Smith4fff3ec2015-03-30 21:05:29 +0000353
Alon Mishne07d949f2014-03-12 14:42:51 +0000354 // But that they belong to different functions
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000355 auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
356 auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000357 EXPECT_EQ(OldFunc, OldSubprogram->getFunction());
358 EXPECT_EQ(NewFunc, NewSubprogram->getFunction());
Alon Mishne07d949f2014-03-12 14:42:51 +0000359 }
360
361 ++OldIter;
362 ++NewIter;
363 }
364 EXPECT_EQ(OldEnd, OldIter);
365 EXPECT_EQ(NewEnd, NewIter);
366}
367
368// Test that the arguments for debug intrinsics in the new function were
369// properly cloned
370TEST_F(CloneFunc, DebugIntrinsics) {
Duncan P. N. Exon Smith4bd905e2015-03-30 21:35:14 +0000371 EXPECT_FALSE(verifyModule(*M));
372
Alon Mishne07d949f2014-03-12 14:42:51 +0000373 inst_iterator OldIter = inst_begin(OldFunc);
374 inst_iterator OldEnd = inst_end(OldFunc);
375 inst_iterator NewIter = inst_begin(NewFunc);
376 inst_iterator NewEnd = inst_end(NewFunc);
377 while (OldIter != OldEnd && NewIter != NewEnd) {
378 Instruction& OldI = *OldIter;
379 Instruction& NewI = *NewIter;
380 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
381 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
382 EXPECT_TRUE(NewIntrin);
383
384 // Old address must belong to the old function
385 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
386 getParent()->getParent());
387 // New address must belong to the new function
388 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
389 getParent()->getParent());
390
391 // Old variable must belong to the old function
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000392 EXPECT_EQ(OldFunc,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000393 cast<DISubprogram>(OldIntrin->getVariable()->getScope())
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000394 ->getFunction());
Alon Mishne07d949f2014-03-12 14:42:51 +0000395 // New variable must belong to the New function
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000396 EXPECT_EQ(NewFunc,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000397 cast<DISubprogram>(NewIntrin->getVariable()->getScope())
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000398 ->getFunction());
Alon Mishne07d949f2014-03-12 14:42:51 +0000399 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
400 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
401 EXPECT_TRUE(NewIntrin);
402
403 // Old variable must belong to the old function
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000404 EXPECT_EQ(OldFunc,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000405 cast<DISubprogram>(OldIntrin->getVariable()->getScope())
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000406 ->getFunction());
Alon Mishne07d949f2014-03-12 14:42:51 +0000407 // New variable must belong to the New function
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000408 EXPECT_EQ(NewFunc,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000409 cast<DISubprogram>(NewIntrin->getVariable()->getScope())
Duncan P. N. Exon Smith537b4a82015-04-14 03:40:37 +0000410 ->getFunction());
Alon Mishne07d949f2014-03-12 14:42:51 +0000411 }
412
413 ++OldIter;
414 ++NewIter;
415 }
416}
417
David Majnemercda86882015-06-30 22:14:01 +0000418class CloneModule : public ::testing::Test {
419protected:
420 void SetUp() override {
421 SetupModule();
422 CreateOldModule();
423 CreateNewModule();
424 }
425
426 void SetupModule() { OldM = new Module("", C); }
427
428 void CreateOldModule() {
429 IRBuilder<> IBuilder(C);
430
431 auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
432 auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
433 "persfn", OldM);
434 auto *F =
435 Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
436 F->setPersonalityFn(PersFn);
437 auto *Entry = BasicBlock::Create(C, "", F);
438 IBuilder.SetInsertPoint(Entry);
439 IBuilder.CreateRetVoid();
440 }
441
442 void CreateNewModule() { NewM = llvm::CloneModule(OldM); }
443
444 LLVMContext C;
445 Module *OldM;
446 Module *NewM;
447};
448
449TEST_F(CloneModule, Verify) {
450 EXPECT_FALSE(verifyModule(*NewM));
451}
452
Chandler Carruth35e67062012-06-20 08:39:27 +0000453}