Home | History | Annotate | Download | only in Utils
      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/STLExtras.h"
     12 #include "llvm/ADT/SmallPtrSet.h"
     13 #include "llvm/IR/Argument.h"
     14 #include "llvm/IR/Constant.h"
     15 #include "llvm/IR/DIBuilder.h"
     16 #include "llvm/IR/DebugInfo.h"
     17 #include "llvm/IR/Function.h"
     18 #include "llvm/IR/IRBuilder.h"
     19 #include "llvm/IR/InstIterator.h"
     20 #include "llvm/IR/Instructions.h"
     21 #include "llvm/IR/IntrinsicInst.h"
     22 #include "llvm/IR/LLVMContext.h"
     23 #include "llvm/IR/Module.h"
     24 #include "llvm/IR/Verifier.h"
     25 #include "gtest/gtest.h"
     26 
     27 using namespace llvm;
     28 
     29 namespace {
     30 
     31 class CloneInstruction : public ::testing::Test {
     32 protected:
     33   void SetUp() override { V = nullptr; }
     34 
     35   template <typename T>
     36   T *clone(T *V1) {
     37     Value *V2 = V1->clone();
     38     Orig.insert(V1);
     39     Clones.insert(V2);
     40     return cast<T>(V2);
     41   }
     42 
     43   void eraseClones() {
     44     DeleteContainerPointers(Clones);
     45   }
     46 
     47   void TearDown() override {
     48     eraseClones();
     49     DeleteContainerPointers(Orig);
     50     delete V;
     51   }
     52 
     53   SmallPtrSet<Value *, 4> Orig;   // Erase on exit
     54   SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
     55 
     56   LLVMContext context;
     57   Value *V;
     58 };
     59 
     60 TEST_F(CloneInstruction, OverflowBits) {
     61   V = new Argument(Type::getInt32Ty(context));
     62 
     63   BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
     64   BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
     65   BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
     66 
     67   BinaryOperator *AddClone = this->clone(Add);
     68   BinaryOperator *SubClone = this->clone(Sub);
     69   BinaryOperator *MulClone = this->clone(Mul);
     70 
     71   EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
     72   EXPECT_FALSE(AddClone->hasNoSignedWrap());
     73   EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
     74   EXPECT_FALSE(SubClone->hasNoSignedWrap());
     75   EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
     76   EXPECT_FALSE(MulClone->hasNoSignedWrap());
     77 
     78   eraseClones();
     79 
     80   Add->setHasNoUnsignedWrap();
     81   Sub->setHasNoUnsignedWrap();
     82   Mul->setHasNoUnsignedWrap();
     83 
     84   AddClone = this->clone(Add);
     85   SubClone = this->clone(Sub);
     86   MulClone = this->clone(Mul);
     87 
     88   EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
     89   EXPECT_FALSE(AddClone->hasNoSignedWrap());
     90   EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
     91   EXPECT_FALSE(SubClone->hasNoSignedWrap());
     92   EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
     93   EXPECT_FALSE(MulClone->hasNoSignedWrap());
     94 
     95   eraseClones();
     96 
     97   Add->setHasNoSignedWrap();
     98   Sub->setHasNoSignedWrap();
     99   Mul->setHasNoSignedWrap();
    100 
    101   AddClone = this->clone(Add);
    102   SubClone = this->clone(Sub);
    103   MulClone = this->clone(Mul);
    104 
    105   EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
    106   EXPECT_TRUE(AddClone->hasNoSignedWrap());
    107   EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
    108   EXPECT_TRUE(SubClone->hasNoSignedWrap());
    109   EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
    110   EXPECT_TRUE(MulClone->hasNoSignedWrap());
    111 
    112   eraseClones();
    113 
    114   Add->setHasNoUnsignedWrap(false);
    115   Sub->setHasNoUnsignedWrap(false);
    116   Mul->setHasNoUnsignedWrap(false);
    117 
    118   AddClone = this->clone(Add);
    119   SubClone = this->clone(Sub);
    120   MulClone = this->clone(Mul);
    121 
    122   EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
    123   EXPECT_TRUE(AddClone->hasNoSignedWrap());
    124   EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
    125   EXPECT_TRUE(SubClone->hasNoSignedWrap());
    126   EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
    127   EXPECT_TRUE(MulClone->hasNoSignedWrap());
    128 }
    129 
    130 TEST_F(CloneInstruction, Inbounds) {
    131   V = new Argument(Type::getInt32PtrTy(context));
    132 
    133   Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
    134   std::vector<Value *> ops;
    135   ops.push_back(Z);
    136   GetElementPtrInst *GEP =
    137       GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
    138   EXPECT_FALSE(this->clone(GEP)->isInBounds());
    139 
    140   GEP->setIsInBounds();
    141   EXPECT_TRUE(this->clone(GEP)->isInBounds());
    142 }
    143 
    144 TEST_F(CloneInstruction, Exact) {
    145   V = new Argument(Type::getInt32Ty(context));
    146 
    147   BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
    148   EXPECT_FALSE(this->clone(SDiv)->isExact());
    149 
    150   SDiv->setIsExact(true);
    151   EXPECT_TRUE(this->clone(SDiv)->isExact());
    152 }
    153 
    154 TEST_F(CloneInstruction, Attributes) {
    155   Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
    156   FunctionType *FT1 =  FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
    157 
    158   Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
    159   BasicBlock *BB = BasicBlock::Create(context, "", F1);
    160   IRBuilder<> Builder(BB);
    161   Builder.CreateRetVoid();
    162 
    163   Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
    164 
    165   Attribute::AttrKind AK[] = { Attribute::NoCapture };
    166   AttributeSet AS = AttributeSet::get(context, 0, AK);
    167   Argument *A = &*F1->arg_begin();
    168   A->addAttr(AS);
    169 
    170   SmallVector<ReturnInst*, 4> Returns;
    171   ValueToValueMapTy VMap;
    172   VMap[A] = UndefValue::get(A->getType());
    173 
    174   CloneFunctionInto(F2, F1, VMap, false, Returns);
    175   EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
    176 
    177   delete F1;
    178   delete F2;
    179 }
    180 
    181 TEST_F(CloneInstruction, CallingConvention) {
    182   Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
    183   FunctionType *FT1 =  FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
    184 
    185   Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
    186   F1->setCallingConv(CallingConv::Cold);
    187   BasicBlock *BB = BasicBlock::Create(context, "", F1);
    188   IRBuilder<> Builder(BB);
    189   Builder.CreateRetVoid();
    190 
    191   Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
    192 
    193   SmallVector<ReturnInst*, 4> Returns;
    194   ValueToValueMapTy VMap;
    195   VMap[&*F1->arg_begin()] = &*F2->arg_begin();
    196 
    197   CloneFunctionInto(F2, F1, VMap, false, Returns);
    198   EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
    199 
    200   delete F1;
    201   delete F2;
    202 }
    203 
    204 class CloneFunc : public ::testing::Test {
    205 protected:
    206   void SetUp() override {
    207     SetupModule();
    208     CreateOldFunc();
    209     CreateNewFunc();
    210     SetupFinder();
    211   }
    212 
    213   void TearDown() override { delete Finder; }
    214 
    215   void SetupModule() {
    216     M = new Module("", C);
    217   }
    218 
    219   void CreateOldFunc() {
    220     FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
    221     OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
    222     CreateOldFunctionBodyAndDI();
    223   }
    224 
    225   void CreateOldFunctionBodyAndDI() {
    226     DIBuilder DBuilder(*M);
    227     IRBuilder<> IBuilder(C);
    228 
    229     // Function DI
    230     auto *File = DBuilder.createFile("filename.c", "/file/dir/");
    231     DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
    232     DISubroutineType *FuncType =
    233         DBuilder.createSubroutineType(ParamTypes);
    234     auto *CU =
    235         DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
    236                                    "/file/dir", "CloneFunc", false, "", 0);
    237 
    238     auto *Subprogram = DBuilder.createFunction(
    239         CU, "f", "f", File, 4, FuncType, true, true, 3, 0, false);
    240     OldFunc->setSubprogram(Subprogram);
    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 =
    259         DBuilder.createAutoVariable(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, nullptr);
    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   EXPECT_FALSE(verifyModule(*M));
    301 
    302   unsigned SubprogramCount = Finder->subprogram_count();
    303   EXPECT_EQ(1U, SubprogramCount);
    304 
    305   auto Iter = Finder->subprograms().begin();
    306   auto *Sub = cast<DISubprogram>(*Iter);
    307 
    308   EXPECT_TRUE(Sub == OldFunc->getSubprogram());
    309   EXPECT_TRUE(Sub == NewFunc->getSubprogram());
    310 }
    311 
    312 // Test that instructions in the old function still belong to it in the
    313 // metadata, while instruction in the new function belong to the new one.
    314 TEST_F(CloneFunc, InstructionOwnership) {
    315   EXPECT_FALSE(verifyModule(*M));
    316 
    317   inst_iterator OldIter = inst_begin(OldFunc);
    318   inst_iterator OldEnd = inst_end(OldFunc);
    319   inst_iterator NewIter = inst_begin(NewFunc);
    320   inst_iterator NewEnd = inst_end(NewFunc);
    321   while (OldIter != OldEnd && NewIter != NewEnd) {
    322     Instruction& OldI = *OldIter;
    323     Instruction& NewI = *NewIter;
    324     EXPECT_NE(&OldI, &NewI);
    325 
    326     EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
    327     if (OldI.hasMetadata()) {
    328       const DebugLoc& OldDL = OldI.getDebugLoc();
    329       const DebugLoc& NewDL = NewI.getDebugLoc();
    330 
    331       // Verify that the debug location data is the same
    332       EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
    333       EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
    334 
    335       // But that they belong to different functions
    336       auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
    337       auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
    338       EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
    339       EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
    340     }
    341 
    342     ++OldIter;
    343     ++NewIter;
    344   }
    345   EXPECT_EQ(OldEnd, OldIter);
    346   EXPECT_EQ(NewEnd, NewIter);
    347 }
    348 
    349 // Test that the arguments for debug intrinsics in the new function were
    350 // properly cloned
    351 TEST_F(CloneFunc, DebugIntrinsics) {
    352   EXPECT_FALSE(verifyModule(*M));
    353 
    354   inst_iterator OldIter = inst_begin(OldFunc);
    355   inst_iterator OldEnd = inst_end(OldFunc);
    356   inst_iterator NewIter = inst_begin(NewFunc);
    357   inst_iterator NewEnd = inst_end(NewFunc);
    358   while (OldIter != OldEnd && NewIter != NewEnd) {
    359     Instruction& OldI = *OldIter;
    360     Instruction& NewI = *NewIter;
    361     if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
    362       DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
    363       EXPECT_TRUE(NewIntrin);
    364 
    365       // Old address must belong to the old function
    366       EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
    367                          getParent()->getParent());
    368       // New address must belong to the new function
    369       EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
    370                          getParent()->getParent());
    371 
    372       // Old variable must belong to the old function
    373       EXPECT_EQ(OldFunc->getSubprogram(),
    374                 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
    375       // New variable must belong to the New function
    376       EXPECT_EQ(NewFunc->getSubprogram(),
    377                 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
    378     } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
    379       DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
    380       EXPECT_TRUE(NewIntrin);
    381 
    382       // Old variable must belong to the old function
    383       EXPECT_EQ(OldFunc->getSubprogram(),
    384                 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
    385       // New variable must belong to the New function
    386       EXPECT_EQ(NewFunc->getSubprogram(),
    387                 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
    388     }
    389 
    390     ++OldIter;
    391     ++NewIter;
    392   }
    393 }
    394 
    395 class CloneModule : public ::testing::Test {
    396 protected:
    397   void SetUp() override {
    398     SetupModule();
    399     CreateOldModule();
    400     CreateNewModule();
    401   }
    402 
    403   void SetupModule() { OldM = new Module("", C); }
    404 
    405   void CreateOldModule() {
    406     DIBuilder DBuilder(*OldM);
    407     IRBuilder<> IBuilder(C);
    408 
    409     auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
    410     auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
    411                                     "persfn", OldM);
    412     auto *F =
    413         Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
    414     F->setPersonalityFn(PersFn);
    415 
    416     // Create debug info
    417     auto *File = DBuilder.createFile("filename.c", "/file/dir/");
    418     DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
    419     DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes);
    420     auto *CU =
    421         DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
    422                                    "/file/dir", "CloneModule", false, "", 0);
    423     // Function DI
    424     auto *Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4, DFuncType,
    425                                                true, true, 3, 0, false);
    426     F->setSubprogram(Subprogram);
    427 
    428     auto *Entry = BasicBlock::Create(C, "", F);
    429     IBuilder.SetInsertPoint(Entry);
    430     IBuilder.CreateRetVoid();
    431 
    432     // Finalize the debug info
    433     DBuilder.finalize();
    434   }
    435 
    436   void CreateNewModule() { NewM = llvm::CloneModule(OldM).release(); }
    437 
    438   LLVMContext C;
    439   Module *OldM;
    440   Module *NewM;
    441 };
    442 
    443 TEST_F(CloneModule, Verify) {
    444   EXPECT_FALSE(verifyModule(*NewM));
    445 }
    446 
    447 TEST_F(CloneModule, OldModuleUnchanged) {
    448   DebugInfoFinder Finder;
    449   Finder.processModule(*OldM);
    450   EXPECT_EQ(1U, Finder.subprogram_count());
    451 }
    452 
    453 TEST_F(CloneModule, Subprogram) {
    454   Function *NewF = NewM->getFunction("f");
    455   DISubprogram *SP = NewF->getSubprogram();
    456   EXPECT_TRUE(SP != nullptr);
    457   EXPECT_EQ(SP->getName(), "f");
    458   EXPECT_EQ(SP->getFile()->getFilename(), "filename.c");
    459   EXPECT_EQ(SP->getLine(), (unsigned)4);
    460 }
    461 }
    462