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, ReplaceAllDbgUsesWith) { 736 using namespace llvm::dwarf; 737 738 LLVMContext Ctx; 739 740 // Note: The datalayout simulates Darwin/x86_64. 741 std::unique_ptr<Module> M = parseIR(Ctx, 742 R"( 743 target datalayout = "e-m:o-i63:64-f80:128-n8:16:32:64-S128" 744 745 declare i32 @escape(i32) 746 747 define void @f() !dbg !6 { 748 entry: 749 %a = add i32 0, 1, !dbg !15 750 call void @llvm.dbg.value(metadata i32 %a, metadata !9, metadata !DIExpression()), !dbg !15 751 752 %b = add i64 0, 1, !dbg !16 753 call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression()), !dbg !16 754 call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul)), !dbg !16 755 call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value)), !dbg !16 756 call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 8)), !dbg !16 757 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 758 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 759 760 %c = inttoptr i64 0 to i64*, !dbg !17 761 call void @llvm.dbg.declare(metadata i64* %c, metadata !13, metadata !DIExpression()), !dbg !17 762 763 %d = inttoptr i64 0 to i32*, !dbg !18 764 call void @llvm.dbg.declare(metadata i32* %d, metadata !20, metadata !DIExpression()), !dbg !18 765 766 %e = add <2 x i16> zeroinitializer, zeroinitializer 767 call void @llvm.dbg.value(metadata <2 x i16> %e, metadata !14, metadata !DIExpression()), !dbg !18 768 769 %f = call i32 @escape(i32 0) 770 call void @llvm.dbg.value(metadata i32 %f, metadata !9, metadata !DIExpression()), !dbg !15 771 772 %barrier = call i32 @escape(i32 0) 773 774 %g = call i32 @escape(i32 %f) 775 call void @llvm.dbg.value(metadata i32 %g, metadata !9, metadata !DIExpression()), !dbg !15 776 777 ret void, !dbg !19 778 } 779 780 declare void @llvm.dbg.declare(metadata, metadata, metadata) 781 declare void @llvm.dbg.value(metadata, metadata, metadata) 782 783 !llvm.dbg.cu = !{!0} 784 !llvm.module.flags = !{!5} 785 786 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 787 !1 = !DIFile(filename: "/Users/vsk/Desktop/foo.ll", directory: "/") 788 !2 = !{} 789 !5 = !{i32 2, !"Debug Info Version", i32 3} 790 !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) 791 !7 = !DISubroutineType(types: !2) 792 !8 = !{!9, !11, !13, !14} 793 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) 794 !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed) 795 !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12) 796 !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed) 797 !13 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !12) 798 !14 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 4, type: !10) 799 !15 = !DILocation(line: 1, column: 1, scope: !6) 800 !16 = !DILocation(line: 2, column: 1, scope: !6) 801 !17 = !DILocation(line: 3, column: 1, scope: !6) 802 !18 = !DILocation(line: 4, column: 1, scope: !6) 803 !19 = !DILocation(line: 5, column: 1, scope: !6) 804 !20 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 5, type: !10) 805 )"); 806 807 bool BrokenDebugInfo = true; 808 verifyModule(*M, &errs(), &BrokenDebugInfo); 809 ASSERT_FALSE(BrokenDebugInfo); 810 811 Function &F = *cast<Function>(M->getNamedValue("f")); 812 DominatorTree DT{F}; 813 814 BasicBlock &BB = F.front(); 815 Instruction &A = BB.front(); 816 Instruction &B = *A.getNextNonDebugInstruction(); 817 Instruction &C = *B.getNextNonDebugInstruction(); 818 Instruction &D = *C.getNextNonDebugInstruction(); 819 Instruction &E = *D.getNextNonDebugInstruction(); 820 Instruction &F_ = *E.getNextNonDebugInstruction(); 821 Instruction &Barrier = *F_.getNextNonDebugInstruction(); 822 Instruction &G = *Barrier.getNextNonDebugInstruction(); 823 824 // Simulate i32 <-> i64* conversion. Expect no updates: the datalayout says 825 // pointers are 64 bits, so the conversion would be lossy. 826 EXPECT_FALSE(replaceAllDbgUsesWith(A, C, C, DT)); 827 EXPECT_FALSE(replaceAllDbgUsesWith(C, A, A, DT)); 828 829 // Simulate i32 <-> <2 x i16> conversion. This is unsupported. 830 EXPECT_FALSE(replaceAllDbgUsesWith(E, A, A, DT)); 831 EXPECT_FALSE(replaceAllDbgUsesWith(A, E, E, DT)); 832 833 // Simulate i32* <-> i64* conversion. 834 EXPECT_TRUE(replaceAllDbgUsesWith(D, C, C, DT)); 835 836 SmallVector<DbgVariableIntrinsic *, 2> CDbgVals; 837 findDbgUsers(CDbgVals, &C); 838 EXPECT_EQ(2U, CDbgVals.size()); 839 EXPECT_TRUE(all_of(CDbgVals, [](DbgVariableIntrinsic *DII) { 840 return isa<DbgDeclareInst>(DII); 841 })); 842 843 EXPECT_TRUE(replaceAllDbgUsesWith(C, D, D, DT)); 844 845 SmallVector<DbgVariableIntrinsic *, 2> DDbgVals; 846 findDbgUsers(DDbgVals, &D); 847 EXPECT_EQ(2U, DDbgVals.size()); 848 EXPECT_TRUE(all_of(DDbgVals, [](DbgVariableIntrinsic *DII) { 849 return isa<DbgDeclareInst>(DII); 850 })); 851 852 // Introduce a use-before-def. Check that the dbg.value for %a is salvaged. 853 EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT)); 854 855 auto *ADbgVal = cast<DbgValueInst>(A.getNextNode()); 856 EXPECT_EQ(ADbgVal->getNumVariableLocationOps(), 1u); 857 EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocationOp(0)); 858 859 // Introduce a use-before-def. Check that the dbg.values for %f become undef. 860 EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT)); 861 862 auto *FDbgVal = cast<DbgValueInst>(F_.getNextNode()); 863 EXPECT_EQ(FDbgVal->getNumVariableLocationOps(), 1u); 864 EXPECT_TRUE(FDbgVal->isKillLocation()); 865 866 SmallVector<DbgValueInst *, 1> FDbgVals; 867 findDbgValues(FDbgVals, &F_); 868 EXPECT_EQ(0U, FDbgVals.size()); 869 870 // Simulate i32 -> i64 conversion to test sign-extension. Here are some 871 // interesting cases to handle: 872 // 1) debug user has empty DIExpression 873 // 2) debug user has non-empty, non-stack-value'd DIExpression 874 // 3) debug user has non-empty, stack-value'd DIExpression 875 // 4-6) like (1-3), but with a fragment 876 EXPECT_TRUE(replaceAllDbgUsesWith(B, A, A, DT)); 877 878 SmallVector<DbgValueInst *, 8> ADbgVals; 879 findDbgValues(ADbgVals, &A); 880 EXPECT_EQ(6U, ADbgVals.size()); 881 882 // Check that %a has a dbg.value with a DIExpression matching \p Ops. 883 auto hasADbgVal = [&](ArrayRef<uint64_t> Ops) { 884 return any_of(ADbgVals, [&](DbgValueInst *DVI) { 885 assert(DVI->getVariable()->getName() == "2"); 886 return DVI->getExpression()->getElements() == Ops; 887 }); 888 }; 889 890 // Case 1: The original expr is empty, so no deref is needed. 891 EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed, 892 DW_OP_LLVM_convert, 64, DW_ATE_signed, 893 DW_OP_stack_value})); 894 895 // Case 2: Perform an address calculation with the original expr, deref it, 896 // then sign-extend the result. 897 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, 898 DW_OP_LLVM_convert, 32, DW_ATE_signed, 899 DW_OP_LLVM_convert, 64, DW_ATE_signed, 900 DW_OP_stack_value})); 901 902 // Case 3: Insert the sign-extension logic before the DW_OP_stack_value. 903 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32, 904 DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed, 905 DW_OP_stack_value})); 906 907 // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end. 908 EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed, 909 DW_OP_LLVM_convert, 64, DW_ATE_signed, 910 DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8})); 911 912 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, 913 DW_OP_LLVM_convert, 32, DW_ATE_signed, 914 DW_OP_LLVM_convert, 64, DW_ATE_signed, 915 DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8})); 916 917 EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32, 918 DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed, 919 DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8})); 920 921 verifyModule(*M, &errs(), &BrokenDebugInfo); 922 ASSERT_FALSE(BrokenDebugInfo); 923 } 924 925 TEST(Local, RemoveUnreachableBlocks) { 926 LLVMContext C; 927 928 std::unique_ptr<Module> M = parseIR(C, 929 R"( 930 define void @br_simple() { 931 entry: 932 br label %bb0 933 bb0: 934 ret void 935 bb1: 936 ret void 937 } 938 939 define void @br_self_loop() { 940 entry: 941 br label %bb0 942 bb0: 943 br i1 true, label %bb1, label %bb0 944 bb1: 945 br i1 true, label %bb0, label %bb2 946 bb2: 947 br label %bb2 948 } 949 950 define void @br_constant() { 951 entry: 952 br label %bb0 953 bb0: 954 br i1 true, label %bb1, label %bb2 955 bb1: 956 br i1 true, label %bb0, label %bb2 957 bb2: 958 br label %bb2 959 } 960 961 define void @br_loop() { 962 entry: 963 br label %bb0 964 bb0: 965 br label %bb0 966 bb1: 967 br label %bb2 968 bb2: 969 br label %bb1 970 } 971 972 declare i32 @__gxx_personality_v0(...) 973 974 define void @invoke_terminator() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 975 entry: 976 br i1 undef, label %invoke.block, label %exit 977 978 invoke.block: 979 %cond = invoke zeroext i1 @invokable() 980 to label %continue.block unwind label %lpad.block 981 982 continue.block: 983 br i1 %cond, label %if.then, label %if.end 984 985 if.then: 986 unreachable 987 988 if.end: 989 unreachable 990 991 lpad.block: 992 %lp = landingpad { i8*, i32 } 993 catch i8* null 994 br label %exit 995 996 exit: 997 ret void 998 } 999 1000 declare i1 @invokable() 1001 )"); 1002 1003 auto runEager = [&](Function &F, DominatorTree *DT) { 1004 PostDominatorTree PDT = PostDominatorTree(F); 1005 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager); 1006 removeUnreachableBlocks(F, &DTU); 1007 EXPECT_TRUE(DTU.getDomTree().verify()); 1008 EXPECT_TRUE(DTU.getPostDomTree().verify()); 1009 }; 1010 1011 auto runLazy = [&](Function &F, DominatorTree *DT) { 1012 PostDominatorTree PDT = PostDominatorTree(F); 1013 DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy); 1014 removeUnreachableBlocks(F, &DTU); 1015 EXPECT_TRUE(DTU.getDomTree().verify()); 1016 EXPECT_TRUE(DTU.getPostDomTree().verify()); 1017 }; 1018 1019 // Test removeUnreachableBlocks under Eager UpdateStrategy. 1020 runWithDomTree(*M, "br_simple", runEager); 1021 runWithDomTree(*M, "br_self_loop", runEager); 1022 runWithDomTree(*M, "br_constant", runEager); 1023 runWithDomTree(*M, "br_loop", runEager); 1024 runWithDomTree(*M, "invoke_terminator", runEager); 1025 1026 // Test removeUnreachableBlocks under Lazy UpdateStrategy. 1027 runWithDomTree(*M, "br_simple", runLazy); 1028 runWithDomTree(*M, "br_self_loop", runLazy); 1029 runWithDomTree(*M, "br_constant", runLazy); 1030 runWithDomTree(*M, "br_loop", runLazy); 1031 runWithDomTree(*M, "invoke_terminator", runLazy); 1032 1033 M = parseIR(C, 1034 R"( 1035 define void @f() { 1036 entry: 1037 ret void 1038 bb0: 1039 ret void 1040 } 1041 )"); 1042 1043 auto checkRUBlocksRetVal = [&](Function &F, DominatorTree *DT) { 1044 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); 1045 EXPECT_TRUE(removeUnreachableBlocks(F, &DTU)); 1046 EXPECT_FALSE(removeUnreachableBlocks(F, &DTU)); 1047 EXPECT_TRUE(DTU.getDomTree().verify()); 1048 }; 1049 1050 runWithDomTree(*M, "f", checkRUBlocksRetVal); 1051 } 1052 1053 TEST(Local, SimplifyCFGWithNullAC) { 1054 LLVMContext Ctx; 1055 1056 std::unique_ptr<Module> M = parseIR(Ctx, R"( 1057 declare void @true_path() 1058 declare void @false_path() 1059 declare void @llvm.assume(i1 %cond); 1060 1061 define i32 @foo(i1, i32) { 1062 entry: 1063 %cmp = icmp sgt i32 %1, 0 1064 br i1 %cmp, label %if.bb1, label %then.bb1 1065 if.bb1: 1066 call void @true_path() 1067 br label %test.bb 1068 then.bb1: 1069 call void @false_path() 1070 br label %test.bb 1071 test.bb: 1072 %phi = phi i1 [1, %if.bb1], [%0, %then.bb1] 1073 call void @llvm.assume(i1 %0) 1074 br i1 %phi, label %if.bb2, label %then.bb2 1075 if.bb2: 1076 ret i32 %1 1077 then.bb2: 1078 ret i32 0 1079 } 1080 )"); 1081 1082 Function &F = *cast<Function>(M->getNamedValue("foo")); 1083 TargetTransformInfo TTI(M->getDataLayout()); 1084 1085 SimplifyCFGOptions Options{}; 1086 Options.setAssumptionCache(nullptr); 1087 1088 // Obtain BasicBlock of interest to this test, %test.bb. 1089 BasicBlock *TestBB = nullptr; 1090 for (BasicBlock &BB : F) { 1091 if (BB.getName().equals("test.bb")) { 1092 TestBB = &BB; 1093 break; 1094 } 1095 } 1096 ASSERT_TRUE(TestBB); 1097 1098 DominatorTree DT(F); 1099 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); 1100 1101 // %test.bb is expected to be simplified by FoldCondBranchOnPHI. 1102 EXPECT_TRUE(simplifyCFG(TestBB, TTI, 1103 RequireAndPreserveDomTree ? &DTU : nullptr, Options)); 1104 } 1105 1106 TEST(Local, CanReplaceOperandWithVariable) { 1107 LLVMContext Ctx; 1108 Module M("test_module", Ctx); 1109 IRBuilder<> B(Ctx); 1110 1111 FunctionType *FnType = 1112 FunctionType::get(Type::getVoidTy(Ctx), {}, false); 1113 1114 FunctionType *VarArgFnType = 1115 FunctionType::get(Type::getVoidTy(Ctx), {B.getInt32Ty()}, true); 1116 1117 Function *TestBody = Function::Create(FnType, GlobalValue::ExternalLinkage, 1118 0, "", &M); 1119 1120 BasicBlock *BB0 = BasicBlock::Create(Ctx, "", TestBody); 1121 B.SetInsertPoint(BB0); 1122 1123 FunctionCallee Intrin = M.getOrInsertFunction("llvm.foo", FnType); 1124 FunctionCallee Func = M.getOrInsertFunction("foo", FnType); 1125 FunctionCallee VarArgFunc 1126 = M.getOrInsertFunction("foo.vararg", VarArgFnType); 1127 FunctionCallee VarArgIntrin 1128 = M.getOrInsertFunction("llvm.foo.vararg", VarArgFnType); 1129 1130 auto *CallToIntrin = B.CreateCall(Intrin); 1131 auto *CallToFunc = B.CreateCall(Func); 1132 1133 // Test if it's valid to replace the callee operand. 1134 EXPECT_FALSE(canReplaceOperandWithVariable(CallToIntrin, 0)); 1135 EXPECT_TRUE(canReplaceOperandWithVariable(CallToFunc, 0)); 1136 1137 // That it's invalid to replace an argument in the variadic argument list for 1138 // an intrinsic, but OK for a normal function. 1139 auto *CallToVarArgFunc = B.CreateCall( 1140 VarArgFunc, {B.getInt32(0), B.getInt32(1), B.getInt32(2)}); 1141 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 0)); 1142 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 1)); 1143 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 2)); 1144 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgFunc, 3)); 1145 1146 auto *CallToVarArgIntrin = B.CreateCall( 1147 VarArgIntrin, {B.getInt32(0), B.getInt32(1), B.getInt32(2)}); 1148 EXPECT_TRUE(canReplaceOperandWithVariable(CallToVarArgIntrin, 0)); 1149 EXPECT_FALSE(canReplaceOperandWithVariable(CallToVarArgIntrin, 1)); 1150 EXPECT_FALSE(canReplaceOperandWithVariable(CallToVarArgIntrin, 2)); 1151 EXPECT_FALSE(canReplaceOperandWithVariable(CallToVarArgIntrin, 3)); 1152 1153 // Test that it's invalid to replace gcroot operands, even though it can't use 1154 // immarg. 1155 Type *PtrPtr = B.getPtrTy(0); 1156 Value *Alloca = B.CreateAlloca(PtrPtr, (unsigned)0); 1157 CallInst *GCRoot = B.CreateIntrinsic(Intrinsic::gcroot, {}, 1158 {Alloca, Constant::getNullValue(PtrPtr)}); 1159 EXPECT_TRUE(canReplaceOperandWithVariable(GCRoot, 0)); // Alloca 1160 EXPECT_FALSE(canReplaceOperandWithVariable(GCRoot, 1)); 1161 EXPECT_FALSE(canReplaceOperandWithVariable(GCRoot, 2)); 1162 1163 BB0->dropAllReferences(); 1164 } 1165 1166 TEST(Local, ExpressionForConstant) { 1167 LLVMContext Context; 1168 Module M("test_module", Context); 1169 DIBuilder DIB(M); 1170 DIExpression *Expr = nullptr; 1171 1172 auto createExpression = [&](Constant *C, Type *Ty) -> DIExpression * { 1173 EXPECT_NE(C, nullptr); 1174 EXPECT_NE(Ty, nullptr); 1175 EXPECT_EQ(C->getType(), Ty); 1176 std::unique_ptr<GlobalVariable> GV = std::make_unique<GlobalVariable>( 1177 Ty, false, GlobalValue::ExternalLinkage, C, "GV"); 1178 EXPECT_NE(GV, nullptr); 1179 1180 DIExpression *Expr = getExpressionForConstant(DIB, *GV->getInitializer(), 1181 *GV->getValueType()); 1182 if (Expr) { 1183 EXPECT_EQ(Expr->getNumElements(), 3u); 1184 EXPECT_EQ(Expr->getElement(0), dwarf::DW_OP_constu); 1185 EXPECT_EQ(Expr->getElement(2), dwarf::DW_OP_stack_value); 1186 } 1187 return Expr; 1188 }; 1189 1190 // Integer. 1191 IntegerType *Int1Ty = Type::getInt1Ty(Context); 1192 Expr = createExpression(ConstantInt::getTrue(Context), Int1Ty); 1193 EXPECT_NE(Expr, nullptr); 1194 EXPECT_EQ(Expr->getElement(1), 18446744073709551615U); 1195 1196 Expr = createExpression(ConstantInt::getFalse(Context), Int1Ty); 1197 EXPECT_NE(Expr, nullptr); 1198 EXPECT_EQ(Expr->getElement(1), 0U); 1199 1200 IntegerType *Int8Ty = Type::getInt8Ty(Context); 1201 Expr = createExpression(ConstantInt::get(Int8Ty, 100), Int8Ty); 1202 EXPECT_NE(Expr, nullptr); 1203 EXPECT_EQ(Expr->getElement(1), 100U); 1204 1205 IntegerType *Int16Ty = Type::getInt16Ty(Context); 1206 Expr = createExpression(ConstantInt::getSigned(Int16Ty, -50), Int16Ty); 1207 EXPECT_NE(Expr, nullptr); 1208 EXPECT_EQ(Expr->getElement(1), -50ULL); 1209 1210 IntegerType *Int32Ty = Type::getInt32Ty(Context); 1211 Expr = createExpression(ConstantInt::get(Int32Ty, 0x7FFFFFFF), Int32Ty); 1212 EXPECT_NE(Expr, nullptr); 1213 EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFU); 1214 1215 IntegerType *Int64Ty = Type::getInt64Ty(Context); 1216 Expr = 1217 createExpression(ConstantInt::get(Int64Ty, 0x7FFFFFFFFFFFFFFF), Int64Ty); 1218 EXPECT_NE(Expr, nullptr); 1219 EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFFFFFFFFFU); 1220 1221 IntegerType *Int128Ty = Type::getInt128Ty(Context); 1222 Expr = createExpression(ConstantInt::get(Int128Ty, 0x7FFFFFFFFFFFFFFF), 1223 Int128Ty); 1224 EXPECT_NE(Expr, nullptr); 1225 EXPECT_EQ(Expr->getElement(1), 0x7FFFFFFFFFFFFFFFU); 1226 1227 GlobalVariable *String = 1228 IRBuilder<>(Context).CreateGlobalString("hello", "hello", 0, &M); 1229 Expr = createExpression(ConstantExpr::getPtrToInt(String, Int32Ty), Int32Ty); 1230 EXPECT_EQ(Expr, nullptr); 1231 1232 // Float. 1233 Type *FloatTy = Type::getFloatTy(Context); 1234 Expr = createExpression(ConstantFP::get(FloatTy, 5.55), FloatTy); 1235 EXPECT_NE(Expr, nullptr); 1236 EXPECT_EQ(Expr->getElement(1), 1085381018U); 1237 1238 // Double. 1239 Type *DoubleTy = Type::getDoubleTy(Context); 1240 Expr = createExpression(ConstantFP::get(DoubleTy, -5.55), DoubleTy); 1241 EXPECT_NE(Expr, nullptr); 1242 EXPECT_EQ(Expr->getElement(1), 13841306799765140275U); 1243 1244 // Half. 1245 Type *HalfTy = Type::getHalfTy(Context); 1246 Expr = createExpression(ConstantFP::get(HalfTy, 5.55), HalfTy); 1247 EXPECT_NE(Expr, nullptr); 1248 EXPECT_EQ(Expr->getElement(1), 17805U); 1249 1250 // BFloat. 1251 Type *BFloatTy = Type::getBFloatTy(Context); 1252 Expr = createExpression(ConstantFP::get(BFloatTy, -5.55), BFloatTy); 1253 EXPECT_NE(Expr, nullptr); 1254 EXPECT_EQ(Expr->getElement(1), 49330U); 1255 1256 // Pointer. 1257 PointerType *PtrTy = PointerType::get(Context, 0); 1258 Expr = createExpression(ConstantPointerNull::get(PtrTy), PtrTy); 1259 EXPECT_NE(Expr, nullptr); 1260 EXPECT_EQ(Expr->getElement(1), 0U); 1261 1262 ConstantInt *K1 = ConstantInt::get(Type::getInt32Ty(Context), 1234); 1263 Expr = createExpression(ConstantExpr::getIntToPtr(K1, PtrTy), PtrTy); 1264 EXPECT_NE(Expr, nullptr); 1265 EXPECT_EQ(Expr->getElement(1), 1234U); 1266 1267 ConstantInt *K2 = ConstantInt::get(Type::getInt64Ty(Context), 5678); 1268 Expr = createExpression(ConstantExpr::getIntToPtr(K2, PtrTy), PtrTy); 1269 EXPECT_NE(Expr, nullptr); 1270 EXPECT_EQ(Expr->getElement(1), 5678U); 1271 1272 Type *FP128Ty = Type::getFP128Ty(Context); 1273 Expr = createExpression(ConstantFP::get(FP128Ty, 32), FP128Ty); 1274 EXPECT_EQ(Expr, nullptr); 1275 1276 Type *X86_FP80Ty = Type::getX86_FP80Ty(Context); 1277 Expr = createExpression(ConstantFP::get(X86_FP80Ty, 32), X86_FP80Ty); 1278 EXPECT_EQ(Expr, nullptr); 1279 1280 Type *PPC_FP128Ty = Type::getPPC_FP128Ty(Context); 1281 Expr = createExpression(ConstantFP::get(PPC_FP128Ty, 32), PPC_FP128Ty); 1282 EXPECT_EQ(Expr, nullptr); 1283 } 1284 1285 TEST(Local, ReplaceDbgVariableRecord) { 1286 LLVMContext C; 1287 1288 // Test that RAUW also replaces the operands of DbgVariableRecord objects, 1289 // i.e. non-instruction stored debugging information. 1290 std::unique_ptr<Module> M = parseIR(C, 1291 R"( 1292 declare void @llvm.dbg.value(metadata, metadata, metadata) 1293 define void @f(i32 %a) !dbg !8 { 1294 entry: 1295 %foo = add i32 %a, 1, !dbg !13 1296 %bar = add i32 %foo, 0, !dbg !13 1297 call void @llvm.dbg.value(metadata i32 %bar, metadata !11, metadata !DIExpression()), !dbg !13 1298 ret void, !dbg !14 1299 } 1300 !llvm.dbg.cu = !{!0} 1301 !llvm.module.flags = !{!3, !4} 1302 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 1303 !1 = !DIFile(filename: "t2.c", directory: "foo") 1304 !2 = !{} 1305 !3 = !{i32 2, !"Dwarf Version", i32 4} 1306 !4 = !{i32 2, !"Debug Info Version", i32 3} 1307 !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) 1308 !9 = !DISubroutineType(types: !10) 1309 !10 = !{null} 1310 !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12) 1311 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 1312 !13 = !DILocation(line: 2, column: 7, scope: !8) 1313 !14 = !DILocation(line: 3, column: 1, scope: !8) 1314 )"); 1315 auto *GV = M->getNamedValue("f"); 1316 ASSERT_TRUE(GV); 1317 auto *F = dyn_cast<Function>(GV); 1318 ASSERT_TRUE(F); 1319 BasicBlock::iterator It = F->front().begin(); 1320 Instruction *FooInst = &*It; 1321 It = std::next(It); 1322 Instruction *BarInst = &*It; 1323 It = std::next(It); 1324 DbgValueInst *DVI = dyn_cast<DbgValueInst>(It); 1325 ASSERT_TRUE(DVI); 1326 It = std::next(It); 1327 Instruction *RetInst = &*It; 1328 1329 // Convert DVI into a DbgVariableRecord. 1330 RetInst->DebugMarker = new DbgMarker(); 1331 RetInst->DebugMarker->MarkedInstr = RetInst; 1332 DbgVariableRecord *DVR = new DbgVariableRecord(DVI); 1333 RetInst->DebugMarker->insertDbgRecord(DVR, false); 1334 // ... and erase the dbg.value. 1335 DVI->eraseFromParent(); 1336 1337 // DVR should originally refer to %bar, 1338 EXPECT_EQ(DVR->getVariableLocationOp(0), BarInst); 1339 1340 // Now try to replace the computation of %bar with %foo -- this should cause 1341 // the DbgVariableRecord's to have it's operand updated beneath it. 1342 BarInst->replaceAllUsesWith(FooInst); 1343 // Check DVR now points at %foo. 1344 EXPECT_EQ(DVR->getVariableLocationOp(0), FooInst); 1345 1346 // Teardown. 1347 RetInst->DebugMarker->eraseFromParent(); 1348 } 1349