1 //===- Local.cpp - Unit tests for Local -----------------------------------===//
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 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Transforms/Utils/Local.h"
10 #include "llvm/ADT/ScopeExit.h"
11 #include "llvm/Analysis/DomTreeUpdater.h"
12 #include "llvm/Analysis/InstructionSimplify.h"
13 #include "llvm/Analysis/PostDominators.h"
14 #include "llvm/Analysis/TargetTransformInfo.h"
15 #include "llvm/AsmParser/Parser.h"
16 #include "llvm/IR/BasicBlock.h"
17 #include "llvm/IR/DIBuilder.h"
18 #include "llvm/IR/DebugInfo.h"
19 #include "llvm/IR/DebugProgramInstruction.h"
20 #include "llvm/IR/IRBuilder.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 "llvm/Support/SourceMgr.h"
27 #include "gtest/gtest.h"
28
29 using namespace llvm;
30
31 extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
32 extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat;
33 extern bool WriteNewDbgInfoFormatToBitcode;
34 extern cl::opt<bool> WriteNewDbgInfoFormat;
35
36 // Backup all of the existing settings that may be modified when
37 // PreserveInputDbgFormat=true, so that when the test is finished we return them
38 // (and the "preserve" setting) to their original values.
SaveDbgInfoFormat()39 static auto SaveDbgInfoFormat() {
40 return make_scope_exit(
41 [OldPreserveInputDbgFormat = PreserveInputDbgFormat.getValue(),
42 OldUseNewDbgInfoFormat = UseNewDbgInfoFormat.getValue(),
43 OldWriteNewDbgInfoFormatToBitcode = WriteNewDbgInfoFormatToBitcode,
44 OldWriteNewDbgInfoFormat = WriteNewDbgInfoFormat.getValue()] {
45 PreserveInputDbgFormat = OldPreserveInputDbgFormat;
46 UseNewDbgInfoFormat = OldUseNewDbgInfoFormat;
47 WriteNewDbgInfoFormatToBitcode = OldWriteNewDbgInfoFormatToBitcode;
48 WriteNewDbgInfoFormat = OldWriteNewDbgInfoFormat;
49 });
50 }
51
TEST(Local,RecursivelyDeleteDeadPHINodes)52 TEST(Local, RecursivelyDeleteDeadPHINodes) {
53 LLVMContext C;
54
55 IRBuilder<> builder(C);
56
57 // Make blocks
58 BasicBlock *bb0 = BasicBlock::Create(C);
59 BasicBlock *bb1 = BasicBlock::Create(C);
60
61 builder.SetInsertPoint(bb0);
62 PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C), 2);
63 BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
64
65 builder.SetInsertPoint(bb1);
66 BranchInst *br1 = builder.CreateBr(bb0);
67
68 phi->addIncoming(phi, bb0);
69 phi->addIncoming(phi, bb1);
70
71 // The PHI will be removed
72 EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
73
74 // Make sure the blocks only contain the branches
75 EXPECT_EQ(&bb0->front(), br0);
76 EXPECT_EQ(&bb1->front(), br1);
77
78 builder.SetInsertPoint(bb0);
79 phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
80
81 EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
82
83 builder.SetInsertPoint(bb0);
84 phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
85 builder.CreateAdd(phi, phi);
86
87 EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
88
89 bb0->dropAllReferences();
90 bb1->dropAllReferences();
91 delete bb0;
92 delete bb1;
93 }
94
TEST(Local,RemoveDuplicatePHINodes)95 TEST(Local, RemoveDuplicatePHINodes) {
96 LLVMContext C;
97 IRBuilder<> B(C);
98
99 std::unique_ptr<Function> F(
100 Function::Create(FunctionType::get(B.getVoidTy(), false),
101 GlobalValue::ExternalLinkage, "F"));
102 BasicBlock *Entry(BasicBlock::Create(C, "", F.get()));
103 BasicBlock *BB(BasicBlock::Create(C, "", F.get()));
104 BranchInst::Create(BB, Entry);
105
106 B.SetInsertPoint(BB);
107
108 AssertingVH<PHINode> P1 = B.CreatePHI(Type::getInt32Ty(C), 2);
109 P1->addIncoming(B.getInt32(42), Entry);
110
111 PHINode *P2 = B.CreatePHI(Type::getInt32Ty(C), 2);
112 P2->addIncoming(B.getInt32(42), Entry);
113
114 AssertingVH<PHINode> P3 = B.CreatePHI(Type::getInt32Ty(C), 2);
115 P3->addIncoming(B.getInt32(42), Entry);
116 P3->addIncoming(B.getInt32(23), BB);
117
118 PHINode *P4 = B.CreatePHI(Type::getInt32Ty(C), 2);
119 P4->addIncoming(B.getInt32(42), Entry);
120 P4->addIncoming(B.getInt32(23), BB);
121
122 P1->addIncoming(P3, BB);
123 P2->addIncoming(P4, BB);
124 BranchInst::Create(BB, BB);
125
126 // Verify that we can eliminate PHIs that become duplicates after chaning PHIs
127 // downstream.
128 EXPECT_TRUE(EliminateDuplicatePHINodes(BB));
129 EXPECT_EQ(3U, BB->size());
130 }
131
parseIR(LLVMContext & C,const char * IR)132 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
133 SMDiagnostic Err;
134 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
135 if (!Mod)
136 Err.print("UtilsTests", errs());
137 return Mod;
138 }
139
TEST(Local,ReplaceDbgDeclare)140 TEST(Local, ReplaceDbgDeclare) {
141 LLVMContext C;
142 // Original C source to get debug info for a local variable:
143 // void f() { int x; }
144 std::unique_ptr<Module> M = parseIR(C,
145 R"(
146 define void @f() !dbg !8 {
147 entry:
148 %x = alloca i32, align 4
149 #dbg_declare(ptr %x, !11, !DIExpression(), !13)
150 #dbg_declare(ptr %x, !11, !DIExpression(), !13)
151 ret void, !dbg !14
152 }
153
154 !llvm.dbg.cu = !{!0}
155 !llvm.module.flags = !{!3, !4}
156 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
157 !1 = !DIFile(filename: "t2.c", directory: "foo")
158 !2 = !{}
159 !3 = !{i32 2, !"Dwarf Version", i32 4}
160 !4 = !{i32 2, !"Debug Info Version", i32 3}
161 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
162 !9 = !DISubroutineType(types: !10)
163 !10 = !{null}
164 !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
165 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
166 !13 = !DILocation(line: 2, column: 7, scope: !8)
167 !14 = !DILocation(line: 3, column: 1, scope: !8)
168 )");
169 auto *GV = M->getNamedValue("f");
170 ASSERT_TRUE(GV);
171 auto *F = dyn_cast<Function>(GV);
172 ASSERT_TRUE(F);
173 Instruction *Inst = &F->front().front();
174 auto *AI = dyn_cast<AllocaInst>(Inst);
175 ASSERT_TRUE(AI);
176
177 Value *NewBase = Constant::getNullValue(PointerType::getUnqual(C));
178 DIBuilder DIB(*M);
179 replaceDbgDeclare(AI, NewBase, DIB, DIExpression::ApplyOffset, 0);
180
181 // There should be exactly two dbg.declares, attached to the terminator.
182 Inst = F->front().getTerminator();
183 ASSERT_TRUE(Inst);
184 EXPECT_TRUE(Inst->hasDbgRecords());
185 EXPECT_EQ(range_size(Inst->getDbgRecordRange()), 2u);
186 for (DbgVariableRecord &DVR : filterDbgVars(Inst->getDbgRecordRange()))
187 EXPECT_EQ(DVR.getAddress(), NewBase);
188 }
189
190 /// Build the dominator tree for the function and run the Test.
runWithDomTree(Module & M,StringRef FuncName,function_ref<void (Function & F,DominatorTree * DT)> Test)191 static void runWithDomTree(
192 Module &M, StringRef FuncName,
193 function_ref<void(Function &F, DominatorTree *DT)> Test) {
194 auto *F = M.getFunction(FuncName);
195 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
196 // Compute the dominator tree for the function.
197 DominatorTree DT(*F);
198 Test(*F, &DT);
199 }
200
TEST(Local,MergeBasicBlockIntoOnlyPred)201 TEST(Local, MergeBasicBlockIntoOnlyPred) {
202 LLVMContext C;
203 std::unique_ptr<Module> M;
204 auto resetIR = [&]() {
205 M = parseIR(C,
206 R"(
207 define i32 @f(i8* %str) {
208 entry:
209 br label %bb2.i
210 bb2.i: ; preds = %bb4.i, %entry
211 br i1 false, label %bb4.i, label %base2flt.exit204
212 bb4.i: ; preds = %bb2.i
213 br i1 false, label %base2flt.exit204, label %bb2.i
214 bb10.i196.bb7.i197_crit_edge: ; No predecessors!
215 br label %bb7.i197
216 bb7.i197: ; preds = %bb10.i196.bb7.i197_crit_edge
217 %.reg2mem.0 = phi i32 [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ]
218 br i1 undef, label %base2flt.exit204, label %base2flt.exit204
219 base2flt.exit204: ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i
220 ret i32 0
221 }
222 )");
223 };
224
225 auto resetIRReplaceEntry = [&]() {
226 M = parseIR(C,
227 R"(
228 define i32 @f() {
229 entry:
230 br label %bb2.i
231 bb2.i: ; preds = %entry
232 ret i32 0
233 }
234 )");
235 };
236
237 auto Test = [&](Function &F, DomTreeUpdater &DTU) {
238 for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
239 BasicBlock *BB = &*I++;
240 BasicBlock *SinglePred = BB->getSinglePredecessor();
241 if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
242 continue;
243 BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator());
244 if (Term && !Term->isConditional())
245 MergeBasicBlockIntoOnlyPred(BB, &DTU);
246 }
247 if (DTU.hasDomTree()) {
248 EXPECT_TRUE(DTU.getDomTree().verify());
249 }
250 if (DTU.hasPostDomTree()) {
251 EXPECT_TRUE(DTU.getPostDomTree().verify());
252 }
253 };
254
255 // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
256 // both DT and PDT.
257 resetIR();
258 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
259 PostDominatorTree PDT = PostDominatorTree(F);
260 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
261 Test(F, DTU);
262 });
263
264 // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
265 // DT.
266 resetIR();
267 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
268 DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Eager);
269 Test(F, DTU);
270 });
271
272 // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
273 // PDT.
274 resetIR();
275 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
276 PostDominatorTree PDT = PostDominatorTree(F);
277 DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Eager);
278 Test(F, DTU);
279 });
280
281 // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
282 // both DT and PDT.
283 resetIR();
284 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
285 PostDominatorTree PDT = PostDominatorTree(F);
286 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
287 Test(F, DTU);
288 });
289
290 // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
291 // PDT.
292 resetIR();
293 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
294 PostDominatorTree PDT = PostDominatorTree(F);
295 DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Lazy);
296 Test(F, DTU);
297 });
298
299 // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with DT.
300 resetIR();
301 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
302 DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Lazy);
303 Test(F, DTU);
304 });
305
306 // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
307 // both DT and PDT.
308 resetIRReplaceEntry();
309 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
310 PostDominatorTree PDT = PostDominatorTree(F);
311 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
312 Test(F, DTU);
313 });
314
315 // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
316 // DT.
317 resetIRReplaceEntry();
318 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
319 DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Eager);
320 Test(F, DTU);
321 });
322
323 // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
324 // PDT.
325 resetIRReplaceEntry();
326 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
327 PostDominatorTree PDT = PostDominatorTree(F);
328 DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Eager);
329 Test(F, DTU);
330 });
331
332 // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
333 // both DT and PDT.
334 resetIRReplaceEntry();
335 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
336 PostDominatorTree PDT = PostDominatorTree(F);
337 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
338 Test(F, DTU);
339 });
340
341 // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
342 // PDT.
343 resetIRReplaceEntry();
344 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
345 PostDominatorTree PDT = PostDominatorTree(F);
346 DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Lazy);
347 Test(F, DTU);
348 });
349
350 // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with DT.
351 resetIRReplaceEntry();
352 runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
353 DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Lazy);
354 Test(F, DTU);
355 });
356 }
357
TEST(Local,ConstantFoldTerminator)358 TEST(Local, ConstantFoldTerminator) {
359 LLVMContext C;
360
361 std::unique_ptr<Module> M = parseIR(C,
362 R"(
363 define void @br_same_dest() {
364 entry:
365 br i1 false, label %bb0, label %bb0
366 bb0:
367 ret void
368 }
369
370 define void @br_different_dest() {
371 entry:
372 br i1 true, label %bb0, label %bb1
373 bb0:
374 br label %exit
375 bb1:
376 br label %exit
377 exit:
378 ret void
379 }
380
381 define void @switch_2_different_dest() {
382 entry:
383 switch i32 0, label %default [ i32 0, label %bb0 ]
384 default:
385 ret void
386 bb0:
387 ret void
388 }
389 define void @switch_2_different_dest_default() {
390 entry:
391 switch i32 1, label %default [ i32 0, label %bb0 ]
392 default:
393 ret void
394 bb0:
395 ret void
396 }
397 define void @switch_3_different_dest() {
398 entry:
399 switch i32 0, label %default [ i32 0, label %bb0
400 i32 1, label %bb1 ]
401 default:
402 ret void
403 bb0:
404 ret void
405 bb1:
406 ret void
407 }
408
409 define void @switch_variable_2_default_dest(i32 %arg) {
410 entry:
411 switch i32 %arg, label %default [ i32 0, label %default ]
412 default:
413 ret void
414 }
415
416 define void @switch_constant_2_default_dest() {
417 entry:
418 switch i32 1, label %default [ i32 0, label %default ]
419 default:
420 ret void
421 }
422
423 define void @switch_constant_3_repeated_dest() {
424 entry:
425 switch i32 0, label %default [ i32 0, label %bb0
426 i32 1, label %bb0 ]
427 bb0:
428 ret void
429 default:
430 ret void
431 }
432
433 define void @indirectbr() {
434 entry:
435 indirectbr i8* blockaddress(@indirectbr, %bb0), [label %bb0, label %bb1]
436 bb0:
437 ret void
438 bb1:
439 ret void
440 }
441
442 define void @indirectbr_repeated() {
443 entry:
444 indirectbr i8* blockaddress(@indirectbr_repeated, %bb0), [label %bb0, label %bb0]
445 bb0:
446 ret void
447 }
448
449 define void @indirectbr_unreachable() {
450 entry:
451 indirectbr i8* blockaddress(@indirectbr_unreachable, %bb0), [label %bb1]
452 bb0:
453 ret void
454 bb1:
455 ret void
456 }
457 )");
458
459 auto CFAllTerminatorsEager = [&](Function &F, DominatorTree *DT) {
460 PostDominatorTree PDT = PostDominatorTree(F);
461 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
462 for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
463 BasicBlock *BB = &*I++;
464 ConstantFoldTerminator(BB, true, nullptr, &DTU);
465 }
466
467 EXPECT_TRUE(DTU.getDomTree().verify());
468 EXPECT_TRUE(DTU.getPostDomTree().verify());
469 };
470
471 auto CFAllTerminatorsLazy = [&](Function &F, DominatorTree *DT) {
472 PostDominatorTree PDT = PostDominatorTree(F);
473 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
474 for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
475 BasicBlock *BB = &*I++;
476 ConstantFoldTerminator(BB, true, nullptr, &DTU);
477 }
478
479 EXPECT_TRUE(DTU.getDomTree().verify());
480 EXPECT_TRUE(DTU.getPostDomTree().verify());
481 };
482
483 // Test ConstantFoldTerminator under Eager UpdateStrategy.
484 runWithDomTree(*M, "br_same_dest", CFAllTerminatorsEager);
485 runWithDomTree(*M, "br_different_dest", CFAllTerminatorsEager);
486 runWithDomTree(*M, "switch_2_different_dest", CFAllTerminatorsEager);
487 runWithDomTree(*M, "switch_2_different_dest_default", CFAllTerminatorsEager);
488 runWithDomTree(*M, "switch_3_different_dest", CFAllTerminatorsEager);
489 runWithDomTree(*M, "switch_variable_2_default_dest", CFAllTerminatorsEager);
490 runWithDomTree(*M, "switch_constant_2_default_dest", CFAllTerminatorsEager);
491 runWithDomTree(*M, "switch_constant_3_repeated_dest", CFAllTerminatorsEager);
492 runWithDomTree(*M, "indirectbr", CFAllTerminatorsEager);
493 runWithDomTree(*M, "indirectbr_repeated", CFAllTerminatorsEager);
494 runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminatorsEager);
495
496 // Test ConstantFoldTerminator under Lazy UpdateStrategy.
497 runWithDomTree(*M, "br_same_dest", CFAllTerminatorsLazy);
498 runWithDomTree(*M, "br_different_dest", CFAllTerminatorsLazy);
499 runWithDomTree(*M, "switch_2_different_dest", CFAllTerminatorsLazy);
500 runWithDomTree(*M, "switch_2_different_dest_default", CFAllTerminatorsLazy);
501 runWithDomTree(*M, "switch_3_different_dest", CFAllTerminatorsLazy);
502 runWithDomTree(*M, "switch_variable_2_default_dest", CFAllTerminatorsLazy);
503 runWithDomTree(*M, "switch_constant_2_default_dest", CFAllTerminatorsLazy);
504 runWithDomTree(*M, "switch_constant_3_repeated_dest", CFAllTerminatorsLazy);
505 runWithDomTree(*M, "indirectbr", CFAllTerminatorsLazy);
506 runWithDomTree(*M, "indirectbr_repeated", CFAllTerminatorsLazy);
507 runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminatorsLazy);
508 }
509
510 struct SalvageDebugInfoTest : ::testing::Test {
511 LLVMContext C;
512 std::unique_ptr<Module> M;
513 Function *F = nullptr;
514
SetUpSalvageDebugInfoTest515 void SetUp() override {
516 M = parseIR(C,
517 R"(
518 define void @f() !dbg !8 {
519 entry:
520 %x = add i32 0, 1
521 %y = add i32 %x, 2
522 #dbg_value(i32 %x, !11, !DIExpression(), !13)
523 #dbg_value(i32 %y, !11, !DIExpression(), !13)
524 ret void, !dbg !14
525 }
526 !llvm.dbg.cu = !{!0}
527 !llvm.module.flags = !{!3, !4}
528 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
529 !1 = !DIFile(filename: "t2.c", directory: "foo")
530 !2 = !{}
531 !3 = !{i32 2, !"Dwarf Version", i32 4}
532 !4 = !{i32 2, !"Debug Info Version", i32 3}
533 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
534 !9 = !DISubroutineType(types: !10)
535 !10 = !{null}
536 !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
537 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
538 !13 = !DILocation(line: 2, column: 7, scope: !8)
539 !14 = !DILocation(line: 3, column: 1, scope: !8)
540 )");
541
542 auto *GV = M->getNamedValue("f");
543 ASSERT_TRUE(GV);
544 F = dyn_cast<Function>(GV);
545 ASSERT_TRUE(F);
546 }
547
doesDebugValueDescribeXSalvageDebugInfoTest548 bool doesDebugValueDescribeX(const DbgVariableRecord &DVR) {
549 if (DVR.getNumVariableLocationOps() != 1u)
550 return false;
551 const auto &CI = *cast<ConstantInt>(DVR.getValue(0));
552 if (CI.isZero())
553 return DVR.getExpression()->getElements().equals(
554 {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value});
555 else if (CI.isOneValue())
556 return DVR.getExpression()->getElements().empty();
557 return false;
558 }
559
doesDebugValueDescribeYSalvageDebugInfoTest560 bool doesDebugValueDescribeY(const DbgVariableRecord &DVR) {
561 if (DVR.getNumVariableLocationOps() != 1u)
562 return false;
563 const auto &CI = *cast<ConstantInt>(DVR.getVariableLocationOp(0));
564 if (CI.isZero())
565 return DVR.getExpression()->getElements().equals(
566 {dwarf::DW_OP_plus_uconst, 3, dwarf::DW_OP_stack_value});
567 else if (CI.isOneValue())
568 return DVR.getExpression()->getElements().equals(
569 {dwarf::DW_OP_plus_uconst, 2, dwarf::DW_OP_stack_value});
570 return false;
571 }
572
verifyDebugValuesAreSalvagedSalvageDebugInfoTest573 void verifyDebugValuesAreSalvaged() {
574 // The function should only contain debug values and a terminator.
575 EXPECT_EQ(F->size(), 1u);
576 EXPECT_TRUE(F->begin()->begin()->isTerminator());
577
578 // Check that the debug values for %x and %y are preserved.
579 bool FoundX = false;
580 bool FoundY = false;
581 for (DbgVariableRecord &DVR :
582 filterDbgVars(F->begin()->begin()->getDbgRecordRange())) {
583 EXPECT_EQ(DVR.getVariable()->getName(), "x");
584 FoundX |= doesDebugValueDescribeX(DVR);
585 FoundY |= doesDebugValueDescribeY(DVR);
586 }
587 EXPECT_TRUE(FoundX);
588 EXPECT_TRUE(FoundY);
589 }
590 };
591
TEST_F(SalvageDebugInfoTest,RecursiveInstDeletion)592 TEST_F(SalvageDebugInfoTest, RecursiveInstDeletion) {
593 Instruction *Inst = &F->front().front();
594 Inst = Inst->getNextNode(); // Get %y = add ...
595 ASSERT_TRUE(Inst);
596 bool Deleted = RecursivelyDeleteTriviallyDeadInstructions(Inst);
597 ASSERT_TRUE(Deleted);
598 verifyDebugValuesAreSalvaged();
599 }
600
TEST_F(SalvageDebugInfoTest,RecursiveBlockSimplification)601 TEST_F(SalvageDebugInfoTest, RecursiveBlockSimplification) {
602 BasicBlock *BB = &F->front();
603 ASSERT_TRUE(BB);
604 bool Deleted = SimplifyInstructionsInBlock(BB);
605 ASSERT_TRUE(Deleted);
606 verifyDebugValuesAreSalvaged();
607 }
608
TEST(Local,wouldInstructionBeTriviallyDead)609 TEST(Local, wouldInstructionBeTriviallyDead) {
610 LLVMContext Ctx;
611 // FIXME: PreserveInputDbgFormat is set to true because this test has
612 // been written to expect debug intrinsics rather than debug records.
613 // TODO: This test doesn't have a DbgRecord equivalent form so delete
614 // it when debug intrinsics are removed.
615 auto SettingGuard = SaveDbgInfoFormat();
616 PreserveInputDbgFormat = cl::boolOrDefault::BOU_TRUE;
617 std::unique_ptr<Module> M = parseIR(Ctx,
618 R"(
619 define dso_local void @fun() local_unnamed_addr #0 !dbg !9 {
620 entry:
621 call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !16
622 ret void, !dbg !16
623 }
624
625 declare void @llvm.dbg.declare(metadata, metadata, metadata)
626
627 !llvm.dbg.cu = !{!0}
628 !llvm.module.flags = !{!2, !3}
629 !llvm.ident = !{!8}
630
631 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 16.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
632 !1 = !DIFile(filename: "test.c", directory: "/")
633 !2 = !{i32 7, !"Dwarf Version", i32 5}
634 !3 = !{i32 2, !"Debug Info Version", i32 3}
635 !8 = !{!"clang version 16.0.0"}
636 !9 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
637 !10 = !DISubroutineType(types: !11)
638 !11 = !{null}
639 !12 = !{!13}
640 !13 = !DILocalVariable(name: "a", scope: !9, file: !1, line: 1, type: !14)
641 !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
642 !16 = !DILocation(line: 1, column: 21, scope: !9)
643 )");
644 bool BrokenDebugInfo = true;
645 verifyModule(*M, &errs(), &BrokenDebugInfo);
646 ASSERT_FALSE(BrokenDebugInfo);
647
648 // Get the dbg.declare.
649 Function &F = *cast<Function>(M->getNamedValue("fun"));
650 Instruction *DbgDeclare = &F.front().front();
651 ASSERT_TRUE(isa<DbgDeclareInst>(DbgDeclare));
652 // Debug intrinsics with empty metadata arguments are not dead.
653 EXPECT_FALSE(wouldInstructionBeTriviallyDead(DbgDeclare));
654 }
655
TEST(Local,ChangeToUnreachable)656 TEST(Local, ChangeToUnreachable) {
657 LLVMContext Ctx;
658
659 std::unique_ptr<Module> M = parseIR(Ctx,
660 R"(
661 define internal void @foo() !dbg !6 {
662 entry:
663 ret void, !dbg !8
664 }
665
666 !llvm.dbg.cu = !{!0}
667 !llvm.debugify = !{!3, !4}
668 !llvm.module.flags = !{!5}
669
670 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
671 !1 = !DIFile(filename: "test.ll", directory: "/")
672 !2 = !{}
673 !3 = !{i32 1}
674 !4 = !{i32 0}
675 !5 = !{i32 2, !"Debug Info Version", i32 3}
676 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, isLocal: true, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !2)
677 !7 = !DISubroutineType(types: !2)
678 !8 = !DILocation(line: 1, column: 1, scope: !6)
679 )");
680
681 bool BrokenDebugInfo = true;
682 verifyModule(*M, &errs(), &BrokenDebugInfo);
683 ASSERT_FALSE(BrokenDebugInfo);
684
685 Function &F = *cast<Function>(M->getNamedValue("foo"));
686
687 BasicBlock &BB = F.front();
688 Instruction &A = BB.front();
689 DebugLoc DLA = A.getDebugLoc();
690
691 ASSERT_TRUE(isa<ReturnInst>(&A));
692 // One instruction should be affected.
693 EXPECT_EQ(changeToUnreachable(&A), 1U);
694
695 Instruction &B = BB.front();
696
697 // There should be an uncreachable instruction.
698 ASSERT_TRUE(isa<UnreachableInst>(&B));
699
700 DebugLoc DLB = B.getDebugLoc();
701 EXPECT_EQ(DLA, DLB);
702 }
703
TEST(Local,FindDbgUsers)704 TEST(Local, FindDbgUsers) {
705 LLVMContext Ctx;
706 std::unique_ptr<Module> M = parseIR(Ctx,
707 R"(
708 define dso_local void @fun(ptr %a) #0 !dbg !11 {
709 entry:
710 #dbg_assign(ptr %a, !16, !DIExpression(), !15, ptr %a, !DIExpression(), !19)
711 ret void
712 }
713
714 !llvm.dbg.cu = !{!0}
715 !llvm.module.flags = !{!2, !3, !9}
716 !llvm.ident = !{!10}
717
718 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
719 !1 = !DIFile(filename: "test.cpp", directory: "/")
720 !2 = !{i32 7, !"Dwarf Version", i32 5}
721 !3 = !{i32 2, !"Debug Info Version", i32 3}
722 !4 = !{i32 1, !"wchar_size", i32 4}
723 !9 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
724 !10 = !{!"clang version 17.0.0"}
725 !11 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
726 !12 = !DISubroutineType(types: !13)
727 !13 = !{null}
728 !14 = !{}
729 !15 = distinct !DIAssignID()
730 !16 = !DILocalVariable(name: "x", scope: !11, file: !1, line: 2, type: !17)
731 !17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64)
732 !18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
733 !19 = !DILocation(line: 0, scope: !11)
734 )");
735
736 bool BrokenDebugInfo = true;
737 verifyModule(*M, &errs(), &BrokenDebugInfo);
738 ASSERT_FALSE(BrokenDebugInfo);
739
740 // Convert to debug intrinsics as we want to test findDbgUsers and
741 // findDbgValue's debug-intrinsic-finding code here.
742 // TODO: Remove this test when debug intrinsics are removed.
743 M->convertFromNewDbgValues();
744
745 Function &Fun = *cast<Function>(M->getNamedValue("fun"));
746 Value *Arg = Fun.getArg(0);
747 SmallVector<DbgVariableIntrinsic *> Users;
748 // Arg (%a) is used twice by a single dbg.assign. Check findDbgUsers returns
749 // only 1 pointer to it rather than 2.
750 findDbgUsers(Users, Arg);
751 EXPECT_EQ(Users.size(), 1u);
752
753 SmallVector<DbgValueInst *> Vals;
754 // Arg (%a) is used twice by a single dbg.assign. Check findDbgValues returns
755 // only 1 pointer to it rather than 2.
756 findDbgValues(Vals, Arg);
757 EXPECT_EQ(Vals.size(), 1u);
758 }
759
TEST(Local,FindDbgRecords)760 TEST(Local, FindDbgRecords) {
761 // DbgRecord copy of the FindDbgUsers test above.
762 LLVMContext Ctx;
763 std::unique_ptr<Module> M = parseIR(Ctx,
764 R"(
765 define dso_local void @fun(ptr %a) #0 !dbg !11 {
766 entry:
767 #dbg_assign(ptr %a, !16, !DIExpression(), !15, ptr %a, !DIExpression(), !19)
768 ret void
769 }
770
771 !llvm.dbg.cu = !{!0}
772 !llvm.module.flags = !{!2, !3, !9}
773 !llvm.ident = !{!10}
774
775 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
776 !1 = !DIFile(filename: "test.cpp", directory: "/")
777 !2 = !{i32 7, !"Dwarf Version", i32 5}
778 !3 = !{i32 2, !"Debug Info Version", i32 3}
779 !4 = !{i32 1, !"wchar_size", i32 4}
780 !9 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
781 !10 = !{!"clang version 17.0.0"}
782 !11 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
783 !12 = !DISubroutineType(types: !13)
784 !13 = !{null}
785 !14 = !{}
786 !15 = distinct !DIAssignID()
787 !16 = !DILocalVariable(name: "x", scope: !11, file: !1, line: 2, type: !17)
788 !17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64)
789 !18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
790 !19 = !DILocation(line: 0, scope: !11)
791 )");
792
793 bool BrokenDebugInfo = true;
794 verifyModule(*M, &errs(), &BrokenDebugInfo);
795 ASSERT_FALSE(BrokenDebugInfo);
796
797 Function &Fun = *cast<Function>(M->getNamedValue("fun"));
798 Value *Arg = Fun.getArg(0);
799
800 SmallVector<DbgVariableIntrinsic *> Users;
801 SmallVector<DbgVariableRecord *> Records;
802 // Arg (%a) is used twice by a single dbg_assign. Check findDbgUsers returns
803 // only 1 pointer to it rather than 2.
804 findDbgUsers(Users, Arg, &Records);
805 EXPECT_EQ(Users.size(), 0u);
806 EXPECT_EQ(Records.size(), 1u);
807
808 SmallVector<DbgValueInst *> Vals;
809 Records.clear();
810 // Arg (%a) is used twice by a single dbg_assign. Check findDbgValues returns
811 // only 1 pointer to it rather than 2.
812 findDbgValues(Vals, Arg, &Records);
813 EXPECT_EQ(Vals.size(), 0u);
814 EXPECT_EQ(Records.size(), 1u);
815 }
816
TEST(Local,ReplaceAllDbgUsesWith)817 TEST(Local, ReplaceAllDbgUsesWith) {
818 using namespace llvm::dwarf;
819 LLVMContext Ctx;
820
821 // Note: The datalayout simulates Darwin/x86_64.
822 std::unique_ptr<Module> M = parseIR(Ctx,
823 R"(
824 target datalayout = "e-m:o-i63:64-f80:128-n8:16:32:64-S128"
825
826 declare i32 @escape(i32)
827
828 define void @f() !dbg !6 {
829 entry:
830 %a = add i32 0, 1, !dbg !15
831
832 #dbg_value(i32 %a, !9, !DIExpression(), !15)
833 %b = add i64 0, 1, !dbg !16
834
835 #dbg_value(i64 %b, !11, !DIExpression(), !16)
836 #dbg_value(i64 %b, !11, !DIExpression(DW_OP_lit0, DW_OP_mul), !16)
837 #dbg_value(i64 %b, !11, !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value), !16)
838 #dbg_value(i64 %b, !11, !DIExpression(DW_OP_LLVM_fragment, 0, 8), !16)
839 #dbg_value(i64 %b, !11, !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_fragment, 0, 8), !16)
840 #dbg_value(i64 %b, !11, !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8), !16)
841 %c = inttoptr i64 0 to ptr, !dbg !17
842
843 #dbg_declare(ptr %c, !13, !DIExpression(), !17)
844 %d = inttoptr i64 0 to ptr, !dbg !18
845
846 #dbg_declare(ptr %d, !20, !DIExpression(), !18)
847 %e = add <2 x i16> zeroinitializer, zeroinitializer
848
849 #dbg_value(<2 x i16> %e, !14, !DIExpression(), !18)
850 %f = call i32 @escape(i32 0)
851
852 #dbg_value(i32 %f, !9, !DIExpression(), !15)
853 %barrier = call i32 @escape(i32 0)
854
855 %g = call i32 @escape(i32 %f)
856
857 #dbg_value(i32 %g, !9, !DIExpression(), !15)
858 ret void, !dbg !19
859 }
860
861 !llvm.dbg.cu = !{!0}
862 !llvm.module.flags = !{!5}
863
864 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
865 !1 = !DIFile(filename: "/Users/vsk/Desktop/foo.ll", directory: "/")
866 !2 = !{}
867 !5 = !{i32 2, !"Debug Info Version", i32 3}
868 !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8)
869 !7 = !DISubroutineType(types: !2)
870 !8 = !{!9, !11, !13, !14}
871 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
872 !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed)
873 !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12)
874 !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed)
875 !13 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !12)
876 !14 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 4, type: !10)
877 !15 = !DILocation(line: 1, column: 1, scope: !6)
878 !16 = !DILocation(line: 2, column: 1, scope: !6)
879 !17 = !DILocation(line: 3, column: 1, scope: !6)
880 !18 = !DILocation(line: 4, column: 1, scope: !6)
881 !19 = !DILocation(line: 5, column: 1, scope: !6)
882 !20 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 5, type: !10)
883 )");
884
885 bool BrokenDebugInfo = true;
886 verifyModule(*M, &errs(), &BrokenDebugInfo);
887 ASSERT_FALSE(BrokenDebugInfo);
888
889 Function &F = *cast<Function>(M->getNamedValue("f"));
890 DominatorTree DT{F};
891
892 BasicBlock &BB = F.front();
893 Instruction &A = BB.front();
894 Instruction &B = *A.getNextNonDebugInstruction();
895 Instruction &C = *B.getNextNonDebugInstruction();
896 Instruction &D = *C.getNextNonDebugInstruction();
897 Instruction &E = *D.getNextNonDebugInstruction();
898 Instruction &F_ = *E.getNextNonDebugInstruction();
899 Instruction &Barrier = *F_.getNextNonDebugInstruction();
900 Instruction &G = *Barrier.getNextNonDebugInstruction();
901
902 // Simulate i32 <-> i64* conversion. Expect no updates: the datalayout says
903 // pointers are 64 bits, so the conversion would be lossy.
904 EXPECT_FALSE(replaceAllDbgUsesWith(A, C, C, DT));
905 EXPECT_FALSE(replaceAllDbgUsesWith(C, A, A, DT));
906
907 // Simulate i32 <-> <2 x i16> conversion. This is unsupported.
908 EXPECT_FALSE(replaceAllDbgUsesWith(E, A, A, DT));
909 EXPECT_FALSE(replaceAllDbgUsesWith(A, E, E, DT));
910
911 // Simulate i32* <-> i64* conversion.
912 EXPECT_TRUE(replaceAllDbgUsesWith(D, C, C, DT));
913
914 SmallVector<DbgVariableIntrinsic *, 2> CDbgVals;
915 SmallVector<DbgVariableRecord *, 2> CDbgRecords;
916 findDbgUsers(CDbgVals, &C, &CDbgRecords);
917 EXPECT_EQ(0U, CDbgVals.size());
918 EXPECT_EQ(2U, CDbgRecords.size());
919 EXPECT_TRUE(all_of(
920 CDbgRecords, [](DbgVariableRecord *DVR) { return DVR->isDbgDeclare(); }));
921
922 EXPECT_TRUE(replaceAllDbgUsesWith(C, D, D, DT));
923
924 SmallVector<DbgVariableIntrinsic *, 2> DDbgVals;
925 SmallVector<DbgVariableRecord *, 2> DDbgRecords;
926 findDbgUsers(DDbgVals, &D, &DDbgRecords);
927 EXPECT_EQ(0U, DDbgVals.size());
928 EXPECT_EQ(2U, DDbgRecords.size());
929 EXPECT_TRUE(all_of(
930 DDbgRecords, [](DbgVariableRecord *DVR) { return DVR->isDbgDeclare(); }));
931
932 // Introduce a use-before-def. Check that the dbg.value for %a is salvaged.
933 EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT));
934
935 EXPECT_FALSE(A.hasDbgRecords());
936 EXPECT_TRUE(B.hasDbgRecords());
937 DbgVariableRecord *BDbgVal =
938 cast<DbgVariableRecord>(&*B.getDbgRecordRange().begin());
939 EXPECT_EQ(BDbgVal->getNumVariableLocationOps(), 1u);
940 EXPECT_EQ(ConstantInt::get(A.getType(), 0),
941 BDbgVal->getVariableLocationOp(0));
942
943 // Introduce a use-before-def. Check that the dbg.values for %f become undef.
944 EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT));
945
946 DbgVariableRecord *BarrierDbgVal =
947 cast<DbgVariableRecord>(&*Barrier.getDbgRecordRange().begin());
948 EXPECT_EQ(BarrierDbgVal->getNumVariableLocationOps(), 1u);
949 EXPECT_TRUE(BarrierDbgVal->isKillLocation());
950
951 SmallVector<DbgValueInst *, 1> BarrierDbgVals;
952 SmallVector<DbgVariableRecord *, 8> BarrierDbgRecs;
953 findDbgValues(BarrierDbgVals, &F_, &BarrierDbgRecs);
954 EXPECT_EQ(0U, BarrierDbgVals.size());
955 EXPECT_EQ(0U, BarrierDbgRecs.size());
956
957 // Simulate i32 -> i64 conversion to test sign-extension. Here are some
958 // interesting cases to handle:
959 // 1) debug user has empty DIExpression
960 // 2) debug user has non-empty, non-stack-value'd DIExpression
961 // 3) debug user has non-empty, stack-value'd DIExpression
962 // 4-6) like (1-3), but with a fragment
963 EXPECT_TRUE(replaceAllDbgUsesWith(B, A, A, DT));
964
965 SmallVector<DbgValueInst *, 8> BDbgVals;
966 SmallVector<DbgVariableRecord *, 8> BDbgRecs;
967 findDbgValues(BDbgVals, &A, &BDbgRecs);
968 EXPECT_EQ(0U, BDbgVals.size());
969 EXPECT_EQ(6U, BDbgRecs.size());
970
971 // Check that %a has a dbg.value with a DIExpression matching \p Ops.
972 auto hasADbgVal = [&](ArrayRef<uint64_t> Ops) {
973 return any_of(BDbgRecs, [&](DbgVariableRecord *DVI) {
974 assert(DVI->getVariable()->getName() == "2");
975 return DVI->getExpression()->getElements() == Ops;
976 });
977 };
978
979 // Case 1: The original expr is empty, so no deref is needed.
980 EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
981 DW_OP_LLVM_convert, 64, DW_ATE_signed,
982 DW_OP_stack_value}));
983
984 // Case 2: Perform an address calculation with the original expr, deref it,
985 // then sign-extend the result.
986 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
987 DW_OP_LLVM_convert, 32, DW_ATE_signed,
988 DW_OP_LLVM_convert, 64, DW_ATE_signed,
989 DW_OP_stack_value}));
990
991 // Case 3: Insert the sign-extension logic before the DW_OP_stack_value.
992 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
993 DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
994 DW_OP_stack_value}));
995
996 // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end.
997 EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
998 DW_OP_LLVM_convert, 64, DW_ATE_signed,
999 DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
1000
1001 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
1002 DW_OP_LLVM_convert, 32, DW_ATE_signed,
1003 DW_OP_LLVM_convert, 64, DW_ATE_signed,
1004 DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
1005
1006 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
1007 DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
1008 DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
1009
1010 verifyModule(*M, &errs(), &BrokenDebugInfo);
1011 ASSERT_FALSE(BrokenDebugInfo);
1012 }
1013
TEST(Local,RemoveUnreachableBlocks)1014 TEST(Local, RemoveUnreachableBlocks) {
1015 LLVMContext C;
1016
1017 std::unique_ptr<Module> M = parseIR(C,
1018 R"(
1019 define void @br_simple() {
1020 entry:
1021 br label %bb0
1022 bb0:
1023 ret void
1024 bb1:
1025 ret void
1026 }
1027
1028 define void @br_self_loop() {
1029 entry:
1030 br label %bb0
1031 bb0:
1032 br i1 true, label %bb1, label %bb0
1033 bb1:
1034 br i1 true, label %bb0, label %bb2
1035 bb2:
1036 br label %bb2
1037 }
1038
1039 define void @br_constant() {
1040 entry:
1041 br label %bb0
1042 bb0:
1043 br i1 true, label %bb1, label %bb2
1044 bb1:
1045 br i1 true, label %bb0, label %bb2
1046 bb2:
1047 br label %bb2
1048 }
1049
1050 define void @br_loop() {
1051 entry:
1052 br label %bb0
1053 bb0:
1054 br label %bb0
1055 bb1:
1056 br label %bb2
1057 bb2:
1058 br label %bb1
1059 }
1060
1061 declare i32 @__gxx_personality_v0(...)
1062
1063 define void @invoke_terminator() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
1064 entry:
1065 br i1 undef, label %invoke.block, label %exit
1066
1067 invoke.block:
1068 %cond = invoke zeroext i1 @invokable()
1069 to label %continue.block unwind label %lpad.block
1070
1071 continue.block:
1072 br i1 %cond, label %if.then, label %if.end
1073
1074 if.then:
1075 unreachable
1076
1077 if.end:
1078 unreachable
1079
1080 lpad.block:
1081 %lp = landingpad { i8*, i32 }
1082 catch i8* null
1083 br label %exit
1084
1085 exit:
1086 ret void
1087 }
1088
1089 declare i1 @invokable()
1090 )");
1091
1092 auto runEager = [&](Function &F, DominatorTree *DT) {
1093 PostDominatorTree PDT = PostDominatorTree(F);
1094 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
1095 removeUnreachableBlocks(F, &DTU);
1096 EXPECT_TRUE(DTU.getDomTree().verify());
1097 EXPECT_TRUE(DTU.getPostDomTree().verify());
1098 };
1099
1100 auto runLazy = [&](Function &F, DominatorTree *DT) {
1101 PostDominatorTree PDT = PostDominatorTree(F);
1102 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
1103 removeUnreachableBlocks(F, &DTU);
1104 EXPECT_TRUE(DTU.getDomTree().verify());
1105 EXPECT_TRUE(DTU.getPostDomTree().verify());
1106 };
1107
1108 // Test removeUnreachableBlocks under Eager UpdateStrategy.
1109 runWithDomTree(*M, "br_simple", runEager);
1110 runWithDomTree(*M, "br_self_loop", runEager);
1111 runWithDomTree(*M, "br_constant", runEager);
1112 runWithDomTree(*M, "br_loop", runEager);
1113 runWithDomTree(*M, "invoke_terminator", runEager);
1114
1115 // Test removeUnreachableBlocks under Lazy UpdateStrategy.
1116 runWithDomTree(*M, "br_simple", runLazy);
1117 runWithDomTree(*M, "br_self_loop", runLazy);
1118 runWithDomTree(*M, "br_constant", runLazy);
1119 runWithDomTree(*M, "br_loop", runLazy);
1120 runWithDomTree(*M, "invoke_terminator", runLazy);
1121
1122 M = parseIR(C,
1123 R"(
1124 define void @f() {
1125 entry:
1126 ret void
1127 bb0:
1128 ret void
1129 }
1130 )");
1131
1132 auto checkRUBlocksRetVal = [&](Function &F, DominatorTree *DT) {
1133 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
1134 EXPECT_TRUE(removeUnreachableBlocks(F, &DTU));
1135 EXPECT_FALSE(removeUnreachableBlocks(F, &DTU));
1136 EXPECT_TRUE(DTU.getDomTree().verify());
1137 };
1138
1139 runWithDomTree(*M, "f", checkRUBlocksRetVal);
1140 }
1141
TEST(Local,SimplifyCFGWithNullAC)1142 TEST(Local, SimplifyCFGWithNullAC) {
1143 LLVMContext Ctx;
1144
1145 std::unique_ptr<Module> M = parseIR(Ctx, R"(
1146 declare void @true_path()
1147 declare void @false_path()
1148 declare void @llvm.assume(i1 %cond);
1149
1150 define i32 @foo(i1, i32) {
1151 entry:
1152 %cmp = icmp sgt i32 %1, 0
1153 br i1 %cmp, label %if.bb1, label %then.bb1
1154 if.bb1:
1155 call void @true_path()
1156 br label %test.bb
1157 then.bb1:
1158 call void @false_path()
1159 br label %test.bb
1160 test.bb:
1161 %phi = phi i1 [1, %if.bb1], [%0, %then.bb1]
1162 call void @llvm.assume(i1 %0)
1163 br i1 %phi, label %if.bb2, label %then.bb2
1164 if.bb2:
1165 ret i32 %1
1166 then.bb2:
1167 ret i32 0
1168 }
1169 )");
1170
1171 Function &F = *cast<Function>(M->getNamedValue("foo"));
1172 TargetTransformInfo TTI(M->getDataLayout());
1173
1174 SimplifyCFGOptions Options{};
1175 Options.setAssumptionCache(nullptr);
1176
1177 // Obtain BasicBlock of interest to this test, %test.bb.
1178 BasicBlock *TestBB = nullptr;
1179 for (BasicBlock &BB : F) {
1180 if (BB.getName() == "test.bb") {
1181 TestBB = &BB;
1182 break;
1183 }
1184 }
1185 ASSERT_TRUE(TestBB);
1186
1187 DominatorTree DT(F);
1188 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
1189
1190 // %test.bb is expected to be simplified by FoldCondBranchOnPHI.
1191 EXPECT_TRUE(simplifyCFG(TestBB, TTI,
1192 RequireAndPreserveDomTree ? &DTU : nullptr, Options));
1193 }
1194
TEST(Local,CanReplaceOperandWithVariable)1195 TEST(Local, CanReplaceOperandWithVariable) {
1196 LLVMContext Ctx;
1197 Module M("test_module", Ctx);
1198 IRBuilder<> B(Ctx);
1199
1200 FunctionType *FnType =
1201 FunctionType::get(Type::getVoidTy(Ctx), {}, false);
1202
1203 FunctionType *VarArgFnType =
1204 FunctionType::get(Type::getVoidTy(Ctx), {B.getInt32Ty()}, true);
1205
1206 Function *TestBody = Function::Create(FnType, GlobalValue::ExternalLinkage,
1207 0, "", &M);
1208
1209 BasicBlock *BB0 = BasicBlock::Create(Ctx, "", TestBody);
1210 B.SetInsertPoint(BB0);
1211
1212 FunctionCallee Intrin = M.getOrInsertFunction("llvm.foo", FnType);
1213 FunctionCallee Func = M.getOrInsertFunction("foo", FnType);
1214 FunctionCallee VarArgFunc
1215 = M.getOrInsertFunction("foo.vararg", VarArgFnType);
1216 FunctionCallee VarArgIntrin
1217 = M.getOrInsertFunction("llvm.foo.vararg", VarArgFnType);
1218
1219 auto *CallToIntrin = B.CreateCall(Intrin);
1220 auto *CallToFunc = B.CreateCall(Func);
1221
1222 // Test if it's valid to replace the callee operand.
1223 EXPECT_FALSE(canReplaceOperandWithVariable(CallToIntrin, 0));
1224 EXPECT_TRUE(canReplaceOperandWithVariable(CallToFunc, 0));
1225
1226 // That it's invalid to replace an argument in the variadic argument list for
1227 // an intrinsic, but OK for a normal function.
1228 auto *CallToVarArgFunc = B.CreateCall(
1229 VarArgFunc, {B.getInt32(0), B.getInt32(1), B.getInt32(2)});
1230 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 0));
1231 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 1));
1232 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 2));
1233 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 3));
1234
1235 auto *CallToVarArgIntrin = B.CreateCall(
1236 VarArgIntrin, {B.getInt32(0), B.getInt32(1), B.getInt32(2)});
1237 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgIntrin, 0));
1238 EXPECT_FALSE(canReplaceOperandWithVariable(CallToVarArgIntrin, 1));
1239 EXPECT_FALSE(canReplaceOperandWithVariable(CallToVarArgIntrin, 2));
1240 EXPECT_FALSE(canReplaceOperandWithVariable(CallToVarArgIntrin, 3));
1241
1242 // Test that it's invalid to replace gcroot operands, even though it can't use
1243 // immarg.
1244 Type *PtrPtr = B.getPtrTy(0);
1245 Value *Alloca = B.CreateAlloca(PtrPtr, (unsigned)0);
1246 CallInst *GCRoot = B.CreateIntrinsic(Intrinsic::gcroot, {},
1247 {Alloca, Constant::getNullValue(PtrPtr)});
1248 EXPECT_TRUE(canReplaceOperandWithVariable(GCRoot, 0)); // Alloca
1249 EXPECT_FALSE(canReplaceOperandWithVariable(GCRoot, 1));
1250 EXPECT_FALSE(canReplaceOperandWithVariable(GCRoot, 2));
1251
1252 BB0->dropAllReferences();
1253 }
1254
TEST(Local,ExpressionForConstant)1255 TEST(Local, ExpressionForConstant) {
1256 LLVMContext Context;
1257 Module M("test_module", Context);
1258 DIBuilder DIB(M);
1259 DIExpression *Expr = nullptr;
1260
1261 auto createExpression = [&](Constant *C, Type *Ty) -> DIExpression * {
1262 EXPECT_NE(C, nullptr);
1263 EXPECT_NE(Ty, nullptr);
1264 EXPECT_EQ(C->getType(), Ty);
1265 std::unique_ptr<GlobalVariable> GV = std::make_unique<GlobalVariable>(
1266 Ty, false, GlobalValue::ExternalLinkage, C, "GV");
1267 EXPECT_NE(GV, nullptr);
1268
1269 DIExpression *Expr = getExpressionForConstant(DIB, *GV->getInitializer(),
1270 *GV->getValueType());
1271 if (Expr) {
1272 EXPECT_EQ(Expr->getNumElements(), 3u);
1273 EXPECT_EQ(Expr->getElement(0), dwarf::DW_OP_constu);
1274 EXPECT_EQ(Expr->getElement(2), dwarf::DW_OP_stack_value);
1275 }
1276 return Expr;
1277 };
1278
1279 // Integer.
1280 IntegerType *Int1Ty = Type::getInt1Ty(Context);
1281 Expr = createExpression(ConstantInt::getTrue(Context), Int1Ty);
1282 EXPECT_NE(Expr, nullptr);
1283 EXPECT_EQ(Expr->getElement(1), 18446744073709551615U);
1284
1285 Expr = createExpression(ConstantInt::getFalse(Context), Int1Ty);
1286 EXPECT_NE(Expr, nullptr);
1287 EXPECT_EQ(Expr->getElement(1), 0U);
1288
1289 IntegerType *Int8Ty = Type::getInt8Ty(Context);
1290 Expr = createExpression(ConstantInt::get(Int8Ty, 100), Int8Ty);
1291 EXPECT_NE(Expr, nullptr);
1292 EXPECT_EQ(Expr->getElement(1), 100U);
1293
1294 IntegerType *Int16Ty = Type::getInt16Ty(Context);
1295 Expr = createExpression(ConstantInt::getSigned(Int16Ty, -50), Int16Ty);
1296 EXPECT_NE(Expr, nullptr);
1297 EXPECT_EQ(Expr->getElement(1), -50ULL);
1298
1299 IntegerType *Int32Ty = Type::getInt32Ty(Context);
1300 Expr = createExpression(ConstantInt::get(Int32Ty, 0x7FFFFFFF), Int32Ty);
1301 EXPECT_NE(Expr, nullptr);
1302 EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFU);
1303
1304 IntegerType *Int64Ty = Type::getInt64Ty(Context);
1305 Expr =
1306 createExpression(ConstantInt::get(Int64Ty, 0x7FFFFFFFFFFFFFFF), Int64Ty);
1307 EXPECT_NE(Expr, nullptr);
1308 EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFFFFFFFFFU);
1309
1310 IntegerType *Int128Ty = Type::getInt128Ty(Context);
1311 Expr = createExpression(ConstantInt::get(Int128Ty, 0x7FFFFFFFFFFFFFFF),
1312 Int128Ty);
1313 EXPECT_NE(Expr, nullptr);
1314 EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFFFFFFFFFU);
1315
1316 GlobalVariable *String =
1317 IRBuilder<>(Context).CreateGlobalString("hello", "hello", 0, &M);
1318 Expr = createExpression(ConstantExpr::getPtrToInt(String, Int32Ty), Int32Ty);
1319 EXPECT_EQ(Expr, nullptr);
1320
1321 // Float.
1322 Type *FloatTy = Type::getFloatTy(Context);
1323 Expr = createExpression(ConstantFP::get(FloatTy, 5.55), FloatTy);
1324 EXPECT_NE(Expr, nullptr);
1325 EXPECT_EQ(Expr->getElement(1), 1085381018U);
1326
1327 // Double.
1328 Type *DoubleTy = Type::getDoubleTy(Context);
1329 Expr = createExpression(ConstantFP::get(DoubleTy, -5.55), DoubleTy);
1330 EXPECT_NE(Expr, nullptr);
1331 EXPECT_EQ(Expr->getElement(1), 13841306799765140275U);
1332
1333 // Half.
1334 Type *HalfTy = Type::getHalfTy(Context);
1335 Expr = createExpression(ConstantFP::get(HalfTy, 5.55), HalfTy);
1336 EXPECT_NE(Expr, nullptr);
1337 EXPECT_EQ(Expr->getElement(1), 17805U);
1338
1339 // BFloat.
1340 Type *BFloatTy = Type::getBFloatTy(Context);
1341 Expr = createExpression(ConstantFP::get(BFloatTy, -5.55), BFloatTy);
1342 EXPECT_NE(Expr, nullptr);
1343 EXPECT_EQ(Expr->getElement(1), 49330U);
1344
1345 // Pointer.
1346 PointerType *PtrTy = PointerType::get(Context, 0);
1347 Expr = createExpression(ConstantPointerNull::get(PtrTy), PtrTy);
1348 EXPECT_NE(Expr, nullptr);
1349 EXPECT_EQ(Expr->getElement(1), 0U);
1350
1351 ConstantInt *K1 = ConstantInt::get(Type::getInt32Ty(Context), 1234);
1352 Expr = createExpression(ConstantExpr::getIntToPtr(K1, PtrTy), PtrTy);
1353 EXPECT_NE(Expr, nullptr);
1354 EXPECT_EQ(Expr->getElement(1), 1234U);
1355
1356 ConstantInt *K2 = ConstantInt::get(Type::getInt64Ty(Context), 5678);
1357 Expr = createExpression(ConstantExpr::getIntToPtr(K2, PtrTy), PtrTy);
1358 EXPECT_NE(Expr, nullptr);
1359 EXPECT_EQ(Expr->getElement(1), 5678U);
1360
1361 Type *FP128Ty = Type::getFP128Ty(Context);
1362 Expr = createExpression(ConstantFP::get(FP128Ty, 32), FP128Ty);
1363 EXPECT_EQ(Expr, nullptr);
1364
1365 Type *X86_FP80Ty = Type::getX86_FP80Ty(Context);
1366 Expr = createExpression(ConstantFP::get(X86_FP80Ty, 32), X86_FP80Ty);
1367 EXPECT_EQ(Expr, nullptr);
1368
1369 Type *PPC_FP128Ty = Type::getPPC_FP128Ty(Context);
1370 Expr = createExpression(ConstantFP::get(PPC_FP128Ty, 32), PPC_FP128Ty);
1371 EXPECT_EQ(Expr, nullptr);
1372 }
1373
TEST(Local,ReplaceDbgVariableRecord)1374 TEST(Local, ReplaceDbgVariableRecord) {
1375 LLVMContext C;
1376 // FIXME: PreserveInputDbgFormat is set to true because this test has
1377 // been written to expect debug intrinsics rather than debug records; use the
1378 // intrinsic format until we update the test checks.
1379 auto SettingGuard = SaveDbgInfoFormat();
1380 PreserveInputDbgFormat = cl::boolOrDefault::BOU_TRUE;
1381
1382 // Test that RAUW also replaces the operands of DbgVariableRecord objects,
1383 // i.e. non-instruction stored debugging information.
1384 std::unique_ptr<Module> M = parseIR(C,
1385 R"(
1386 declare void @llvm.dbg.value(metadata, metadata, metadata)
1387 define void @f(i32 %a) !dbg !8 {
1388 entry:
1389 %foo = add i32 %a, 1, !dbg !13
1390 %bar = add i32 %foo, 0, !dbg !13
1391 call void @llvm.dbg.value(metadata i32 %bar, metadata !11, metadata !DIExpression()), !dbg !13
1392 ret void, !dbg !14
1393 }
1394 !llvm.dbg.cu = !{!0}
1395 !llvm.module.flags = !{!3, !4}
1396 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
1397 !1 = !DIFile(filename: "t2.c", directory: "foo")
1398 !2 = !{}
1399 !3 = !{i32 2, !"Dwarf Version", i32 4}
1400 !4 = !{i32 2, !"Debug Info Version", i32 3}
1401 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
1402 !9 = !DISubroutineType(types: !10)
1403 !10 = !{null}
1404 !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
1405 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
1406 !13 = !DILocation(line: 2, column: 7, scope: !8)
1407 !14 = !DILocation(line: 3, column: 1, scope: !8)
1408 )");
1409 auto *GV = M->getNamedValue("f");
1410 ASSERT_TRUE(GV);
1411 auto *F = dyn_cast<Function>(GV);
1412 ASSERT_TRUE(F);
1413 BasicBlock::iterator It = F->front().begin();
1414 Instruction *FooInst = &*It;
1415 It = std::next(It);
1416 Instruction *BarInst = &*It;
1417 It = std::next(It);
1418 DbgValueInst *DVI = dyn_cast<DbgValueInst>(It);
1419 ASSERT_TRUE(DVI);
1420 It = std::next(It);
1421 Instruction *RetInst = &*It;
1422
1423 // Convert DVI into a DbgVariableRecord.
1424 RetInst->DebugMarker = new DbgMarker();
1425 RetInst->DebugMarker->MarkedInstr = RetInst;
1426 DbgVariableRecord *DVR = new DbgVariableRecord(DVI);
1427 RetInst->DebugMarker->insertDbgRecord(DVR, false);
1428 // ... and erase the dbg.value.
1429 DVI->eraseFromParent();
1430
1431 // DVR should originally refer to %bar,
1432 EXPECT_EQ(DVR->getVariableLocationOp(0), BarInst);
1433
1434 // Now try to replace the computation of %bar with %foo -- this should cause
1435 // the DbgVariableRecord's to have it's operand updated beneath it.
1436 BarInst->replaceAllUsesWith(FooInst);
1437 // Check DVR now points at %foo.
1438 EXPECT_EQ(DVR->getVariableLocationOp(0), FooInst);
1439
1440 // Teardown.
1441 RetInst->DebugMarker->eraseFromParent();
1442 }
1443