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 28using namespace llvm; 29 30namespace { 31 32class CloneInstruction : public ::testing::Test { 33protected: 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 61TEST_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 131TEST_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 145TEST_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 155TEST_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 182TEST_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 205class CloneFunc : public ::testing::Test { 206protected: 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. 293TEST_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. 299TEST_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. 317TEST_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. 332TEST_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 369TEST_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