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