c7799795d9be94a1f56649853c402c528b8a5cc9
[oota-llvm.git] / unittests / Transforms / Utils / Cloning.cpp
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/DebugInfo.h"
17 #include "llvm/IR/DIBuilder.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/IRBuilder.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "gtest/gtest.h"
27
28 using namespace llvm;
29
30 namespace {
31
32 class CloneInstruction : public ::testing::Test {
33 protected:
34   virtual void SetUp() {
35     V = nullptr;
36   }
37
38   template <typename T>
39   T *clone(T *V1) {
40     Value *V2 = V1->clone();
41     Orig.insert(V1);
42     Clones.insert(V2);
43     return cast<T>(V2);
44   }
45
46   void eraseClones() {
47     DeleteContainerPointers(Clones);
48   }
49
50   virtual void TearDown() {
51     eraseClones();
52     DeleteContainerPointers(Orig);
53     delete V;
54   }
55
56   SmallPtrSet<Value *, 4> Orig;   // Erase on exit
57   SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
58
59   LLVMContext context;
60   Value *V;
61 };
62
63 TEST_F(CloneInstruction, OverflowBits) {
64   V = new Argument(Type::getInt32Ty(context));
65
66   BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
67   BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
68   BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
69
70   BinaryOperator *AddClone = this->clone(Add);
71   BinaryOperator *SubClone = this->clone(Sub);
72   BinaryOperator *MulClone = this->clone(Mul);
73
74   EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
75   EXPECT_FALSE(AddClone->hasNoSignedWrap());
76   EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
77   EXPECT_FALSE(SubClone->hasNoSignedWrap());
78   EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
79   EXPECT_FALSE(MulClone->hasNoSignedWrap());
80
81   eraseClones();
82
83   Add->setHasNoUnsignedWrap();
84   Sub->setHasNoUnsignedWrap();
85   Mul->setHasNoUnsignedWrap();
86
87   AddClone = this->clone(Add);
88   SubClone = this->clone(Sub);
89   MulClone = this->clone(Mul);
90
91   EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
92   EXPECT_FALSE(AddClone->hasNoSignedWrap());
93   EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
94   EXPECT_FALSE(SubClone->hasNoSignedWrap());
95   EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
96   EXPECT_FALSE(MulClone->hasNoSignedWrap());
97
98   eraseClones();
99
100   Add->setHasNoSignedWrap();
101   Sub->setHasNoSignedWrap();
102   Mul->setHasNoSignedWrap();
103
104   AddClone = this->clone(Add);
105   SubClone = this->clone(Sub);
106   MulClone = this->clone(Mul);
107
108   EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
109   EXPECT_TRUE(AddClone->hasNoSignedWrap());
110   EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
111   EXPECT_TRUE(SubClone->hasNoSignedWrap());
112   EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
113   EXPECT_TRUE(MulClone->hasNoSignedWrap());
114
115   eraseClones();
116
117   Add->setHasNoUnsignedWrap(false);
118   Sub->setHasNoUnsignedWrap(false);
119   Mul->setHasNoUnsignedWrap(false);
120
121   AddClone = this->clone(Add);
122   SubClone = this->clone(Sub);
123   MulClone = this->clone(Mul);
124
125   EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
126   EXPECT_TRUE(AddClone->hasNoSignedWrap());
127   EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
128   EXPECT_TRUE(SubClone->hasNoSignedWrap());
129   EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
130   EXPECT_TRUE(MulClone->hasNoSignedWrap());
131 }
132
133 TEST_F(CloneInstruction, Inbounds) {
134   V = new Argument(Type::getInt32PtrTy(context));
135
136   Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
137   std::vector<Value *> ops;
138   ops.push_back(Z);
139   GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops);
140   EXPECT_FALSE(this->clone(GEP)->isInBounds());
141
142   GEP->setIsInBounds();
143   EXPECT_TRUE(this->clone(GEP)->isInBounds());
144 }
145
146 TEST_F(CloneInstruction, Exact) {
147   V = new Argument(Type::getInt32Ty(context));
148
149   BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
150   EXPECT_FALSE(this->clone(SDiv)->isExact());
151
152   SDiv->setIsExact(true);
153   EXPECT_TRUE(this->clone(SDiv)->isExact());
154 }
155
156 TEST_F(CloneInstruction, Attributes) {
157   Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
158   FunctionType *FT1 =  FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
159
160   Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
161   BasicBlock *BB = BasicBlock::Create(context, "", F1);
162   IRBuilder<> Builder(BB);
163   Builder.CreateRetVoid();
164
165   Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
166
167   Attribute::AttrKind AK[] = { Attribute::NoCapture };
168   AttributeSet AS = AttributeSet::get(context, 0, AK);
169   Argument *A = F1->arg_begin();
170   A->addAttr(AS);
171
172   SmallVector<ReturnInst*, 4> Returns;
173   ValueToValueMapTy VMap;
174   VMap[A] = UndefValue::get(A->getType());
175
176   CloneFunctionInto(F2, F1, VMap, false, Returns);
177   EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
178
179   delete F1;
180   delete F2;
181 }
182
183 TEST_F(CloneInstruction, CallingConvention) {
184   Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
185   FunctionType *FT1 =  FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
186
187   Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
188   F1->setCallingConv(CallingConv::Cold);
189   BasicBlock *BB = BasicBlock::Create(context, "", F1);
190   IRBuilder<> Builder(BB);
191   Builder.CreateRetVoid();
192
193   Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
194
195   SmallVector<ReturnInst*, 4> Returns;
196   ValueToValueMapTy VMap;
197   VMap[F1->arg_begin()] = F2->arg_begin();
198
199   CloneFunctionInto(F2, F1, VMap, false, Returns);
200   EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
201
202   delete F1;
203   delete F2;
204 }
205
206 class CloneFunc : public ::testing::Test {
207 protected:
208   virtual void SetUp() {
209     SetupModule();
210     CreateOldFunc();
211     CreateNewFunc();
212     SetupFinder();
213   }
214
215   virtual void TearDown() {
216     delete Finder;
217   }
218
219   void SetupModule() {
220     M = new Module("", C);
221   }
222
223   void CreateOldFunc() {
224     FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
225     OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
226     CreateOldFunctionBodyAndDI();
227   }
228
229   void CreateOldFunctionBodyAndDI() {
230     DIBuilder DBuilder(*M);
231     IRBuilder<> IBuilder(C);
232
233     // Function DI
234     DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
235     DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
236     DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
237     DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
238         "filename.c", "/file/dir", "CloneFunc", false, "", 0);
239
240     DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
241         FuncType, true, true, 3, 0, false, OldFunc);
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     DIType IntType = DBuilder.createBasicType("int", 32, 0,
257         dwarf::DW_ATE_signed);
258     DIExpression E = DBuilder.createExpression();
259     DIVariable Variable = DBuilder.createLocalVariable(
260       dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
261     DBuilder.insertDeclare(Alloca, Variable, E, Store);
262     DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, Terminator);
263     // Finalize the debug info
264     DBuilder.finalize();
265
266
267     // Create another, empty, compile unit
268     DIBuilder DBuilder2(*M);
269     DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
270         "extra.c", "/file/dir", "CloneFunc", false, "", 0);
271     DBuilder2.finalize();
272   }
273
274   void CreateNewFunc() {
275     ValueToValueMapTy VMap;
276     NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
277     M->getFunctionList().push_back(NewFunc);
278   }
279
280   void SetupFinder() {
281     Finder = new DebugInfoFinder();
282     Finder->processModule(*M);
283   }
284
285   LLVMContext C;
286   Function* OldFunc;
287   Function* NewFunc;
288   Module* M;
289   DebugInfoFinder* Finder;
290 };
291
292 // Test that a new, distinct function was created.
293 TEST_F(CloneFunc, NewFunctionCreated) {
294   EXPECT_NE(OldFunc, NewFunc);
295 }
296
297 // Test that a new subprogram entry was added and is pointing to the new
298 // function, while the original subprogram still points to the old one.
299 TEST_F(CloneFunc, Subprogram) {
300   unsigned SubprogramCount = Finder->subprogram_count();
301   EXPECT_EQ(2U, SubprogramCount);
302
303   auto Iter = Finder->subprograms().begin();
304   DISubprogram Sub1(*Iter);
305   EXPECT_TRUE(Sub1.Verify());
306   Iter++;
307   DISubprogram Sub2(*Iter);
308   EXPECT_TRUE(Sub2.Verify());
309
310   EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
311            || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
312 }
313
314 // Test that the new subprogram entry was not added to the CU which doesn't
315 // contain the old subprogram entry.
316 TEST_F(CloneFunc, SubprogramInRightCU) {
317   EXPECT_EQ(2U, Finder->compile_unit_count());
318
319   auto Iter = Finder->compile_units().begin();
320   DICompileUnit CU1(*Iter);
321   EXPECT_TRUE(CU1.Verify());
322   Iter++;
323   DICompileUnit CU2(*Iter);
324   EXPECT_TRUE(CU2.Verify());
325   EXPECT_TRUE(CU1.getSubprograms().getNumElements() == 0
326            || CU2.getSubprograms().getNumElements() == 0);
327 }
328
329 // Test that instructions in the old function still belong to it in the
330 // metadata, while instruction in the new function belong to the new one.
331 TEST_F(CloneFunc, InstructionOwnership) {
332   inst_iterator OldIter = inst_begin(OldFunc);
333   inst_iterator OldEnd = inst_end(OldFunc);
334   inst_iterator NewIter = inst_begin(NewFunc);
335   inst_iterator NewEnd = inst_end(NewFunc);
336   while (OldIter != OldEnd && NewIter != NewEnd) {
337     Instruction& OldI = *OldIter;
338     Instruction& NewI = *NewIter;
339     EXPECT_NE(&OldI, &NewI);
340
341     EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
342     if (OldI.hasMetadata()) {
343       const DebugLoc& OldDL = OldI.getDebugLoc();
344       const DebugLoc& NewDL = NewI.getDebugLoc();
345
346       // Verify that the debug location data is the same
347       EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
348       EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
349       
350       // But that they belong to different functions
351       DISubprogram OldSubprogram(OldDL.getScope(C));
352       DISubprogram NewSubprogram(NewDL.getScope(C));
353       EXPECT_TRUE(OldSubprogram.Verify());
354       EXPECT_TRUE(NewSubprogram.Verify());
355       EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
356       EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
357     }
358
359     ++OldIter;
360     ++NewIter;
361   }
362   EXPECT_EQ(OldEnd, OldIter);
363   EXPECT_EQ(NewEnd, NewIter);
364 }
365
366 // Test that the arguments for debug intrinsics in the new function were
367 // properly cloned
368 TEST_F(CloneFunc, DebugIntrinsics) {
369   inst_iterator OldIter = inst_begin(OldFunc);
370   inst_iterator OldEnd = inst_end(OldFunc);
371   inst_iterator NewIter = inst_begin(NewFunc);
372   inst_iterator NewEnd = inst_end(NewFunc);
373   while (OldIter != OldEnd && NewIter != NewEnd) {
374     Instruction& OldI = *OldIter;
375     Instruction& NewI = *NewIter;
376     if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
377       DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
378       EXPECT_TRUE(NewIntrin);
379
380       // Old address must belong to the old function
381       EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
382                          getParent()->getParent());
383       // New address must belong to the new function
384       EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
385                          getParent()->getParent());
386
387       // Old variable must belong to the old function
388       EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
389                          .getContext()).getFunction());
390       // New variable must belong to the New function
391       EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
392                          .getContext()).getFunction());
393     } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
394       DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
395       EXPECT_TRUE(NewIntrin);
396
397       // Old variable must belong to the old function
398       EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
399                          .getContext()).getFunction());
400       // New variable must belong to the New function
401       EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
402                          .getContext()).getFunction());
403     }
404
405     ++OldIter;
406     ++NewIter;
407   }
408 }
409
410 }