1 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
32 class CloneInstruction : public ::testing::Test {
34 virtual void SetUp() {
40 Value *V2 = V1->clone();
47 DeleteContainerPointers(Clones);
50 virtual void TearDown() {
52 DeleteContainerPointers(Orig);
56 SmallPtrSet<Value *, 4> Orig; // Erase on exit
57 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
63 TEST_F(CloneInstruction, OverflowBits) {
64 V = new Argument(Type::getInt32Ty(context));
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);
70 BinaryOperator *AddClone = this->clone(Add);
71 BinaryOperator *SubClone = this->clone(Sub);
72 BinaryOperator *MulClone = this->clone(Mul);
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());
83 Add->setHasNoUnsignedWrap();
84 Sub->setHasNoUnsignedWrap();
85 Mul->setHasNoUnsignedWrap();
87 AddClone = this->clone(Add);
88 SubClone = this->clone(Sub);
89 MulClone = this->clone(Mul);
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());
100 Add->setHasNoSignedWrap();
101 Sub->setHasNoSignedWrap();
102 Mul->setHasNoSignedWrap();
104 AddClone = this->clone(Add);
105 SubClone = this->clone(Sub);
106 MulClone = this->clone(Mul);
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());
117 Add->setHasNoUnsignedWrap(false);
118 Sub->setHasNoUnsignedWrap(false);
119 Mul->setHasNoUnsignedWrap(false);
121 AddClone = this->clone(Add);
122 SubClone = this->clone(Sub);
123 MulClone = this->clone(Mul);
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());
133 TEST_F(CloneInstruction, Inbounds) {
134 V = new Argument(Type::getInt32PtrTy(context));
136 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
137 std::vector<Value *> ops;
139 GetElementPtrInst *GEP =
140 GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
141 EXPECT_FALSE(this->clone(GEP)->isInBounds());
143 GEP->setIsInBounds();
144 EXPECT_TRUE(this->clone(GEP)->isInBounds());
147 TEST_F(CloneInstruction, Exact) {
148 V = new Argument(Type::getInt32Ty(context));
150 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
151 EXPECT_FALSE(this->clone(SDiv)->isExact());
153 SDiv->setIsExact(true);
154 EXPECT_TRUE(this->clone(SDiv)->isExact());
157 TEST_F(CloneInstruction, Attributes) {
158 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
159 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
161 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
162 BasicBlock *BB = BasicBlock::Create(context, "", F1);
163 IRBuilder<> Builder(BB);
164 Builder.CreateRetVoid();
166 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
168 Attribute::AttrKind AK[] = { Attribute::NoCapture };
169 AttributeSet AS = AttributeSet::get(context, 0, AK);
170 Argument *A = F1->arg_begin();
173 SmallVector<ReturnInst*, 4> Returns;
174 ValueToValueMapTy VMap;
175 VMap[A] = UndefValue::get(A->getType());
177 CloneFunctionInto(F2, F1, VMap, false, Returns);
178 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
184 TEST_F(CloneInstruction, CallingConvention) {
185 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
186 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
188 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
189 F1->setCallingConv(CallingConv::Cold);
190 BasicBlock *BB = BasicBlock::Create(context, "", F1);
191 IRBuilder<> Builder(BB);
192 Builder.CreateRetVoid();
194 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
196 SmallVector<ReturnInst*, 4> Returns;
197 ValueToValueMapTy VMap;
198 VMap[F1->arg_begin()] = F2->arg_begin();
200 CloneFunctionInto(F2, F1, VMap, false, Returns);
201 EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
207 class CloneFunc : public ::testing::Test {
209 virtual void SetUp() {
216 virtual void TearDown() {
221 M = new Module("", C);
224 void CreateOldFunc() {
225 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
226 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
227 CreateOldFunctionBodyAndDI();
230 void CreateOldFunctionBodyAndDI() {
231 DIBuilder DBuilder(*M);
232 IRBuilder<> IBuilder(C);
235 DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
236 DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
237 DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
238 DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
239 "filename.c", "/file/dir", "CloneFunc", false, "", 0);
241 DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
242 FuncType, true, true, 3, 0, false, OldFunc);
245 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
246 IBuilder.SetInsertPoint(Entry);
247 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
248 IBuilder.SetCurrentDebugLocation(Loc);
249 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
250 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
251 Value* AllocaContent = IBuilder.getInt32(1);
252 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
253 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
254 Instruction* Terminator = IBuilder.CreateRetVoid();
256 // Create a local variable around the alloca
257 DIType IntType = DBuilder.createBasicType("int", 32, 0,
258 dwarf::DW_ATE_signed);
259 DIExpression E = DBuilder.createExpression();
260 DIVariable Variable = DBuilder.createLocalVariable(
261 dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
262 DBuilder.insertDeclare(Alloca, Variable, E, Store);
263 DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, Terminator);
264 // Finalize the debug info
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();
275 void CreateNewFunc() {
276 ValueToValueMapTy VMap;
277 NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
278 M->getFunctionList().push_back(NewFunc);
282 Finder = new DebugInfoFinder();
283 Finder->processModule(*M);
290 DebugInfoFinder* Finder;
293 // Test that a new, distinct function was created.
294 TEST_F(CloneFunc, NewFunctionCreated) {
295 EXPECT_NE(OldFunc, NewFunc);
298 // Test that a new subprogram entry was added and is pointing to the new
299 // function, while the original subprogram still points to the old one.
300 TEST_F(CloneFunc, Subprogram) {
301 EXPECT_FALSE(verifyModule(*M));
303 unsigned SubprogramCount = Finder->subprogram_count();
304 EXPECT_EQ(2U, SubprogramCount);
306 auto Iter = Finder->subprograms().begin();
307 DISubprogram Sub1(*Iter);
308 EXPECT_TRUE(Sub1.isSubprogram());
310 DISubprogram Sub2(*Iter);
311 EXPECT_TRUE(Sub2.isSubprogram());
313 EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
314 || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
317 // Test that the new subprogram entry was not added to the CU which doesn't
318 // contain the old subprogram entry.
319 TEST_F(CloneFunc, SubprogramInRightCU) {
320 EXPECT_FALSE(verifyModule(*M));
322 EXPECT_EQ(2U, Finder->compile_unit_count());
324 auto Iter = Finder->compile_units().begin();
325 DICompileUnit CU1(*Iter);
326 EXPECT_TRUE(CU1.isCompileUnit());
328 DICompileUnit CU2(*Iter);
329 EXPECT_TRUE(CU2.isCompileUnit());
330 EXPECT_TRUE(CU1.getSubprograms().getNumElements() == 0
331 || CU2.getSubprograms().getNumElements() == 0);
334 // Test that instructions in the old function still belong to it in the
335 // metadata, while instruction in the new function belong to the new one.
336 TEST_F(CloneFunc, InstructionOwnership) {
337 EXPECT_FALSE(verifyModule(*M));
339 inst_iterator OldIter = inst_begin(OldFunc);
340 inst_iterator OldEnd = inst_end(OldFunc);
341 inst_iterator NewIter = inst_begin(NewFunc);
342 inst_iterator NewEnd = inst_end(NewFunc);
343 while (OldIter != OldEnd && NewIter != NewEnd) {
344 Instruction& OldI = *OldIter;
345 Instruction& NewI = *NewIter;
346 EXPECT_NE(&OldI, &NewI);
348 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
349 if (OldI.hasMetadata()) {
350 const DebugLoc& OldDL = OldI.getDebugLoc();
351 const DebugLoc& NewDL = NewI.getDebugLoc();
353 // Verify that the debug location data is the same
354 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
355 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
357 // But that they belong to different functions
358 DISubprogram OldSubprogram(OldDL.getScope());
359 DISubprogram NewSubprogram(NewDL.getScope());
360 EXPECT_TRUE(OldSubprogram.isSubprogram());
361 EXPECT_TRUE(NewSubprogram.isSubprogram());
362 EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
363 EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
369 EXPECT_EQ(OldEnd, OldIter);
370 EXPECT_EQ(NewEnd, NewIter);
373 // Test that the arguments for debug intrinsics in the new function were
375 TEST_F(CloneFunc, DebugIntrinsics) {
376 EXPECT_FALSE(verifyModule(*M));
378 inst_iterator OldIter = inst_begin(OldFunc);
379 inst_iterator OldEnd = inst_end(OldFunc);
380 inst_iterator NewIter = inst_begin(NewFunc);
381 inst_iterator NewEnd = inst_end(NewFunc);
382 while (OldIter != OldEnd && NewIter != NewEnd) {
383 Instruction& OldI = *OldIter;
384 Instruction& NewI = *NewIter;
385 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
386 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
387 EXPECT_TRUE(NewIntrin);
389 // Old address must belong to the old function
390 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
391 getParent()->getParent());
392 // New address must belong to the new function
393 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
394 getParent()->getParent());
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 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
403 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
404 EXPECT_TRUE(NewIntrin);
406 // Old variable must belong to the old function
407 EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
408 .getContext()).getFunction());
409 // New variable must belong to the New function
410 EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
411 .getContext()).getFunction());