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/IR/Argument.h"
14 #include "llvm/IR/Constant.h"
15 #include "llvm/IR/DebugInfo.h"
16 #include "llvm/IR/DIBuilder.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/InstIterator.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/IntrinsicInst.h"
22 #include "llvm/IR/IRBuilder.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/IR/LLVMContext.h"
25 #include "gtest/gtest.h"
33 class CloneInstruction : public ::testing::Test {
35 virtual void SetUp() {
41 Value *V2 = V1->clone();
42 std::unique_ptr<Value> V(V1);
43 if (!Orig.insert(std::move(V)).second)
44 V.release(); // this wasn't the first time we added the element, so the
45 // set already had ownership
46 Clones.insert(std::unique_ptr<Value>(V2));
50 void eraseClones() { Clones.clear(); }
52 virtual void TearDown() {
58 std::set<std::unique_ptr<Value>> Orig; // Erase on exit
59 std::set<std::unique_ptr<Value>> Clones; // Erase in eraseClones
62 std::unique_ptr<Value> V;
65 TEST_F(CloneInstruction, OverflowBits) {
66 V = make_unique<Argument>(Type::getInt32Ty(context));
69 BinaryOperator::Create(Instruction::Add, V.get(), V.get());
71 BinaryOperator::Create(Instruction::Sub, V.get(), V.get());
73 BinaryOperator::Create(Instruction::Mul, V.get(), V.get());
75 BinaryOperator *AddClone = this->clone(Add);
76 BinaryOperator *SubClone = this->clone(Sub);
77 BinaryOperator *MulClone = this->clone(Mul);
79 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
80 EXPECT_FALSE(AddClone->hasNoSignedWrap());
81 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
82 EXPECT_FALSE(SubClone->hasNoSignedWrap());
83 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
84 EXPECT_FALSE(MulClone->hasNoSignedWrap());
88 Add->setHasNoUnsignedWrap();
89 Sub->setHasNoUnsignedWrap();
90 Mul->setHasNoUnsignedWrap();
92 AddClone = this->clone(Add);
93 SubClone = this->clone(Sub);
94 MulClone = this->clone(Mul);
96 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
97 EXPECT_FALSE(AddClone->hasNoSignedWrap());
98 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
99 EXPECT_FALSE(SubClone->hasNoSignedWrap());
100 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
101 EXPECT_FALSE(MulClone->hasNoSignedWrap());
105 Add->setHasNoSignedWrap();
106 Sub->setHasNoSignedWrap();
107 Mul->setHasNoSignedWrap();
109 AddClone = this->clone(Add);
110 SubClone = this->clone(Sub);
111 MulClone = this->clone(Mul);
113 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
114 EXPECT_TRUE(AddClone->hasNoSignedWrap());
115 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
116 EXPECT_TRUE(SubClone->hasNoSignedWrap());
117 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
118 EXPECT_TRUE(MulClone->hasNoSignedWrap());
122 Add->setHasNoUnsignedWrap(false);
123 Sub->setHasNoUnsignedWrap(false);
124 Mul->setHasNoUnsignedWrap(false);
126 AddClone = this->clone(Add);
127 SubClone = this->clone(Sub);
128 MulClone = this->clone(Mul);
130 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
131 EXPECT_TRUE(AddClone->hasNoSignedWrap());
132 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
133 EXPECT_TRUE(SubClone->hasNoSignedWrap());
134 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
135 EXPECT_TRUE(MulClone->hasNoSignedWrap());
138 TEST_F(CloneInstruction, Inbounds) {
139 V = make_unique<Argument>(Type::getInt32PtrTy(context));
141 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
142 std::vector<Value *> ops;
144 GetElementPtrInst *GEP = GetElementPtrInst::Create(V.get(), ops);
145 EXPECT_FALSE(this->clone(GEP)->isInBounds());
147 GEP->setIsInBounds();
148 EXPECT_TRUE(this->clone(GEP)->isInBounds());
151 TEST_F(CloneInstruction, Exact) {
152 V = make_unique<Argument>(Type::getInt32Ty(context));
154 BinaryOperator *SDiv =
155 BinaryOperator::Create(Instruction::SDiv, V.get(), V.get());
156 EXPECT_FALSE(this->clone(SDiv)->isExact());
158 SDiv->setIsExact(true);
159 EXPECT_TRUE(this->clone(SDiv)->isExact());
162 TEST_F(CloneInstruction, Attributes) {
163 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
164 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
166 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
167 BasicBlock *BB = BasicBlock::Create(context, "", F1);
168 IRBuilder<> Builder(BB);
169 Builder.CreateRetVoid();
171 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
173 Attribute::AttrKind AK[] = { Attribute::NoCapture };
174 AttributeSet AS = AttributeSet::get(context, 0, AK);
175 Argument *A = F1->arg_begin();
178 SmallVector<ReturnInst*, 4> Returns;
179 ValueToValueMapTy VMap;
180 VMap[A] = UndefValue::get(A->getType());
182 CloneFunctionInto(F2, F1, VMap, false, Returns);
183 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
189 TEST_F(CloneInstruction, CallingConvention) {
190 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
191 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
193 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
194 F1->setCallingConv(CallingConv::Cold);
195 BasicBlock *BB = BasicBlock::Create(context, "", F1);
196 IRBuilder<> Builder(BB);
197 Builder.CreateRetVoid();
199 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
201 SmallVector<ReturnInst*, 4> Returns;
202 ValueToValueMapTy VMap;
203 VMap[F1->arg_begin()] = F2->arg_begin();
205 CloneFunctionInto(F2, F1, VMap, false, Returns);
206 EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
212 class CloneFunc : public ::testing::Test {
214 virtual void SetUp() {
221 virtual void TearDown() {
226 M = new Module("", C);
229 void CreateOldFunc() {
230 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
231 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
232 CreateOldFunctionBodyAndDI();
235 void CreateOldFunctionBodyAndDI() {
236 DIBuilder DBuilder(*M);
237 IRBuilder<> IBuilder(C);
240 DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
241 DIArray ParamTypes = DBuilder.getOrCreateArray(ArrayRef<Value*>());
242 DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
243 DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
244 "filename.c", "/file/dir", "CloneFunc", false, "", 0);
246 DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
247 FuncType, true, true, 3, 0, false, OldFunc);
250 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
251 IBuilder.SetInsertPoint(Entry);
252 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
253 IBuilder.SetCurrentDebugLocation(Loc);
254 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
255 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
256 Value* AllocaContent = IBuilder.getInt32(1);
257 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
258 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
259 Instruction* Terminator = IBuilder.CreateRetVoid();
261 // Create a local variable around the alloca
262 DIType IntType = DBuilder.createBasicType("int", 32, 0,
263 dwarf::DW_ATE_signed);
264 DIVariable Variable = DBuilder.createLocalVariable(
265 dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
266 DBuilder.insertDeclare(Alloca, Variable, Store);
267 DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, Terminator);
268 // Finalize the debug info
272 // Create another, empty, compile unit
273 DIBuilder DBuilder2(*M);
274 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
275 "extra.c", "/file/dir", "CloneFunc", false, "", 0);
276 DBuilder2.finalize();
279 void CreateNewFunc() {
280 ValueToValueMapTy VMap;
281 NewFunc = CloneFunction(OldFunc, VMap, true, NULL);
282 M->getFunctionList().push_back(NewFunc);
286 Finder = new DebugInfoFinder();
287 Finder->processModule(*M);
294 DebugInfoFinder* Finder;
297 // Test that a new, distinct function was created.
298 TEST_F(CloneFunc, NewFunctionCreated) {
299 EXPECT_NE(OldFunc, NewFunc);
302 // Test that a new subprogram entry was added and is pointing to the new
303 // function, while the original subprogram still points to the old one.
304 TEST_F(CloneFunc, Subprogram) {
305 unsigned SubprogramCount = Finder->subprogram_count();
306 EXPECT_EQ(2U, SubprogramCount);
308 auto Iter = Finder->subprograms().begin();
309 DISubprogram Sub1(*Iter);
310 EXPECT_TRUE(Sub1.Verify());
312 DISubprogram Sub2(*Iter);
313 EXPECT_TRUE(Sub2.Verify());
315 EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
316 || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
319 // Test that the new subprogram entry was not added to the CU which doesn't
320 // contain the old subprogram entry.
321 TEST_F(CloneFunc, SubprogramInRightCU) {
322 EXPECT_EQ(2U, Finder->compile_unit_count());
324 auto Iter = Finder->compile_units().begin();
325 DICompileUnit CU1(*Iter);
326 EXPECT_TRUE(CU1.Verify());
328 DICompileUnit CU2(*Iter);
329 EXPECT_TRUE(CU2.Verify());
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 inst_iterator OldIter = inst_begin(OldFunc);
338 inst_iterator OldEnd = inst_end(OldFunc);
339 inst_iterator NewIter = inst_begin(NewFunc);
340 inst_iterator NewEnd = inst_end(NewFunc);
341 while (OldIter != OldEnd && NewIter != NewEnd) {
342 Instruction& OldI = *OldIter;
343 Instruction& NewI = *NewIter;
344 EXPECT_NE(&OldI, &NewI);
346 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
347 if (OldI.hasMetadata()) {
348 const DebugLoc& OldDL = OldI.getDebugLoc();
349 const DebugLoc& NewDL = NewI.getDebugLoc();
351 // Verify that the debug location data is the same
352 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
353 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
355 // But that they belong to different functions
356 DISubprogram OldSubprogram(OldDL.getScope(C));
357 DISubprogram NewSubprogram(NewDL.getScope(C));
358 EXPECT_TRUE(OldSubprogram.Verify());
359 EXPECT_TRUE(NewSubprogram.Verify());
360 EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
361 EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
367 EXPECT_EQ(OldEnd, OldIter);
368 EXPECT_EQ(NewEnd, NewIter);
371 // Test that the arguments for debug intrinsics in the new function were
373 TEST_F(CloneFunc, DebugIntrinsics) {
374 inst_iterator OldIter = inst_begin(OldFunc);
375 inst_iterator OldEnd = inst_end(OldFunc);
376 inst_iterator NewIter = inst_begin(NewFunc);
377 inst_iterator NewEnd = inst_end(NewFunc);
378 while (OldIter != OldEnd && NewIter != NewEnd) {
379 Instruction& OldI = *OldIter;
380 Instruction& NewI = *NewIter;
381 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
382 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
383 EXPECT_TRUE(NewIntrin);
385 // Old address must belong to the old function
386 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
387 getParent()->getParent());
388 // New address must belong to the new function
389 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
390 getParent()->getParent());
392 // Old variable must belong to the old function
393 EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
394 .getContext()).getFunction());
395 // New variable must belong to the New function
396 EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
397 .getContext()).getFunction());
398 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
399 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
400 EXPECT_TRUE(NewIntrin);
402 // Old variable must belong to the old function
403 EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
404 .getContext()).getFunction());
405 // New variable must belong to the New function
406 EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
407 .getContext()).getFunction());