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 "gtest/gtest.h" 26 27 using namespace llvm; 28 29 namespace { 30 31 class CloneInstruction : public ::testing::Test { 32 protected: 33 virtual void SetUp() { 34 V = nullptr; 35 } 36 37 template <typename T> 38 T *clone(T *V1) { 39 Value *V2 = V1->clone(); 40 Orig.insert(V1); 41 Clones.insert(V2); 42 return cast<T>(V2); 43 } 44 45 void eraseClones() { 46 DeleteContainerPointers(Clones); 47 } 48 49 virtual void TearDown() { 50 eraseClones(); 51 DeleteContainerPointers(Orig); 52 delete V; 53 } 54 55 SmallPtrSet<Value *, 4> Orig; // Erase on exit 56 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones 57 58 LLVMContext context; 59 Value *V; 60 }; 61 62 TEST_F(CloneInstruction, OverflowBits) { 63 V = new Argument(Type::getInt32Ty(context)); 64 65 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V); 66 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); 67 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); 68 69 BinaryOperator *AddClone = this->clone(Add); 70 BinaryOperator *SubClone = this->clone(Sub); 71 BinaryOperator *MulClone = this->clone(Mul); 72 73 EXPECT_FALSE(AddClone->hasNoUnsignedWrap()); 74 EXPECT_FALSE(AddClone->hasNoSignedWrap()); 75 EXPECT_FALSE(SubClone->hasNoUnsignedWrap()); 76 EXPECT_FALSE(SubClone->hasNoSignedWrap()); 77 EXPECT_FALSE(MulClone->hasNoUnsignedWrap()); 78 EXPECT_FALSE(MulClone->hasNoSignedWrap()); 79 80 eraseClones(); 81 82 Add->setHasNoUnsignedWrap(); 83 Sub->setHasNoUnsignedWrap(); 84 Mul->setHasNoUnsignedWrap(); 85 86 AddClone = this->clone(Add); 87 SubClone = this->clone(Sub); 88 MulClone = this->clone(Mul); 89 90 EXPECT_TRUE(AddClone->hasNoUnsignedWrap()); 91 EXPECT_FALSE(AddClone->hasNoSignedWrap()); 92 EXPECT_TRUE(SubClone->hasNoUnsignedWrap()); 93 EXPECT_FALSE(SubClone->hasNoSignedWrap()); 94 EXPECT_TRUE(MulClone->hasNoUnsignedWrap()); 95 EXPECT_FALSE(MulClone->hasNoSignedWrap()); 96 97 eraseClones(); 98 99 Add->setHasNoSignedWrap(); 100 Sub->setHasNoSignedWrap(); 101 Mul->setHasNoSignedWrap(); 102 103 AddClone = this->clone(Add); 104 SubClone = this->clone(Sub); 105 MulClone = this->clone(Mul); 106 107 EXPECT_TRUE(AddClone->hasNoUnsignedWrap()); 108 EXPECT_TRUE(AddClone->hasNoSignedWrap()); 109 EXPECT_TRUE(SubClone->hasNoUnsignedWrap()); 110 EXPECT_TRUE(SubClone->hasNoSignedWrap()); 111 EXPECT_TRUE(MulClone->hasNoUnsignedWrap()); 112 EXPECT_TRUE(MulClone->hasNoSignedWrap()); 113 114 eraseClones(); 115 116 Add->setHasNoUnsignedWrap(false); 117 Sub->setHasNoUnsignedWrap(false); 118 Mul->setHasNoUnsignedWrap(false); 119 120 AddClone = this->clone(Add); 121 SubClone = this->clone(Sub); 122 MulClone = this->clone(Mul); 123 124 EXPECT_FALSE(AddClone->hasNoUnsignedWrap()); 125 EXPECT_TRUE(AddClone->hasNoSignedWrap()); 126 EXPECT_FALSE(SubClone->hasNoUnsignedWrap()); 127 EXPECT_TRUE(SubClone->hasNoSignedWrap()); 128 EXPECT_FALSE(MulClone->hasNoUnsignedWrap()); 129 EXPECT_TRUE(MulClone->hasNoSignedWrap()); 130 } 131 132 TEST_F(CloneInstruction, Inbounds) { 133 V = new Argument(Type::getInt32PtrTy(context)); 134 135 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context)); 136 std::vector<Value *> ops; 137 ops.push_back(Z); 138 GetElementPtrInst *GEP = GetElementPtrInst::Create(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 virtual void SetUp() { 208 SetupModule(); 209 CreateOldFunc(); 210 CreateNewFunc(); 211 SetupFinder(); 212 } 213 214 virtual void TearDown() { 215 delete Finder; 216 } 217 218 void SetupModule() { 219 M = new Module("", C); 220 } 221 222 void CreateOldFunc() { 223 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false); 224 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M); 225 CreateOldFunctionBodyAndDI(); 226 } 227 228 void CreateOldFunctionBodyAndDI() { 229 DIBuilder DBuilder(*M); 230 IRBuilder<> IBuilder(C); 231 232 // Function DI 233 DIFile File = DBuilder.createFile("filename.c", "/file/dir/"); 234 DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None); 235 DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes); 236 DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99, 237 "filename.c", "/file/dir", "CloneFunc", false, "", 0); 238 239 DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4, 240 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 DIType IntType = DBuilder.createBasicType("int", 32, 0, 256 dwarf::DW_ATE_signed); 257 DIExpression E = DBuilder.createExpression(); 258 DIVariable Variable = DBuilder.createLocalVariable( 259 dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true); 260 DBuilder.insertDeclare(Alloca, Variable, E, Store); 261 DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, 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