[InstCombine] Signed saturation patterns
[llvm-complete.git] / unittests / Transforms / Utils / CloningTest.cpp
blob3d0bd10e87a99ded9c736e5d2794c07ed0ec9673
1 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/Utils/Cloning.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallPtrSet.h"
12 #include "llvm/Analysis/DomTreeUpdater.h"
13 #include "llvm/Analysis/LoopInfo.h"
14 #include "llvm/AsmParser/Parser.h"
15 #include "llvm/IR/Argument.h"
16 #include "llvm/IR/Constant.h"
17 #include "llvm/IR/DIBuilder.h"
18 #include "llvm/IR/DebugInfo.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/InstIterator.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/IntrinsicInst.h"
24 #include "llvm/IR/LLVMContext.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/IR/Verifier.h"
27 #include "gtest/gtest.h"
29 using namespace llvm;
31 namespace {
33 class CloneInstruction : public ::testing::Test {
34 protected:
35 void SetUp() override { V = nullptr; }
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);
45 void eraseClones() {
46 for (Value *V : Clones)
47 V->deleteValue();
48 Clones.clear();
51 void TearDown() override {
52 eraseClones();
53 for (Value *V : Orig)
54 V->deleteValue();
55 Orig.clear();
56 if (V)
57 V->deleteValue();
60 SmallPtrSet<Value *, 4> Orig; // Erase on exit
61 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
63 LLVMContext context;
64 Value *V;
67 TEST_F(CloneInstruction, OverflowBits) {
68 V = new Argument(Type::getInt32Ty(context));
70 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
71 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
72 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
74 BinaryOperator *AddClone = this->clone(Add);
75 BinaryOperator *SubClone = this->clone(Sub);
76 BinaryOperator *MulClone = this->clone(Mul);
78 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
79 EXPECT_FALSE(AddClone->hasNoSignedWrap());
80 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
81 EXPECT_FALSE(SubClone->hasNoSignedWrap());
82 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
83 EXPECT_FALSE(MulClone->hasNoSignedWrap());
85 eraseClones();
87 Add->setHasNoUnsignedWrap();
88 Sub->setHasNoUnsignedWrap();
89 Mul->setHasNoUnsignedWrap();
91 AddClone = this->clone(Add);
92 SubClone = this->clone(Sub);
93 MulClone = this->clone(Mul);
95 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
96 EXPECT_FALSE(AddClone->hasNoSignedWrap());
97 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
98 EXPECT_FALSE(SubClone->hasNoSignedWrap());
99 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
100 EXPECT_FALSE(MulClone->hasNoSignedWrap());
102 eraseClones();
104 Add->setHasNoSignedWrap();
105 Sub->setHasNoSignedWrap();
106 Mul->setHasNoSignedWrap();
108 AddClone = this->clone(Add);
109 SubClone = this->clone(Sub);
110 MulClone = this->clone(Mul);
112 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
113 EXPECT_TRUE(AddClone->hasNoSignedWrap());
114 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
115 EXPECT_TRUE(SubClone->hasNoSignedWrap());
116 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
117 EXPECT_TRUE(MulClone->hasNoSignedWrap());
119 eraseClones();
121 Add->setHasNoUnsignedWrap(false);
122 Sub->setHasNoUnsignedWrap(false);
123 Mul->setHasNoUnsignedWrap(false);
125 AddClone = this->clone(Add);
126 SubClone = this->clone(Sub);
127 MulClone = this->clone(Mul);
129 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
130 EXPECT_TRUE(AddClone->hasNoSignedWrap());
131 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
132 EXPECT_TRUE(SubClone->hasNoSignedWrap());
133 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
134 EXPECT_TRUE(MulClone->hasNoSignedWrap());
137 TEST_F(CloneInstruction, Inbounds) {
138 V = new Argument(Type::getInt32PtrTy(context));
140 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
141 std::vector<Value *> ops;
142 ops.push_back(Z);
143 GetElementPtrInst *GEP =
144 GetElementPtrInst::Create(Type::getInt32Ty(context), V, 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 = new Argument(Type::getInt32Ty(context));
154 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
155 EXPECT_FALSE(this->clone(SDiv)->isExact());
157 SDiv->setIsExact(true);
158 EXPECT_TRUE(this->clone(SDiv)->isExact());
161 TEST_F(CloneInstruction, Attributes) {
162 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
163 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
165 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
166 BasicBlock *BB = BasicBlock::Create(context, "", F1);
167 IRBuilder<> Builder(BB);
168 Builder.CreateRetVoid();
170 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
172 Argument *A = &*F1->arg_begin();
173 A->addAttr(Attribute::NoCapture);
175 SmallVector<ReturnInst*, 4> Returns;
176 ValueToValueMapTy VMap;
177 VMap[A] = UndefValue::get(A->getType());
179 CloneFunctionInto(F2, F1, VMap, false, Returns);
180 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
182 delete F1;
183 delete F2;
186 TEST_F(CloneInstruction, CallingConvention) {
187 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
188 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
190 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
191 F1->setCallingConv(CallingConv::Cold);
192 BasicBlock *BB = BasicBlock::Create(context, "", F1);
193 IRBuilder<> Builder(BB);
194 Builder.CreateRetVoid();
196 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
198 SmallVector<ReturnInst*, 4> Returns;
199 ValueToValueMapTy VMap;
200 VMap[&*F1->arg_begin()] = &*F2->arg_begin();
202 CloneFunctionInto(F2, F1, VMap, false, Returns);
203 EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
205 delete F1;
206 delete F2;
209 TEST_F(CloneInstruction, DuplicateInstructionsToSplit) {
210 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
211 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
212 V = new Argument(Type::getInt32Ty(context));
214 Function *F = Function::Create(FT, Function::ExternalLinkage);
216 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
217 IRBuilder<> Builder1(BB1);
219 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
220 IRBuilder<> Builder2(BB2);
222 Builder1.CreateBr(BB2);
224 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
225 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
226 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
227 Builder2.CreateRetVoid();
229 // Dummy DTU.
230 ValueToValueMapTy Mapping;
231 DomTreeUpdater DTU(DomTreeUpdater::UpdateStrategy::Lazy);
232 auto Split =
233 DuplicateInstructionsInSplitBetween(BB2, BB1, SubInst, Mapping, DTU);
235 EXPECT_TRUE(Split);
236 EXPECT_EQ(Mapping.size(), 2u);
237 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
238 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
240 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
241 EXPECT_TRUE(AddSplit);
242 EXPECT_EQ(AddSplit->getOperand(0), V);
243 EXPECT_EQ(AddSplit->getOperand(1), V);
244 EXPECT_EQ(AddSplit->getParent(), Split);
246 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
247 EXPECT_TRUE(MulSplit);
248 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
249 EXPECT_EQ(MulSplit->getOperand(1), V);
250 EXPECT_EQ(MulSplit->getParent(), Split);
252 EXPECT_EQ(AddSplit->getNextNode(), MulSplit);
253 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
255 delete F;
258 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq1) {
259 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
260 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
261 V = new Argument(Type::getInt32Ty(context));
263 Function *F = Function::Create(FT, Function::ExternalLinkage);
265 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
266 IRBuilder<> Builder1(BB1);
268 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
269 IRBuilder<> Builder2(BB2);
271 Builder1.CreateBr(BB2);
273 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
274 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
275 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
276 Builder2.CreateBr(BB2);
278 // Dummy DTU.
279 DomTreeUpdater DTU(DomTreeUpdater::UpdateStrategy::Lazy);
280 ValueToValueMapTy Mapping;
281 auto Split = DuplicateInstructionsInSplitBetween(
282 BB2, BB2, BB2->getTerminator(), Mapping, DTU);
284 EXPECT_TRUE(Split);
285 EXPECT_EQ(Mapping.size(), 3u);
286 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
287 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
288 EXPECT_TRUE(Mapping.find(SubInst) != Mapping.end());
290 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
291 EXPECT_TRUE(AddSplit);
292 EXPECT_EQ(AddSplit->getOperand(0), V);
293 EXPECT_EQ(AddSplit->getOperand(1), V);
294 EXPECT_EQ(AddSplit->getParent(), Split);
296 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
297 EXPECT_TRUE(MulSplit);
298 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
299 EXPECT_EQ(MulSplit->getOperand(1), V);
300 EXPECT_EQ(MulSplit->getParent(), Split);
302 auto SubSplit = dyn_cast<Instruction>(Mapping[SubInst]);
303 EXPECT_EQ(MulSplit->getNextNode(), SubSplit);
304 EXPECT_EQ(SubSplit->getNextNode(), Split->getTerminator());
305 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
306 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
308 delete F;
311 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq2) {
312 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
313 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
314 V = new Argument(Type::getInt32Ty(context));
316 Function *F = Function::Create(FT, Function::ExternalLinkage);
318 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
319 IRBuilder<> Builder1(BB1);
321 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
322 IRBuilder<> Builder2(BB2);
324 Builder1.CreateBr(BB2);
326 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
327 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
328 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
329 Builder2.CreateBr(BB2);
331 // Dummy DTU.
332 DomTreeUpdater DTU(DomTreeUpdater::UpdateStrategy::Lazy);
333 ValueToValueMapTy Mapping;
334 auto Split =
335 DuplicateInstructionsInSplitBetween(BB2, BB2, SubInst, Mapping, DTU);
337 EXPECT_TRUE(Split);
338 EXPECT_EQ(Mapping.size(), 2u);
339 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
340 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
342 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
343 EXPECT_TRUE(AddSplit);
344 EXPECT_EQ(AddSplit->getOperand(0), V);
345 EXPECT_EQ(AddSplit->getOperand(1), V);
346 EXPECT_EQ(AddSplit->getParent(), Split);
348 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
349 EXPECT_TRUE(MulSplit);
350 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
351 EXPECT_EQ(MulSplit->getOperand(1), V);
352 EXPECT_EQ(MulSplit->getParent(), Split);
353 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
354 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
355 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
357 delete F;
360 static void runWithLoopInfoAndDominatorTree(
361 Module &M, StringRef FuncName,
362 function_ref<void(Function &F, LoopInfo &LI, DominatorTree &DT)> Test) {
363 auto *F = M.getFunction(FuncName);
364 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
366 DominatorTree DT(*F);
367 LoopInfo LI(DT);
369 Test(*F, LI, DT);
372 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
373 SMDiagnostic Err;
374 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
375 if (!Mod)
376 Err.print("CloneLoop", errs());
377 return Mod;
380 TEST(CloneLoop, CloneLoopNest) {
381 // Parse the module.
382 LLVMContext Context;
384 std::unique_ptr<Module> M = parseIR(
385 Context,
386 R"(define void @foo(i32* %A, i32 %ub) {
387 entry:
388 %guardcmp = icmp slt i32 0, %ub
389 br i1 %guardcmp, label %for.outer.preheader, label %for.end
390 for.outer.preheader:
391 br label %for.outer
392 for.outer:
393 %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]
394 br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch
395 for.inner.preheader:
396 br label %for.inner
397 for.inner:
398 %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]
399 %idxprom = sext i32 %i to i64
400 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
401 store i32 %i, i32* %arrayidx, align 4
402 %inc = add nsw i32 %i, 1
403 %cmp = icmp slt i32 %inc, %ub
404 br i1 %cmp, label %for.inner, label %for.inner.exit
405 for.inner.exit:
406 br label %for.outer.latch
407 for.outer.latch:
408 %inc.outer = add nsw i32 %j, 1
409 %cmp.outer = icmp slt i32 %inc.outer, %ub
410 br i1 %cmp.outer, label %for.outer, label %for.outer.exit
411 for.outer.exit:
412 br label %for.end
413 for.end:
414 ret void
418 runWithLoopInfoAndDominatorTree(
419 *M, "foo", [&](Function &F, LoopInfo &LI, DominatorTree &DT) {
420 Function::iterator FI = F.begin();
421 // First basic block is entry - skip it.
422 BasicBlock *Preheader = &*(++FI);
423 BasicBlock *Header = &*(++FI);
424 assert(Header->getName() == "for.outer");
425 Loop *L = LI.getLoopFor(Header);
426 EXPECT_NE(L, nullptr);
427 EXPECT_EQ(Header, L->getHeader());
428 EXPECT_EQ(Preheader, L->getLoopPreheader());
430 ValueToValueMapTy VMap;
431 SmallVector<BasicBlock *, 4> ClonedLoopBlocks;
432 Loop *NewLoop = cloneLoopWithPreheader(Preheader, Preheader, L, VMap,
433 "", &LI, &DT, ClonedLoopBlocks);
434 EXPECT_NE(NewLoop, nullptr);
435 EXPECT_EQ(NewLoop->getSubLoops().size(), 1u);
436 Loop::block_iterator BI = NewLoop->block_begin();
437 EXPECT_TRUE((*BI)->getName().startswith("for.outer"));
438 EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.preheader"));
439 EXPECT_TRUE((*(++BI))->getName().startswith("for.inner"));
440 EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.exit"));
441 EXPECT_TRUE((*(++BI))->getName().startswith("for.outer.latch"));
445 class CloneFunc : public ::testing::Test {
446 protected:
447 void SetUp() override {
448 SetupModule();
449 CreateOldFunc();
450 CreateNewFunc();
451 SetupFinder();
454 void TearDown() override { delete Finder; }
456 void SetupModule() {
457 M = new Module("", C);
460 void CreateOldFunc() {
461 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
462 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
463 CreateOldFunctionBodyAndDI();
466 void CreateOldFunctionBodyAndDI() {
467 DIBuilder DBuilder(*M);
468 IRBuilder<> IBuilder(C);
470 // Function DI
471 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
472 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
473 DISubroutineType *FuncType =
474 DBuilder.createSubroutineType(ParamTypes);
475 auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
476 DBuilder.createFile("filename.c",
477 "/file/dir"),
478 "CloneFunc", false, "", 0);
480 auto *Subprogram = DBuilder.createFunction(
481 CU, "f", "f", File, 4, FuncType, 3, DINode::FlagZero,
482 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition);
483 OldFunc->setSubprogram(Subprogram);
485 // Function body
486 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
487 IBuilder.SetInsertPoint(Entry);
488 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
489 IBuilder.SetCurrentDebugLocation(Loc);
490 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
491 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
492 Value* AllocaContent = IBuilder.getInt32(1);
493 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
494 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
496 // Create a local variable around the alloca
497 auto *IntType = DBuilder.createBasicType("int", 32, dwarf::DW_ATE_signed);
498 auto *E = DBuilder.createExpression();
499 auto *Variable =
500 DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true);
501 auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
502 DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
503 DBuilder.insertDbgValueIntrinsic(AllocaContent, Variable, E, DL, Entry);
504 // Also create an inlined variable.
505 // Create a distinct struct type that we should not duplicate during
506 // cloning).
507 auto *StructType = DICompositeType::getDistinct(
508 C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr,
509 nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr);
510 auto *InlinedSP = DBuilder.createFunction(
511 CU, "inlined", "inlined", File, 8, FuncType, 9, DINode::FlagZero,
512 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition);
513 auto *InlinedVar =
514 DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, StructType, true);
515 auto *Scope = DBuilder.createLexicalBlock(
516 DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1);
517 auto InlinedDL =
518 DebugLoc::get(9, 4, Scope, DebugLoc::get(5, 2, Subprogram));
519 IBuilder.SetCurrentDebugLocation(InlinedDL);
520 DBuilder.insertDeclare(Alloca, InlinedVar, E, InlinedDL, Store);
521 IBuilder.CreateStore(IBuilder.getInt32(2), Alloca);
522 // Finalize the debug info.
523 DBuilder.finalize();
524 IBuilder.CreateRetVoid();
526 // Create another, empty, compile unit.
527 DIBuilder DBuilder2(*M);
528 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
529 DBuilder.createFile("extra.c", "/file/dir"),
530 "CloneFunc", false, "", 0);
531 DBuilder2.finalize();
534 void CreateNewFunc() {
535 ValueToValueMapTy VMap;
536 NewFunc = CloneFunction(OldFunc, VMap, nullptr);
539 void SetupFinder() {
540 Finder = new DebugInfoFinder();
541 Finder->processModule(*M);
544 LLVMContext C;
545 Function* OldFunc;
546 Function* NewFunc;
547 Module* M;
548 DebugInfoFinder* Finder;
551 // Test that a new, distinct function was created.
552 TEST_F(CloneFunc, NewFunctionCreated) {
553 EXPECT_NE(OldFunc, NewFunc);
556 // Test that a new subprogram entry was added and is pointing to the new
557 // function, while the original subprogram still points to the old one.
558 TEST_F(CloneFunc, Subprogram) {
559 EXPECT_FALSE(verifyModule(*M, &errs()));
560 EXPECT_EQ(3U, Finder->subprogram_count());
561 EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram());
564 // Test that instructions in the old function still belong to it in the
565 // metadata, while instruction in the new function belong to the new one.
566 TEST_F(CloneFunc, InstructionOwnership) {
567 EXPECT_FALSE(verifyModule(*M));
569 inst_iterator OldIter = inst_begin(OldFunc);
570 inst_iterator OldEnd = inst_end(OldFunc);
571 inst_iterator NewIter = inst_begin(NewFunc);
572 inst_iterator NewEnd = inst_end(NewFunc);
573 while (OldIter != OldEnd && NewIter != NewEnd) {
574 Instruction& OldI = *OldIter;
575 Instruction& NewI = *NewIter;
576 EXPECT_NE(&OldI, &NewI);
578 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
579 if (OldI.hasMetadata()) {
580 const DebugLoc& OldDL = OldI.getDebugLoc();
581 const DebugLoc& NewDL = NewI.getDebugLoc();
583 // Verify that the debug location data is the same
584 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
585 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
587 // But that they belong to different functions
588 auto *OldSubprogram = cast<DISubprogram>(OldDL.getInlinedAtScope());
589 auto *NewSubprogram = cast<DISubprogram>(NewDL.getInlinedAtScope());
590 EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
591 EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
594 ++OldIter;
595 ++NewIter;
597 EXPECT_EQ(OldEnd, OldIter);
598 EXPECT_EQ(NewEnd, NewIter);
601 // Test that the arguments for debug intrinsics in the new function were
602 // properly cloned
603 TEST_F(CloneFunc, DebugIntrinsics) {
604 EXPECT_FALSE(verifyModule(*M));
606 inst_iterator OldIter = inst_begin(OldFunc);
607 inst_iterator OldEnd = inst_end(OldFunc);
608 inst_iterator NewIter = inst_begin(NewFunc);
609 inst_iterator NewEnd = inst_end(NewFunc);
610 while (OldIter != OldEnd && NewIter != NewEnd) {
611 Instruction& OldI = *OldIter;
612 Instruction& NewI = *NewIter;
613 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
614 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
615 EXPECT_TRUE(NewIntrin);
617 // Old address must belong to the old function
618 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
619 getParent()->getParent());
620 // New address must belong to the new function
621 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
622 getParent()->getParent());
624 if (OldIntrin->getDebugLoc()->getInlinedAt()) {
625 // Inlined variable should refer to the same DILocalVariable as in the
626 // Old Function
627 EXPECT_EQ(OldIntrin->getVariable(), NewIntrin->getVariable());
628 } else {
629 // Old variable must belong to the old function.
630 EXPECT_EQ(OldFunc->getSubprogram(),
631 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
632 // New variable must belong to the new function.
633 EXPECT_EQ(NewFunc->getSubprogram(),
634 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
636 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
637 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
638 EXPECT_TRUE(NewIntrin);
640 if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
641 // Old variable must belong to the old function.
642 EXPECT_EQ(OldFunc->getSubprogram(),
643 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
644 // New variable must belong to the new function.
645 EXPECT_EQ(NewFunc->getSubprogram(),
646 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
650 ++OldIter;
651 ++NewIter;
655 static int GetDICompileUnitCount(const Module& M) {
656 if (const auto* LLVM_DBG_CU = M.getNamedMetadata("llvm.dbg.cu")) {
657 return LLVM_DBG_CU->getNumOperands();
659 return 0;
662 TEST(CloneFunction, CloneFunctionToDifferentModule) {
663 StringRef ImplAssembly = R"(
664 define void @foo() {
665 ret void, !dbg !5
668 !llvm.module.flags = !{!0}
669 !llvm.dbg.cu = !{!2, !6}
670 !0 = !{i32 1, !"Debug Info Version", i32 3}
671 !1 = distinct !DISubprogram(unit: !2)
672 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3)
673 !3 = !DIFile(filename: "foo.c", directory: "/tmp")
674 !4 = distinct !DISubprogram(unit: !2)
675 !5 = !DILocation(line: 4, scope: !1)
676 !6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3)
678 StringRef DeclAssembly = R"(
679 declare void @foo()
682 LLVMContext Context;
683 SMDiagnostic Error;
685 auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context);
686 EXPECT_TRUE(ImplModule != nullptr);
687 // DICompileUnits: !2, !6. Only !2 is reachable from @foo().
688 EXPECT_TRUE(GetDICompileUnitCount(*ImplModule) == 2);
689 auto* ImplFunction = ImplModule->getFunction("foo");
690 EXPECT_TRUE(ImplFunction != nullptr);
692 auto DeclModule = parseAssemblyString(DeclAssembly, Error, Context);
693 EXPECT_TRUE(DeclModule != nullptr);
694 // No DICompileUnits defined here.
695 EXPECT_TRUE(GetDICompileUnitCount(*DeclModule) == 0);
696 auto* DeclFunction = DeclModule->getFunction("foo");
697 EXPECT_TRUE(DeclFunction != nullptr);
699 ValueToValueMapTy VMap;
700 VMap[ImplFunction] = DeclFunction;
701 // No args to map
702 SmallVector<ReturnInst*, 8> Returns;
703 CloneFunctionInto(DeclFunction, ImplFunction, VMap, true, Returns);
705 EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
706 EXPECT_FALSE(verifyModule(*DeclModule, &errs()));
707 // DICompileUnit !2 shall be inserted into DeclModule.
708 EXPECT_TRUE(GetDICompileUnitCount(*DeclModule) == 1);
711 class CloneModule : public ::testing::Test {
712 protected:
713 void SetUp() override {
714 SetupModule();
715 CreateOldModule();
716 CreateNewModule();
719 void SetupModule() { OldM = new Module("", C); }
721 void CreateOldModule() {
722 auto *CD = OldM->getOrInsertComdat("comdat");
723 CD->setSelectionKind(Comdat::ExactMatch);
725 auto GV = new GlobalVariable(
726 *OldM, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage,
727 ConstantInt::get(Type::getInt32Ty(C), 1), "gv");
728 GV->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {}));
729 GV->setComdat(CD);
731 DIBuilder DBuilder(*OldM);
732 IRBuilder<> IBuilder(C);
734 auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
735 auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
736 "persfn", OldM);
737 auto *F =
738 Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
739 F->setPersonalityFn(PersFn);
740 F->setComdat(CD);
742 // Create debug info
743 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
744 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
745 DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes);
746 auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
747 DBuilder.createFile("filename.c",
748 "/file/dir"),
749 "CloneModule", false, "", 0);
750 // Function DI
751 auto *Subprogram = DBuilder.createFunction(
752 CU, "f", "f", File, 4, DFuncType, 3, DINode::FlagZero,
753 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition);
754 F->setSubprogram(Subprogram);
756 // Create and assign DIGlobalVariableExpression to gv
757 auto GVExpression = DBuilder.createGlobalVariableExpression(
758 Subprogram, "gv", "gv", File, 1, DBuilder.createNullPtrType(), false);
759 GV->addDebugInfo(GVExpression);
761 // DIGlobalVariableExpression not attached to any global variable
762 auto Expr = DBuilder.createExpression(
763 ArrayRef<uint64_t>{dwarf::DW_OP_constu, 42U, dwarf::DW_OP_stack_value});
765 DBuilder.createGlobalVariableExpression(
766 Subprogram, "unattached", "unattached", File, 1,
767 DBuilder.createNullPtrType(), false, Expr);
769 auto *Entry = BasicBlock::Create(C, "", F);
770 IBuilder.SetInsertPoint(Entry);
771 IBuilder.CreateRetVoid();
773 // Finalize the debug info
774 DBuilder.finalize();
777 void CreateNewModule() { NewM = llvm::CloneModule(*OldM).release(); }
779 LLVMContext C;
780 Module *OldM;
781 Module *NewM;
784 TEST_F(CloneModule, Verify) {
785 EXPECT_FALSE(verifyModule(*NewM));
788 TEST_F(CloneModule, OldModuleUnchanged) {
789 DebugInfoFinder Finder;
790 Finder.processModule(*OldM);
791 EXPECT_EQ(1U, Finder.subprogram_count());
794 TEST_F(CloneModule, Subprogram) {
795 Function *NewF = NewM->getFunction("f");
796 DISubprogram *SP = NewF->getSubprogram();
797 EXPECT_TRUE(SP != nullptr);
798 EXPECT_EQ(SP->getName(), "f");
799 EXPECT_EQ(SP->getFile()->getFilename(), "filename.c");
800 EXPECT_EQ(SP->getLine(), (unsigned)4);
803 TEST_F(CloneModule, GlobalMetadata) {
804 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
805 EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));
808 TEST_F(CloneModule, GlobalDebugInfo) {
809 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
810 EXPECT_TRUE(NewGV != nullptr);
812 // Find debug info expression assigned to global
813 SmallVector<DIGlobalVariableExpression *, 1> GVs;
814 NewGV->getDebugInfo(GVs);
815 EXPECT_EQ(GVs.size(), 1U);
817 DIGlobalVariableExpression *GVExpr = GVs[0];
818 DIGlobalVariable *GV = GVExpr->getVariable();
819 EXPECT_TRUE(GV != nullptr);
821 EXPECT_EQ(GV->getName(), "gv");
822 EXPECT_EQ(GV->getLine(), 1U);
824 // Assert that the scope of the debug info attached to
825 // global variable matches the cloned function.
826 DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
827 EXPECT_TRUE(SP != nullptr);
828 EXPECT_EQ(GV->getScope(), SP);
831 TEST_F(CloneModule, CompileUnit) {
832 // Find DICompileUnit listed in llvm.dbg.cu
833 auto *NMD = NewM->getNamedMetadata("llvm.dbg.cu");
834 EXPECT_TRUE(NMD != nullptr);
835 EXPECT_EQ(NMD->getNumOperands(), 1U);
837 DICompileUnit *CU = dyn_cast<llvm::DICompileUnit>(NMD->getOperand(0));
838 EXPECT_TRUE(CU != nullptr);
840 // Assert this CU is consistent with the cloned function debug info
841 DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
842 EXPECT_TRUE(SP != nullptr);
843 EXPECT_EQ(SP->getUnit(), CU);
845 // Check globals listed in CU have the correct scope
846 DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables();
847 EXPECT_EQ(GlobalArray.size(), 2U);
848 for (DIGlobalVariableExpression *GVExpr : GlobalArray) {
849 DIGlobalVariable *GV = GVExpr->getVariable();
850 EXPECT_EQ(GV->getScope(), SP);
854 TEST_F(CloneModule, Comdat) {
855 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
856 auto *CD = NewGV->getComdat();
857 ASSERT_NE(nullptr, CD);
858 EXPECT_EQ("comdat", CD->getName());
859 EXPECT_EQ(Comdat::ExactMatch, CD->getSelectionKind());
861 Function *NewF = NewM->getFunction("f");
862 EXPECT_EQ(CD, NewF->getComdat());