1 //===- 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
10 #include "llvm/Transforms/Utils/Cloning.h"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/SmallPtrSet.h"
14 #include "llvm/IR/Argument.h"
15 #include "llvm/IR/Constant.h"
16 #include "llvm/IR/DIBuilder.h"
17 #include "llvm/IR/DebugInfo.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/InstIterator.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/IR/IntrinsicInst.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/Verifier.h"
26 #include "gtest/gtest.h"
27
28 using namespace llvm;
29
30 namespace {
31
32 class CloneInstruction : public ::testing::Test {
33 protected:
SetUp()34 void SetUp() override { V = nullptr; }
35
36 template <typename T>
clone(T * V1)37 T *clone(T *V1) {
38 Value *V2 = V1->clone();
39 Orig.insert(V1);
40 Clones.insert(V2);
41 return cast<T>(V2);
42 }
43
eraseClones()44 void eraseClones() {
45 DeleteContainerPointers(Clones);
46 }
47
TearDown()48 void TearDown() override {
49 eraseClones();
50 DeleteContainerPointers(Orig);
51 delete V;
52 }
53
54 SmallPtrSet<Value *, 4> Orig; // Erase on exit
55 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
56
57 LLVMContext context;
58 Value *V;
59 };
60
TEST_F(CloneInstruction,OverflowBits)61 TEST_F(CloneInstruction, OverflowBits) {
62 V = new Argument(Type::getInt32Ty(context));
63
64 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);
67
68 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();
80
81 Add->setHasNoUnsignedWrap();
82 Sub->setHasNoUnsignedWrap();
83 Mul->setHasNoUnsignedWrap();
84
85 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();
97
98 Add->setHasNoSignedWrap();
99 Sub->setHasNoSignedWrap();
100 Mul->setHasNoSignedWrap();
101
102 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();
114
115 Add->setHasNoUnsignedWrap(false);
116 Sub->setHasNoUnsignedWrap(false);
117 Mul->setHasNoUnsignedWrap(false);
118
119 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());
129 }
130
TEST_F(CloneInstruction,Inbounds)131 TEST_F(CloneInstruction, Inbounds) {
132 V = new Argument(Type::getInt32PtrTy(context));
133
134 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
135 std::vector<Value *> ops;
136 ops.push_back(Z);
137 GetElementPtrInst *GEP =
138 GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
139 EXPECT_FALSE(this->clone(GEP)->isInBounds());
140
141 GEP->setIsInBounds();
142 EXPECT_TRUE(this->clone(GEP)->isInBounds());
143 }
144
TEST_F(CloneInstruction,Exact)145 TEST_F(CloneInstruction, Exact) {
146 V = new Argument(Type::getInt32Ty(context));
147
148 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
149 EXPECT_FALSE(this->clone(SDiv)->isExact());
150
151 SDiv->setIsExact(true);
152 EXPECT_TRUE(this->clone(SDiv)->isExact());
153 }
154
TEST_F(CloneInstruction,Attributes)155 TEST_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());
177
178 delete F1;
179 delete F2;
180 }
181
TEST_F(CloneInstruction,CallingConvention)182 TEST_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
205 class CloneFunc : public ::testing::Test {
206 protected:
SetUp()207 void SetUp() override {
208 SetupModule();
209 CreateOldFunc();
210 CreateNewFunc();
211 SetupFinder();
212 }
213
TearDown()214 void TearDown() override { delete Finder; }
215
SetupModule()216 void SetupModule() {
217 M = new Module("", C);
218 }
219
CreateOldFunc()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
CreateOldFunctionBodyAndDI()226 void CreateOldFunctionBodyAndDI() {
227 DIBuilder DBuilder(*M);
228 IRBuilder<> IBuilder(C);
229
230 // Function DI
231 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
232 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
233 DISubroutineType *FuncType =
234 DBuilder.createSubroutineType(ParamTypes);
235 auto *CU =
236 DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
237 "/file/dir", "CloneFunc", false, "", 0);
238
239 auto *Subprogram = DBuilder.createFunction(
240 CU, "f", "f", File, 4, FuncType, true, true, 3, 0, false);
241 OldFunc->setSubprogram(Subprogram);
242
243 // Function body
244 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
245 IBuilder.SetInsertPoint(Entry);
246 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
247 IBuilder.SetCurrentDebugLocation(Loc);
248 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
249 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
250 Value* AllocaContent = IBuilder.getInt32(1);
251 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
252 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
253 Instruction* Terminator = IBuilder.CreateRetVoid();
254
255 // Create a local variable around the alloca
256 auto *IntType =
257 DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed);
258 auto *E = DBuilder.createExpression();
259 auto *Variable =
260 DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true);
261 auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
262 DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
263 DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
264 Terminator);
265 // Finalize the debug info
266 DBuilder.finalize();
267
268
269 // Create another, empty, compile unit
270 DIBuilder DBuilder2(*M);
271 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
272 "extra.c", "/file/dir", "CloneFunc", false, "", 0);
273 DBuilder2.finalize();
274 }
275
CreateNewFunc()276 void CreateNewFunc() {
277 ValueToValueMapTy VMap;
278 NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
279 M->getFunctionList().push_back(NewFunc);
280 }
281
SetupFinder()282 void SetupFinder() {
283 Finder = new DebugInfoFinder();
284 Finder->processModule(*M);
285 }
286
287 LLVMContext C;
288 Function* OldFunc;
289 Function* NewFunc;
290 Module* M;
291 DebugInfoFinder* Finder;
292 };
293
294 // Test that a new, distinct function was created.
TEST_F(CloneFunc,NewFunctionCreated)295 TEST_F(CloneFunc, NewFunctionCreated) {
296 EXPECT_NE(OldFunc, NewFunc);
297 }
298
299 // Test that a new subprogram entry was added and is pointing to the new
300 // function, while the original subprogram still points to the old one.
TEST_F(CloneFunc,Subprogram)301 TEST_F(CloneFunc, Subprogram) {
302 EXPECT_FALSE(verifyModule(*M));
303
304 unsigned SubprogramCount = Finder->subprogram_count();
305 EXPECT_EQ(2U, SubprogramCount);
306
307 auto Iter = Finder->subprograms().begin();
308 auto *Sub1 = cast<DISubprogram>(*Iter);
309 Iter++;
310 auto *Sub2 = cast<DISubprogram>(*Iter);
311
312 EXPECT_TRUE(
313 (Sub1 == OldFunc->getSubprogram() && Sub2 == NewFunc->getSubprogram()) ||
314 (Sub1 == NewFunc->getSubprogram() && Sub2 == OldFunc->getSubprogram()));
315 }
316
317 // Test that the new subprogram entry was not added to the CU which doesn't
318 // contain the old subprogram entry.
TEST_F(CloneFunc,SubprogramInRightCU)319 TEST_F(CloneFunc, SubprogramInRightCU) {
320 EXPECT_FALSE(verifyModule(*M));
321
322 EXPECT_EQ(2U, Finder->compile_unit_count());
323
324 auto Iter = Finder->compile_units().begin();
325 auto *CU1 = cast<DICompileUnit>(*Iter);
326 Iter++;
327 auto *CU2 = cast<DICompileUnit>(*Iter);
328 EXPECT_TRUE(CU1->getSubprograms().size() == 0 ||
329 CU2->getSubprograms().size() == 0);
330 }
331
332 // Test that instructions in the old function still belong to it in the
333 // metadata, while instruction in the new function belong to the new one.
TEST_F(CloneFunc,InstructionOwnership)334 TEST_F(CloneFunc, InstructionOwnership) {
335 EXPECT_FALSE(verifyModule(*M));
336
337 inst_iterator OldIter = inst_begin(OldFunc);
338 inst_iterator OldEnd = inst_end(OldFunc);
339 inst_iterator NewIter = inst_begin(NewFunc);
340 inst_iterator NewEnd = inst_end(NewFunc);
341 while (OldIter != OldEnd && NewIter != NewEnd) {
342 Instruction& OldI = *OldIter;
343 Instruction& NewI = *NewIter;
344 EXPECT_NE(&OldI, &NewI);
345
346 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
347 if (OldI.hasMetadata()) {
348 const DebugLoc& OldDL = OldI.getDebugLoc();
349 const DebugLoc& NewDL = NewI.getDebugLoc();
350
351 // Verify that the debug location data is the same
352 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
353 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
354
355 // But that they belong to different functions
356 auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
357 auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
358 EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
359 EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
360 }
361
362 ++OldIter;
363 ++NewIter;
364 }
365 EXPECT_EQ(OldEnd, OldIter);
366 EXPECT_EQ(NewEnd, NewIter);
367 }
368
369 // Test that the arguments for debug intrinsics in the new function were
370 // properly cloned
TEST_F(CloneFunc,DebugIntrinsics)371 TEST_F(CloneFunc, DebugIntrinsics) {
372 EXPECT_FALSE(verifyModule(*M));
373
374 inst_iterator OldIter = inst_begin(OldFunc);
375 inst_iterator OldEnd = inst_end(OldFunc);
376 inst_iterator NewIter = inst_begin(NewFunc);
377 inst_iterator NewEnd = inst_end(NewFunc);
378 while (OldIter != OldEnd && NewIter != NewEnd) {
379 Instruction& OldI = *OldIter;
380 Instruction& NewI = *NewIter;
381 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
382 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
383 EXPECT_TRUE(NewIntrin);
384
385 // Old address must belong to the old function
386 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
387 getParent()->getParent());
388 // New address must belong to the new function
389 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
390 getParent()->getParent());
391
392 // Old variable must belong to the old function
393 EXPECT_EQ(OldFunc->getSubprogram(),
394 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
395 // New variable must belong to the New function
396 EXPECT_EQ(NewFunc->getSubprogram(),
397 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
398 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
399 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
400 EXPECT_TRUE(NewIntrin);
401
402 // Old variable must belong to the old function
403 EXPECT_EQ(OldFunc->getSubprogram(),
404 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
405 // New variable must belong to the New function
406 EXPECT_EQ(NewFunc->getSubprogram(),
407 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
408 }
409
410 ++OldIter;
411 ++NewIter;
412 }
413 }
414
415 class CloneModule : public ::testing::Test {
416 protected:
SetUp()417 void SetUp() override {
418 SetupModule();
419 CreateOldModule();
420 CreateNewModule();
421 }
422
SetupModule()423 void SetupModule() { OldM = new Module("", C); }
424
CreateOldModule()425 void CreateOldModule() {
426 IRBuilder<> IBuilder(C);
427
428 auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
429 auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
430 "persfn", OldM);
431 auto *F =
432 Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
433 F->setPersonalityFn(PersFn);
434 auto *Entry = BasicBlock::Create(C, "", F);
435 IBuilder.SetInsertPoint(Entry);
436 IBuilder.CreateRetVoid();
437 }
438
CreateNewModule()439 void CreateNewModule() { NewM = llvm::CloneModule(OldM).release(); }
440
441 LLVMContext C;
442 Module *OldM;
443 Module *NewM;
444 };
445
TEST_F(CloneModule,Verify)446 TEST_F(CloneModule, Verify) {
447 EXPECT_FALSE(verifyModule(*NewM));
448 }
449
450 }
451