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
28using namespace llvm;
29
30namespace {
31
32class CloneInstruction : public ::testing::Test {
33protected:
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
63TEST_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
133TEST_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
146TEST_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
156TEST_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
183TEST_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
206class CloneFunc : public ::testing::Test {
207protected:
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    DIArray ParamTypes = DBuilder.getOrCreateArray(ArrayRef<Value*>());
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    DIVariable Variable = DBuilder.createLocalVariable(
259      dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
260    DBuilder.insertDeclare(Alloca, Variable, Store);
261    DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, Terminator);
262    // Finalize the debug info
263    DBuilder.finalize();
264
265
266    // Create another, empty, compile unit
267    DIBuilder DBuilder2(*M);
268    DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
269        "extra.c", "/file/dir", "CloneFunc", false, "", 0);
270    DBuilder2.finalize();
271  }
272
273  void CreateNewFunc() {
274    ValueToValueMapTy VMap;
275    NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
276    M->getFunctionList().push_back(NewFunc);
277  }
278
279  void SetupFinder() {
280    Finder = new DebugInfoFinder();
281    Finder->processModule(*M);
282  }
283
284  LLVMContext C;
285  Function* OldFunc;
286  Function* NewFunc;
287  Module* M;
288  DebugInfoFinder* Finder;
289};
290
291// Test that a new, distinct function was created.
292TEST_F(CloneFunc, NewFunctionCreated) {
293  EXPECT_NE(OldFunc, NewFunc);
294}
295
296// Test that a new subprogram entry was added and is pointing to the new
297// function, while the original subprogram still points to the old one.
298TEST_F(CloneFunc, Subprogram) {
299  unsigned SubprogramCount = Finder->subprogram_count();
300  EXPECT_EQ(2U, SubprogramCount);
301
302  auto Iter = Finder->subprograms().begin();
303  DISubprogram Sub1(*Iter);
304  EXPECT_TRUE(Sub1.Verify());
305  Iter++;
306  DISubprogram Sub2(*Iter);
307  EXPECT_TRUE(Sub2.Verify());
308
309  EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
310           || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
311}
312
313// Test that the new subprogram entry was not added to the CU which doesn't
314// contain the old subprogram entry.
315TEST_F(CloneFunc, SubprogramInRightCU) {
316  EXPECT_EQ(2U, Finder->compile_unit_count());
317
318  auto Iter = Finder->compile_units().begin();
319  DICompileUnit CU1(*Iter);
320  EXPECT_TRUE(CU1.Verify());
321  Iter++;
322  DICompileUnit CU2(*Iter);
323  EXPECT_TRUE(CU2.Verify());
324  EXPECT_TRUE(CU1.getSubprograms().getNumElements() == 0
325           || CU2.getSubprograms().getNumElements() == 0);
326}
327
328// Test that instructions in the old function still belong to it in the
329// metadata, while instruction in the new function belong to the new one.
330TEST_F(CloneFunc, InstructionOwnership) {
331  inst_iterator OldIter = inst_begin(OldFunc);
332  inst_iterator OldEnd = inst_end(OldFunc);
333  inst_iterator NewIter = inst_begin(NewFunc);
334  inst_iterator NewEnd = inst_end(NewFunc);
335  while (OldIter != OldEnd && NewIter != NewEnd) {
336    Instruction& OldI = *OldIter;
337    Instruction& NewI = *NewIter;
338    EXPECT_NE(&OldI, &NewI);
339
340    EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
341    if (OldI.hasMetadata()) {
342      const DebugLoc& OldDL = OldI.getDebugLoc();
343      const DebugLoc& NewDL = NewI.getDebugLoc();
344
345      // Verify that the debug location data is the same
346      EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
347      EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
348
349      // But that they belong to different functions
350      DISubprogram OldSubprogram(OldDL.getScope(C));
351      DISubprogram NewSubprogram(NewDL.getScope(C));
352      EXPECT_TRUE(OldSubprogram.Verify());
353      EXPECT_TRUE(NewSubprogram.Verify());
354      EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
355      EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
356    }
357
358    ++OldIter;
359    ++NewIter;
360  }
361  EXPECT_EQ(OldEnd, OldIter);
362  EXPECT_EQ(NewEnd, NewIter);
363}
364
365// Test that the arguments for debug intrinsics in the new function were
366// properly cloned
367TEST_F(CloneFunc, DebugIntrinsics) {
368  inst_iterator OldIter = inst_begin(OldFunc);
369  inst_iterator OldEnd = inst_end(OldFunc);
370  inst_iterator NewIter = inst_begin(NewFunc);
371  inst_iterator NewEnd = inst_end(NewFunc);
372  while (OldIter != OldEnd && NewIter != NewEnd) {
373    Instruction& OldI = *OldIter;
374    Instruction& NewI = *NewIter;
375    if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
376      DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
377      EXPECT_TRUE(NewIntrin);
378
379      // Old address must belong to the old function
380      EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
381                         getParent()->getParent());
382      // New address must belong to the new function
383      EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
384                         getParent()->getParent());
385
386      // Old variable must belong to the old function
387      EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
388                         .getContext()).getFunction());
389      // New variable must belong to the New function
390      EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
391                         .getContext()).getFunction());
392    } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
393      DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
394      EXPECT_TRUE(NewIntrin);
395
396      // Old variable must belong to the old function
397      EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
398                         .getContext()).getFunction());
399      // New variable must belong to the New function
400      EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
401                         .getContext()).getFunction());
402    }
403
404    ++OldIter;
405    ++NewIter;
406  }
407}
408
409}
410