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 28 using namespace llvm; 29 30 namespace { 31 32 class CloneInstruction : public ::testing::Test { 33 protected: 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 63 TEST_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 133 TEST_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 146 TEST_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 156 TEST_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 183 TEST_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 206 class CloneFunc : public ::testing::Test { 207 protected: 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. 292 TEST_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. 298 TEST_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. 315 TEST_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. 330 TEST_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 367 TEST_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