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
28using namespace llvm;
29
30namespace {
31
32class CloneInstruction : public ::testing::Test {
33protected:
34  void SetUp() override { V = nullptr; }
35
36  template <typename T>
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
44  void eraseClones() {
45    DeleteContainerPointers(Clones);
46  }
47
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
61TEST_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
131TEST_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
145TEST_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
155TEST_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
182TEST_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
205class CloneFunc : public ::testing::Test {
206protected:
207  void SetUp() override {
208    SetupModule();
209    CreateOldFunc();
210    CreateNewFunc();
211    SetupFinder();
212  }
213
214  void TearDown() override { delete Finder; }
215
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
231    DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
232    DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
233    MDSubroutineType *FuncType =
234        DBuilder.createSubroutineType(File, ParamTypes);
235    DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
236        "filename.c", "/file/dir", "CloneFunc", false, "", 0);
237
238    DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
239        FuncType, true, true, 3, 0, false, OldFunc);
240
241    // Function body
242    BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
243    IBuilder.SetInsertPoint(Entry);
244    DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
245    IBuilder.SetCurrentDebugLocation(Loc);
246    AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
247    IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
248    Value* AllocaContent = IBuilder.getInt32(1);
249    Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
250    IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
251    Instruction* Terminator = IBuilder.CreateRetVoid();
252
253    // Create a local variable around the alloca
254    DIType IntType = DBuilder.createBasicType("int", 32, 0,
255        dwarf::DW_ATE_signed);
256    DIExpression E = DBuilder.createExpression();
257    DIVariable Variable = DBuilder.createLocalVariable(
258      dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
259    auto *DL = MDLocation::get(Subprogram->getContext(), 5, 0, Subprogram);
260    DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
261    DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
262                                     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.
293TEST_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.
299TEST_F(CloneFunc, Subprogram) {
300  EXPECT_FALSE(verifyModule(*M));
301
302  unsigned SubprogramCount = Finder->subprogram_count();
303  EXPECT_EQ(2U, SubprogramCount);
304
305  auto Iter = Finder->subprograms().begin();
306  DISubprogram Sub1 = cast<MDSubprogram>(*Iter);
307  Iter++;
308  DISubprogram Sub2 = cast<MDSubprogram>(*Iter);
309
310  EXPECT_TRUE(
311      (Sub1->getFunction() == OldFunc && Sub2->getFunction() == NewFunc) ||
312      (Sub1->getFunction() == NewFunc && Sub2->getFunction() == OldFunc));
313}
314
315// Test that the new subprogram entry was not added to the CU which doesn't
316// contain the old subprogram entry.
317TEST_F(CloneFunc, SubprogramInRightCU) {
318  EXPECT_FALSE(verifyModule(*M));
319
320  EXPECT_EQ(2U, Finder->compile_unit_count());
321
322  auto Iter = Finder->compile_units().begin();
323  DICompileUnit CU1 = cast<MDCompileUnit>(*Iter);
324  Iter++;
325  DICompileUnit CU2 = cast<MDCompileUnit>(*Iter);
326  EXPECT_TRUE(CU1->getSubprograms().size() == 0 ||
327              CU2->getSubprograms().size() == 0);
328}
329
330// Test that instructions in the old function still belong to it in the
331// metadata, while instruction in the new function belong to the new one.
332TEST_F(CloneFunc, InstructionOwnership) {
333  EXPECT_FALSE(verifyModule(*M));
334
335  inst_iterator OldIter = inst_begin(OldFunc);
336  inst_iterator OldEnd = inst_end(OldFunc);
337  inst_iterator NewIter = inst_begin(NewFunc);
338  inst_iterator NewEnd = inst_end(NewFunc);
339  while (OldIter != OldEnd && NewIter != NewEnd) {
340    Instruction& OldI = *OldIter;
341    Instruction& NewI = *NewIter;
342    EXPECT_NE(&OldI, &NewI);
343
344    EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
345    if (OldI.hasMetadata()) {
346      const DebugLoc& OldDL = OldI.getDebugLoc();
347      const DebugLoc& NewDL = NewI.getDebugLoc();
348
349      // Verify that the debug location data is the same
350      EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
351      EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
352
353      // But that they belong to different functions
354      auto *OldSubprogram = cast<MDSubprogram>(OldDL.getScope());
355      auto *NewSubprogram = cast<MDSubprogram>(NewDL.getScope());
356      EXPECT_EQ(OldFunc, OldSubprogram->getFunction());
357      EXPECT_EQ(NewFunc, NewSubprogram->getFunction());
358    }
359
360    ++OldIter;
361    ++NewIter;
362  }
363  EXPECT_EQ(OldEnd, OldIter);
364  EXPECT_EQ(NewEnd, NewIter);
365}
366
367// Test that the arguments for debug intrinsics in the new function were
368// properly cloned
369TEST_F(CloneFunc, DebugIntrinsics) {
370  EXPECT_FALSE(verifyModule(*M));
371
372  inst_iterator OldIter = inst_begin(OldFunc);
373  inst_iterator OldEnd = inst_end(OldFunc);
374  inst_iterator NewIter = inst_begin(NewFunc);
375  inst_iterator NewEnd = inst_end(NewFunc);
376  while (OldIter != OldEnd && NewIter != NewEnd) {
377    Instruction& OldI = *OldIter;
378    Instruction& NewI = *NewIter;
379    if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
380      DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
381      EXPECT_TRUE(NewIntrin);
382
383      // Old address must belong to the old function
384      EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
385                         getParent()->getParent());
386      // New address must belong to the new function
387      EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
388                         getParent()->getParent());
389
390      // Old variable must belong to the old function
391      EXPECT_EQ(OldFunc,
392                cast<MDSubprogram>(OldIntrin->getVariable()->getScope())
393                    ->getFunction());
394      // New variable must belong to the New function
395      EXPECT_EQ(NewFunc,
396                cast<MDSubprogram>(NewIntrin->getVariable()->getScope())
397                    ->getFunction());
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,
404                cast<MDSubprogram>(OldIntrin->getVariable()->getScope())
405                    ->getFunction());
406      // New variable must belong to the New function
407      EXPECT_EQ(NewFunc,
408                cast<MDSubprogram>(NewIntrin->getVariable()->getScope())
409                    ->getFunction());
410    }
411
412    ++OldIter;
413    ++NewIter;
414  }
415}
416
417}
418