~pali/+junk/llvm-toolchain-3.7

« back to all changes in this revision

Viewing changes to unittests/Transforms/Utils/Cloning.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2015-07-15 17:51:08 UTC
  • Revision ID: package-import@ubuntu.com-20150715175108-l8mynwovkx4zx697
Tags: upstream-3.7~+rc2
ImportĀ upstreamĀ versionĀ 3.7~+rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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:
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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:
 
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
    auto *File = DBuilder.createFile("filename.c", "/file/dir/");
 
232
    DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
 
233
    DISubroutineType *FuncType =
 
234
        DBuilder.createSubroutineType(File, 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, OldFunc);
 
241
 
 
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
 
255
    auto *IntType =
 
256
        DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed);
 
257
    auto *E = DBuilder.createExpression();
 
258
    auto *Variable = DBuilder.createLocalVariable(
 
259
        dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
 
260
    auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
 
261
    DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
 
262
    DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
 
263
                                     Terminator);
 
264
    // 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;
 
277
    NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
 
278
    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.
 
294
TEST_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.
 
300
TEST_F(CloneFunc, Subprogram) {
 
301
  EXPECT_FALSE(verifyModule(*M));
 
302
 
 
303
  unsigned SubprogramCount = Finder->subprogram_count();
 
304
  EXPECT_EQ(2U, SubprogramCount);
 
305
 
 
306
  auto Iter = Finder->subprograms().begin();
 
307
  auto *Sub1 = cast<DISubprogram>(*Iter);
 
308
  Iter++;
 
309
  auto *Sub2 = cast<DISubprogram>(*Iter);
 
310
 
 
311
  EXPECT_TRUE(
 
312
      (Sub1->getFunction() == OldFunc && Sub2->getFunction() == NewFunc) ||
 
313
      (Sub1->getFunction() == NewFunc && Sub2->getFunction() == OldFunc));
 
314
}
 
315
 
 
316
// Test that the new subprogram entry was not added to the CU which doesn't
 
317
// contain the old subprogram entry.
 
318
TEST_F(CloneFunc, SubprogramInRightCU) {
 
319
  EXPECT_FALSE(verifyModule(*M));
 
320
 
 
321
  EXPECT_EQ(2U, Finder->compile_unit_count());
 
322
 
 
323
  auto Iter = Finder->compile_units().begin();
 
324
  auto *CU1 = cast<DICompileUnit>(*Iter);
 
325
  Iter++;
 
326
  auto *CU2 = cast<DICompileUnit>(*Iter);
 
327
  EXPECT_TRUE(CU1->getSubprograms().size() == 0 ||
 
328
              CU2->getSubprograms().size() == 0);
 
329
}
 
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.
 
333
TEST_F(CloneFunc, InstructionOwnership) {
 
334
  EXPECT_FALSE(verifyModule(*M));
 
335
 
 
336
  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());
 
353
 
 
354
      // But that they belong to different functions
 
355
      auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
 
356
      auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
 
357
      EXPECT_EQ(OldFunc, OldSubprogram->getFunction());
 
358
      EXPECT_EQ(NewFunc, NewSubprogram->getFunction());
 
359
    }
 
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
 
370
TEST_F(CloneFunc, DebugIntrinsics) {
 
371
  EXPECT_FALSE(verifyModule(*M));
 
372
 
 
373
  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
 
392
      EXPECT_EQ(OldFunc,
 
393
                cast<DISubprogram>(OldIntrin->getVariable()->getScope())
 
394
                    ->getFunction());
 
395
      // New variable must belong to the New function
 
396
      EXPECT_EQ(NewFunc,
 
397
                cast<DISubprogram>(NewIntrin->getVariable()->getScope())
 
398
                    ->getFunction());
 
399
    } 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
 
404
      EXPECT_EQ(OldFunc,
 
405
                cast<DISubprogram>(OldIntrin->getVariable()->getScope())
 
406
                    ->getFunction());
 
407
      // New variable must belong to the New function
 
408
      EXPECT_EQ(NewFunc,
 
409
                cast<DISubprogram>(NewIntrin->getVariable()->getScope())
 
410
                    ->getFunction());
 
411
    }
 
412
 
 
413
    ++OldIter;
 
414
    ++NewIter;
 
415
  }
 
416
}
 
417
 
 
418
class CloneModule : public ::testing::Test {
 
419
protected:
 
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
 
 
449
TEST_F(CloneModule, Verify) {
 
450
  EXPECT_FALSE(verifyModule(*NewM));
 
451
}
 
452
 
 
453
}