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/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     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.
    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(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.
    317 TEST_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.
    332 TEST_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
    369 TEST_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