1 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
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
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"
33 class CloneInstruction
: public ::testing::Test
{
35 void SetUp() override
{ V
= nullptr; }
39 Value
*V2
= V1
->clone();
46 for (Value
*V
: Clones
)
51 void TearDown() override
{
60 SmallPtrSet
<Value
*, 4> Orig
; // Erase on exit
61 SmallPtrSet
<Value
*, 4> Clones
; // Erase in eraseClones
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());
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());
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());
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
;
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());
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());
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();
230 ValueToValueMapTy Mapping
;
231 DomTreeUpdater
DTU(DomTreeUpdater::UpdateStrategy::Lazy
);
233 DuplicateInstructionsInSplitBetween(BB2
, BB1
, SubInst
, Mapping
, DTU
);
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());
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
);
279 DomTreeUpdater
DTU(DomTreeUpdater::UpdateStrategy::Lazy
);
280 ValueToValueMapTy Mapping
;
281 auto Split
= DuplicateInstructionsInSplitBetween(
282 BB2
, BB2
, BB2
->getTerminator(), Mapping
, DTU
);
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
);
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
);
332 DomTreeUpdater
DTU(DomTreeUpdater::UpdateStrategy::Lazy
);
333 ValueToValueMapTy Mapping
;
335 DuplicateInstructionsInSplitBetween(BB2
, BB2
, SubInst
, Mapping
, DTU
);
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
);
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
);
372 static std::unique_ptr
<Module
> parseIR(LLVMContext
&C
, const char *IR
) {
374 std::unique_ptr
<Module
> Mod
= parseAssemblyString(IR
, Err
, C
);
376 Err
.print("CloneLoop", errs());
380 TEST(CloneLoop
, CloneLoopNest
) {
384 std::unique_ptr
<Module
> M
= parseIR(
386 R
"(define void @foo(i32* %A, i32 %ub) {
388 %guardcmp = icmp slt i32 0, %ub
389 br i1 %guardcmp, label %for.outer.preheader, label %for.end
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
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
406 br label %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
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
{
447 void SetUp() override
{
454 void TearDown() override
{ delete Finder
; }
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
);
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",
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
);
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();
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
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
);
514 DBuilder
.createAutoVariable(InlinedSP
, "inlined", File
, 5, StructType
, true);
515 auto *Scope
= DBuilder
.createLexicalBlock(
516 DBuilder
.createLexicalBlockFile(InlinedSP
, File
), File
, 1, 1);
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.
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);
540 Finder
= new DebugInfoFinder();
541 Finder
->processModule(*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
);
597 EXPECT_EQ(OldEnd
, OldIter
);
598 EXPECT_EQ(NewEnd
, NewIter
);
601 // Test that the arguments for debug intrinsics in the new function were
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
627 EXPECT_EQ(OldIntrin
->getVariable(), NewIntrin
->getVariable());
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()));
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();
662 TEST(CloneFunction
, CloneFunctionToDifferentModule
) {
663 StringRef ImplAssembly
= R
"(
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
"(
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
;
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
{
713 void SetUp() override
{
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
, {}));
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
,
738 Function::Create(FuncType
, GlobalValue::PrivateLinkage
, "f", OldM
);
739 F
->setPersonalityFn(PersFn
);
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",
749 "CloneModule", false, "", 0);
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
777 void CreateNewModule() { NewM
= llvm::CloneModule(*OldM
).release(); }
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());