LocalTest.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  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. #include "llvm/Transforms/Utils/Local.h"
  9. #include "llvm/Analysis/DomTreeUpdater.h"
  10. #include "llvm/Analysis/PostDominators.h"
  11. #include "llvm/AsmParser/Parser.h"
  12. #include "llvm/IR/BasicBlock.h"
  13. #include "llvm/IR/DIBuilder.h"
  14. #include "llvm/IR/IRBuilder.h"
  15. #include "llvm/IR/Instructions.h"
  16. #include "llvm/IR/IntrinsicInst.h"
  17. #include "llvm/IR/LLVMContext.h"
  18. #include "llvm/IR/Verifier.h"
  19. #include "llvm/Support/SourceMgr.h"
  20. #include "gtest/gtest.h"
  21. using namespace llvm;
  22. TEST(Local, RecursivelyDeleteDeadPHINodes) {
  23. LLVMContext C;
  24. IRBuilder<> builder(C);
  25. // Make blocks
  26. BasicBlock *bb0 = BasicBlock::Create(C);
  27. BasicBlock *bb1 = BasicBlock::Create(C);
  28. builder.SetInsertPoint(bb0);
  29. PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C), 2);
  30. BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
  31. builder.SetInsertPoint(bb1);
  32. BranchInst *br1 = builder.CreateBr(bb0);
  33. phi->addIncoming(phi, bb0);
  34. phi->addIncoming(phi, bb1);
  35. // The PHI will be removed
  36. EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
  37. // Make sure the blocks only contain the branches
  38. EXPECT_EQ(&bb0->front(), br0);
  39. EXPECT_EQ(&bb1->front(), br1);
  40. builder.SetInsertPoint(bb0);
  41. phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
  42. EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
  43. builder.SetInsertPoint(bb0);
  44. phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
  45. builder.CreateAdd(phi, phi);
  46. EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
  47. bb0->dropAllReferences();
  48. bb1->dropAllReferences();
  49. delete bb0;
  50. delete bb1;
  51. }
  52. TEST(Local, RemoveDuplicatePHINodes) {
  53. LLVMContext C;
  54. IRBuilder<> B(C);
  55. std::unique_ptr<Function> F(
  56. Function::Create(FunctionType::get(B.getVoidTy(), false),
  57. GlobalValue::ExternalLinkage, "F"));
  58. BasicBlock *Entry(BasicBlock::Create(C, "", F.get()));
  59. BasicBlock *BB(BasicBlock::Create(C, "", F.get()));
  60. BranchInst::Create(BB, Entry);
  61. B.SetInsertPoint(BB);
  62. AssertingVH<PHINode> P1 = B.CreatePHI(Type::getInt32Ty(C), 2);
  63. P1->addIncoming(B.getInt32(42), Entry);
  64. PHINode *P2 = B.CreatePHI(Type::getInt32Ty(C), 2);
  65. P2->addIncoming(B.getInt32(42), Entry);
  66. AssertingVH<PHINode> P3 = B.CreatePHI(Type::getInt32Ty(C), 2);
  67. P3->addIncoming(B.getInt32(42), Entry);
  68. P3->addIncoming(B.getInt32(23), BB);
  69. PHINode *P4 = B.CreatePHI(Type::getInt32Ty(C), 2);
  70. P4->addIncoming(B.getInt32(42), Entry);
  71. P4->addIncoming(B.getInt32(23), BB);
  72. P1->addIncoming(P3, BB);
  73. P2->addIncoming(P4, BB);
  74. BranchInst::Create(BB, BB);
  75. // Verify that we can eliminate PHIs that become duplicates after chaning PHIs
  76. // downstream.
  77. EXPECT_TRUE(EliminateDuplicatePHINodes(BB));
  78. EXPECT_EQ(3U, BB->size());
  79. }
  80. static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
  81. SMDiagnostic Err;
  82. std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
  83. if (!Mod)
  84. Err.print("UtilsTests", errs());
  85. return Mod;
  86. }
  87. TEST(Local, ReplaceDbgDeclare) {
  88. LLVMContext C;
  89. // Original C source to get debug info for a local variable:
  90. // void f() { int x; }
  91. std::unique_ptr<Module> M = parseIR(C,
  92. R"(
  93. define void @f() !dbg !8 {
  94. entry:
  95. %x = alloca i32, align 4
  96. call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata !DIExpression()), !dbg !13
  97. call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata !DIExpression()), !dbg !13
  98. ret void, !dbg !14
  99. }
  100. declare void @llvm.dbg.declare(metadata, metadata, metadata)
  101. !llvm.dbg.cu = !{!0}
  102. !llvm.module.flags = !{!3, !4}
  103. !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
  104. !1 = !DIFile(filename: "t2.c", directory: "foo")
  105. !2 = !{}
  106. !3 = !{i32 2, !"Dwarf Version", i32 4}
  107. !4 = !{i32 2, !"Debug Info Version", i32 3}
  108. !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)
  109. !9 = !DISubroutineType(types: !10)
  110. !10 = !{null}
  111. !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
  112. !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
  113. !13 = !DILocation(line: 2, column: 7, scope: !8)
  114. !14 = !DILocation(line: 3, column: 1, scope: !8)
  115. )");
  116. auto *GV = M->getNamedValue("f");
  117. ASSERT_TRUE(GV);
  118. auto *F = dyn_cast<Function>(GV);
  119. ASSERT_TRUE(F);
  120. Instruction *Inst = &F->front().front();
  121. auto *AI = dyn_cast<AllocaInst>(Inst);
  122. ASSERT_TRUE(AI);
  123. Inst = Inst->getNextNode()->getNextNode();
  124. ASSERT_TRUE(Inst);
  125. auto *DII = dyn_cast<DbgDeclareInst>(Inst);
  126. ASSERT_TRUE(DII);
  127. Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C));
  128. DIBuilder DIB(*M);
  129. replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::ApplyOffset, 0);
  130. // There should be exactly two dbg.declares.
  131. int Declares = 0;
  132. for (const Instruction &I : F->front())
  133. if (isa<DbgDeclareInst>(I))
  134. Declares++;
  135. EXPECT_EQ(2, Declares);
  136. }
  137. /// Build the dominator tree for the function and run the Test.
  138. static void runWithDomTree(
  139. Module &M, StringRef FuncName,
  140. function_ref<void(Function &F, DominatorTree *DT)> Test) {
  141. auto *F = M.getFunction(FuncName);
  142. ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
  143. // Compute the dominator tree for the function.
  144. DominatorTree DT(*F);
  145. Test(*F, &DT);
  146. }
  147. TEST(Local, MergeBasicBlockIntoOnlyPred) {
  148. LLVMContext C;
  149. std::unique_ptr<Module> M;
  150. auto resetIR = [&]() {
  151. M = parseIR(C,
  152. R"(
  153. define i32 @f(i8* %str) {
  154. entry:
  155. br label %bb2.i
  156. bb2.i: ; preds = %bb4.i, %entry
  157. br i1 false, label %bb4.i, label %base2flt.exit204
  158. bb4.i: ; preds = %bb2.i
  159. br i1 false, label %base2flt.exit204, label %bb2.i
  160. bb10.i196.bb7.i197_crit_edge: ; No predecessors!
  161. br label %bb7.i197
  162. bb7.i197: ; preds = %bb10.i196.bb7.i197_crit_edge
  163. %.reg2mem.0 = phi i32 [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ]
  164. br i1 undef, label %base2flt.exit204, label %base2flt.exit204
  165. base2flt.exit204: ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i
  166. ret i32 0
  167. }
  168. )");
  169. };
  170. auto resetIRReplaceEntry = [&]() {
  171. M = parseIR(C,
  172. R"(
  173. define i32 @f() {
  174. entry:
  175. br label %bb2.i
  176. bb2.i: ; preds = %entry
  177. ret i32 0
  178. }
  179. )");
  180. };
  181. auto Test = [&](Function &F, DomTreeUpdater &DTU) {
  182. for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
  183. BasicBlock *BB = &*I++;
  184. BasicBlock *SinglePred = BB->getSinglePredecessor();
  185. if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
  186. continue;
  187. BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator());
  188. if (Term && !Term->isConditional())
  189. MergeBasicBlockIntoOnlyPred(BB, &DTU);
  190. }
  191. if (DTU.hasDomTree()) {
  192. EXPECT_TRUE(DTU.getDomTree().verify());
  193. }
  194. if (DTU.hasPostDomTree()) {
  195. EXPECT_TRUE(DTU.getPostDomTree().verify());
  196. }
  197. };
  198. // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
  199. // both DT and PDT.
  200. resetIR();
  201. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  202. PostDominatorTree PDT = PostDominatorTree(F);
  203. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
  204. Test(F, DTU);
  205. });
  206. // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
  207. // DT.
  208. resetIR();
  209. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  210. DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Eager);
  211. Test(F, DTU);
  212. });
  213. // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
  214. // PDT.
  215. resetIR();
  216. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  217. PostDominatorTree PDT = PostDominatorTree(F);
  218. DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Eager);
  219. Test(F, DTU);
  220. });
  221. // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
  222. // both DT and PDT.
  223. resetIR();
  224. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  225. PostDominatorTree PDT = PostDominatorTree(F);
  226. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  227. Test(F, DTU);
  228. });
  229. // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
  230. // PDT.
  231. resetIR();
  232. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  233. PostDominatorTree PDT = PostDominatorTree(F);
  234. DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  235. Test(F, DTU);
  236. });
  237. // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with DT.
  238. resetIR();
  239. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  240. DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Lazy);
  241. Test(F, DTU);
  242. });
  243. // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
  244. // both DT and PDT.
  245. resetIRReplaceEntry();
  246. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  247. PostDominatorTree PDT = PostDominatorTree(F);
  248. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
  249. Test(F, DTU);
  250. });
  251. // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
  252. // DT.
  253. resetIRReplaceEntry();
  254. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  255. DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Eager);
  256. Test(F, DTU);
  257. });
  258. // Test MergeBasicBlockIntoOnlyPred working under Eager UpdateStrategy with
  259. // PDT.
  260. resetIRReplaceEntry();
  261. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  262. PostDominatorTree PDT = PostDominatorTree(F);
  263. DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Eager);
  264. Test(F, DTU);
  265. });
  266. // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
  267. // both DT and PDT.
  268. resetIRReplaceEntry();
  269. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  270. PostDominatorTree PDT = PostDominatorTree(F);
  271. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  272. Test(F, DTU);
  273. });
  274. // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with
  275. // PDT.
  276. resetIRReplaceEntry();
  277. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  278. PostDominatorTree PDT = PostDominatorTree(F);
  279. DomTreeUpdater DTU(PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  280. Test(F, DTU);
  281. });
  282. // Test MergeBasicBlockIntoOnlyPred working under Lazy UpdateStrategy with DT.
  283. resetIRReplaceEntry();
  284. runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
  285. DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Lazy);
  286. Test(F, DTU);
  287. });
  288. }
  289. TEST(Local, ConstantFoldTerminator) {
  290. LLVMContext C;
  291. std::unique_ptr<Module> M = parseIR(C,
  292. R"(
  293. define void @br_same_dest() {
  294. entry:
  295. br i1 false, label %bb0, label %bb0
  296. bb0:
  297. ret void
  298. }
  299. define void @br_different_dest() {
  300. entry:
  301. br i1 true, label %bb0, label %bb1
  302. bb0:
  303. br label %exit
  304. bb1:
  305. br label %exit
  306. exit:
  307. ret void
  308. }
  309. define void @switch_2_different_dest() {
  310. entry:
  311. switch i32 0, label %default [ i32 0, label %bb0 ]
  312. default:
  313. ret void
  314. bb0:
  315. ret void
  316. }
  317. define void @switch_2_different_dest_default() {
  318. entry:
  319. switch i32 1, label %default [ i32 0, label %bb0 ]
  320. default:
  321. ret void
  322. bb0:
  323. ret void
  324. }
  325. define void @switch_3_different_dest() {
  326. entry:
  327. switch i32 0, label %default [ i32 0, label %bb0
  328. i32 1, label %bb1 ]
  329. default:
  330. ret void
  331. bb0:
  332. ret void
  333. bb1:
  334. ret void
  335. }
  336. define void @switch_variable_2_default_dest(i32 %arg) {
  337. entry:
  338. switch i32 %arg, label %default [ i32 0, label %default ]
  339. default:
  340. ret void
  341. }
  342. define void @switch_constant_2_default_dest() {
  343. entry:
  344. switch i32 1, label %default [ i32 0, label %default ]
  345. default:
  346. ret void
  347. }
  348. define void @switch_constant_3_repeated_dest() {
  349. entry:
  350. switch i32 0, label %default [ i32 0, label %bb0
  351. i32 1, label %bb0 ]
  352. bb0:
  353. ret void
  354. default:
  355. ret void
  356. }
  357. define void @indirectbr() {
  358. entry:
  359. indirectbr i8* blockaddress(@indirectbr, %bb0), [label %bb0, label %bb1]
  360. bb0:
  361. ret void
  362. bb1:
  363. ret void
  364. }
  365. define void @indirectbr_repeated() {
  366. entry:
  367. indirectbr i8* blockaddress(@indirectbr_repeated, %bb0), [label %bb0, label %bb0]
  368. bb0:
  369. ret void
  370. }
  371. define void @indirectbr_unreachable() {
  372. entry:
  373. indirectbr i8* blockaddress(@indirectbr_unreachable, %bb0), [label %bb1]
  374. bb0:
  375. ret void
  376. bb1:
  377. ret void
  378. }
  379. )");
  380. auto CFAllTerminatorsEager = [&](Function &F, DominatorTree *DT) {
  381. PostDominatorTree PDT = PostDominatorTree(F);
  382. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
  383. for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
  384. BasicBlock *BB = &*I++;
  385. ConstantFoldTerminator(BB, true, nullptr, &DTU);
  386. }
  387. EXPECT_TRUE(DTU.getDomTree().verify());
  388. EXPECT_TRUE(DTU.getPostDomTree().verify());
  389. };
  390. auto CFAllTerminatorsLazy = [&](Function &F, DominatorTree *DT) {
  391. PostDominatorTree PDT = PostDominatorTree(F);
  392. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  393. for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
  394. BasicBlock *BB = &*I++;
  395. ConstantFoldTerminator(BB, true, nullptr, &DTU);
  396. }
  397. EXPECT_TRUE(DTU.getDomTree().verify());
  398. EXPECT_TRUE(DTU.getPostDomTree().verify());
  399. };
  400. // Test ConstantFoldTerminator under Eager UpdateStrategy.
  401. runWithDomTree(*M, "br_same_dest", CFAllTerminatorsEager);
  402. runWithDomTree(*M, "br_different_dest", CFAllTerminatorsEager);
  403. runWithDomTree(*M, "switch_2_different_dest", CFAllTerminatorsEager);
  404. runWithDomTree(*M, "switch_2_different_dest_default", CFAllTerminatorsEager);
  405. runWithDomTree(*M, "switch_3_different_dest", CFAllTerminatorsEager);
  406. runWithDomTree(*M, "switch_variable_2_default_dest", CFAllTerminatorsEager);
  407. runWithDomTree(*M, "switch_constant_2_default_dest", CFAllTerminatorsEager);
  408. runWithDomTree(*M, "switch_constant_3_repeated_dest", CFAllTerminatorsEager);
  409. runWithDomTree(*M, "indirectbr", CFAllTerminatorsEager);
  410. runWithDomTree(*M, "indirectbr_repeated", CFAllTerminatorsEager);
  411. runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminatorsEager);
  412. // Test ConstantFoldTerminator under Lazy UpdateStrategy.
  413. runWithDomTree(*M, "br_same_dest", CFAllTerminatorsLazy);
  414. runWithDomTree(*M, "br_different_dest", CFAllTerminatorsLazy);
  415. runWithDomTree(*M, "switch_2_different_dest", CFAllTerminatorsLazy);
  416. runWithDomTree(*M, "switch_2_different_dest_default", CFAllTerminatorsLazy);
  417. runWithDomTree(*M, "switch_3_different_dest", CFAllTerminatorsLazy);
  418. runWithDomTree(*M, "switch_variable_2_default_dest", CFAllTerminatorsLazy);
  419. runWithDomTree(*M, "switch_constant_2_default_dest", CFAllTerminatorsLazy);
  420. runWithDomTree(*M, "switch_constant_3_repeated_dest", CFAllTerminatorsLazy);
  421. runWithDomTree(*M, "indirectbr", CFAllTerminatorsLazy);
  422. runWithDomTree(*M, "indirectbr_repeated", CFAllTerminatorsLazy);
  423. runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminatorsLazy);
  424. }
  425. struct SalvageDebugInfoTest : ::testing::Test {
  426. LLVMContext C;
  427. std::unique_ptr<Module> M;
  428. Function *F = nullptr;
  429. void SetUp() {
  430. M = parseIR(C,
  431. R"(
  432. define void @f() !dbg !8 {
  433. entry:
  434. %x = add i32 0, 1
  435. %y = add i32 %x, 2
  436. call void @llvm.dbg.value(metadata i32 %x, metadata !11, metadata !DIExpression()), !dbg !13
  437. call void @llvm.dbg.value(metadata i32 %y, metadata !11, metadata !DIExpression()), !dbg !13
  438. ret void, !dbg !14
  439. }
  440. declare void @llvm.dbg.value(metadata, metadata, metadata)
  441. !llvm.dbg.cu = !{!0}
  442. !llvm.module.flags = !{!3, !4}
  443. !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
  444. !1 = !DIFile(filename: "t2.c", directory: "foo")
  445. !2 = !{}
  446. !3 = !{i32 2, !"Dwarf Version", i32 4}
  447. !4 = !{i32 2, !"Debug Info Version", i32 3}
  448. !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)
  449. !9 = !DISubroutineType(types: !10)
  450. !10 = !{null}
  451. !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
  452. !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
  453. !13 = !DILocation(line: 2, column: 7, scope: !8)
  454. !14 = !DILocation(line: 3, column: 1, scope: !8)
  455. )");
  456. auto *GV = M->getNamedValue("f");
  457. ASSERT_TRUE(GV);
  458. F = dyn_cast<Function>(GV);
  459. ASSERT_TRUE(F);
  460. }
  461. bool doesDebugValueDescribeX(const DbgValueInst &DI) {
  462. const auto &CI = *cast<ConstantInt>(DI.getValue());
  463. if (CI.isZero())
  464. return DI.getExpression()->getElements().equals(
  465. {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value});
  466. else if (CI.isOneValue())
  467. return DI.getExpression()->getElements().empty();
  468. return false;
  469. }
  470. bool doesDebugValueDescribeY(const DbgValueInst &DI) {
  471. const auto &CI = *cast<ConstantInt>(DI.getValue());
  472. if (CI.isZero())
  473. return DI.getExpression()->getElements().equals(
  474. {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2,
  475. dwarf::DW_OP_stack_value});
  476. else if (CI.isOneValue())
  477. return DI.getExpression()->getElements().equals(
  478. {dwarf::DW_OP_plus_uconst, 2, dwarf::DW_OP_stack_value});
  479. return false;
  480. }
  481. void verifyDebugValuesAreSalvaged() {
  482. // Check that the debug values for %x and %y are preserved.
  483. bool FoundX = false;
  484. bool FoundY = false;
  485. for (const Instruction &I : F->front()) {
  486. auto DI = dyn_cast<DbgValueInst>(&I);
  487. if (!DI) {
  488. // The function should only contain debug values and a terminator.
  489. ASSERT_TRUE(I.isTerminator());
  490. continue;
  491. }
  492. EXPECT_EQ(DI->getVariable()->getName(), "x");
  493. FoundX |= doesDebugValueDescribeX(*DI);
  494. FoundY |= doesDebugValueDescribeY(*DI);
  495. }
  496. ASSERT_TRUE(FoundX);
  497. ASSERT_TRUE(FoundY);
  498. }
  499. };
  500. TEST_F(SalvageDebugInfoTest, RecursiveInstDeletion) {
  501. Instruction *Inst = &F->front().front();
  502. Inst = Inst->getNextNode(); // Get %y = add ...
  503. ASSERT_TRUE(Inst);
  504. bool Deleted = RecursivelyDeleteTriviallyDeadInstructions(Inst);
  505. ASSERT_TRUE(Deleted);
  506. verifyDebugValuesAreSalvaged();
  507. }
  508. TEST_F(SalvageDebugInfoTest, RecursiveBlockSimplification) {
  509. BasicBlock *BB = &F->front();
  510. ASSERT_TRUE(BB);
  511. bool Deleted = SimplifyInstructionsInBlock(BB);
  512. ASSERT_TRUE(Deleted);
  513. verifyDebugValuesAreSalvaged();
  514. }
  515. TEST(Local, ChangeToUnreachable) {
  516. LLVMContext Ctx;
  517. std::unique_ptr<Module> M = parseIR(Ctx,
  518. R"(
  519. define internal void @foo() !dbg !6 {
  520. entry:
  521. ret void, !dbg !8
  522. }
  523. !llvm.dbg.cu = !{!0}
  524. !llvm.debugify = !{!3, !4}
  525. !llvm.module.flags = !{!5}
  526. !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
  527. !1 = !DIFile(filename: "test.ll", directory: "/")
  528. !2 = !{}
  529. !3 = !{i32 1}
  530. !4 = !{i32 0}
  531. !5 = !{i32 2, !"Debug Info Version", i32 3}
  532. !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)
  533. !7 = !DISubroutineType(types: !2)
  534. !8 = !DILocation(line: 1, column: 1, scope: !6)
  535. )");
  536. bool BrokenDebugInfo = true;
  537. verifyModule(*M, &errs(), &BrokenDebugInfo);
  538. ASSERT_FALSE(BrokenDebugInfo);
  539. Function &F = *cast<Function>(M->getNamedValue("foo"));
  540. BasicBlock &BB = F.front();
  541. Instruction &A = BB.front();
  542. DebugLoc DLA = A.getDebugLoc();
  543. ASSERT_TRUE(isa<ReturnInst>(&A));
  544. // One instruction should be affected.
  545. EXPECT_EQ(changeToUnreachable(&A, /*UseLLVMTrap*/false), 1U);
  546. Instruction &B = BB.front();
  547. // There should be an uncreachable instruction.
  548. ASSERT_TRUE(isa<UnreachableInst>(&B));
  549. DebugLoc DLB = B.getDebugLoc();
  550. EXPECT_EQ(DLA, DLB);
  551. }
  552. TEST(Local, ReplaceAllDbgUsesWith) {
  553. using namespace llvm::dwarf;
  554. LLVMContext Ctx;
  555. // Note: The datalayout simulates Darwin/x86_64.
  556. std::unique_ptr<Module> M = parseIR(Ctx,
  557. R"(
  558. target datalayout = "e-m:o-i63:64-f80:128-n8:16:32:64-S128"
  559. declare i32 @escape(i32)
  560. define void @f() !dbg !6 {
  561. entry:
  562. %a = add i32 0, 1, !dbg !15
  563. call void @llvm.dbg.value(metadata i32 %a, metadata !9, metadata !DIExpression()), !dbg !15
  564. %b = add i64 0, 1, !dbg !16
  565. call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression()), !dbg !16
  566. call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul)), !dbg !16
  567. call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_lit0, DW_OP_mul, DW_OP_stack_value)), !dbg !16
  568. call void @llvm.dbg.value(metadata i64 %b, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 8)), !dbg !16
  569. 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
  570. 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
  571. %c = inttoptr i64 0 to i64*, !dbg !17
  572. call void @llvm.dbg.declare(metadata i64* %c, metadata !13, metadata !DIExpression()), !dbg !17
  573. %d = inttoptr i64 0 to i32*, !dbg !18
  574. call void @llvm.dbg.addr(metadata i32* %d, metadata !20, metadata !DIExpression()), !dbg !18
  575. %e = add <2 x i16> zeroinitializer, zeroinitializer
  576. call void @llvm.dbg.value(metadata <2 x i16> %e, metadata !14, metadata !DIExpression()), !dbg !18
  577. %f = call i32 @escape(i32 0)
  578. call void @llvm.dbg.value(metadata i32 %f, metadata !9, metadata !DIExpression()), !dbg !15
  579. %barrier = call i32 @escape(i32 0)
  580. %g = call i32 @escape(i32 %f)
  581. call void @llvm.dbg.value(metadata i32 %g, metadata !9, metadata !DIExpression()), !dbg !15
  582. ret void, !dbg !19
  583. }
  584. declare void @llvm.dbg.addr(metadata, metadata, metadata)
  585. declare void @llvm.dbg.declare(metadata, metadata, metadata)
  586. declare void @llvm.dbg.value(metadata, metadata, metadata)
  587. !llvm.dbg.cu = !{!0}
  588. !llvm.module.flags = !{!5}
  589. !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
  590. !1 = !DIFile(filename: "/Users/vsk/Desktop/foo.ll", directory: "/")
  591. !2 = !{}
  592. !5 = !{i32 2, !"Debug Info Version", i32 3}
  593. !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)
  594. !7 = !DISubroutineType(types: !2)
  595. !8 = !{!9, !11, !13, !14}
  596. !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
  597. !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed)
  598. !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12)
  599. !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed)
  600. !13 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !12)
  601. !14 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 4, type: !10)
  602. !15 = !DILocation(line: 1, column: 1, scope: !6)
  603. !16 = !DILocation(line: 2, column: 1, scope: !6)
  604. !17 = !DILocation(line: 3, column: 1, scope: !6)
  605. !18 = !DILocation(line: 4, column: 1, scope: !6)
  606. !19 = !DILocation(line: 5, column: 1, scope: !6)
  607. !20 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 5, type: !10)
  608. )");
  609. bool BrokenDebugInfo = true;
  610. verifyModule(*M, &errs(), &BrokenDebugInfo);
  611. ASSERT_FALSE(BrokenDebugInfo);
  612. Function &F = *cast<Function>(M->getNamedValue("f"));
  613. DominatorTree DT{F};
  614. BasicBlock &BB = F.front();
  615. Instruction &A = BB.front();
  616. Instruction &B = *A.getNextNonDebugInstruction();
  617. Instruction &C = *B.getNextNonDebugInstruction();
  618. Instruction &D = *C.getNextNonDebugInstruction();
  619. Instruction &E = *D.getNextNonDebugInstruction();
  620. Instruction &F_ = *E.getNextNonDebugInstruction();
  621. Instruction &Barrier = *F_.getNextNonDebugInstruction();
  622. Instruction &G = *Barrier.getNextNonDebugInstruction();
  623. // Simulate i32 <-> i64* conversion. Expect no updates: the datalayout says
  624. // pointers are 64 bits, so the conversion would be lossy.
  625. EXPECT_FALSE(replaceAllDbgUsesWith(A, C, C, DT));
  626. EXPECT_FALSE(replaceAllDbgUsesWith(C, A, A, DT));
  627. // Simulate i32 <-> <2 x i16> conversion. This is unsupported.
  628. EXPECT_FALSE(replaceAllDbgUsesWith(E, A, A, DT));
  629. EXPECT_FALSE(replaceAllDbgUsesWith(A, E, E, DT));
  630. // Simulate i32* <-> i64* conversion.
  631. EXPECT_TRUE(replaceAllDbgUsesWith(D, C, C, DT));
  632. SmallVector<DbgVariableIntrinsic *, 2> CDbgVals;
  633. findDbgUsers(CDbgVals, &C);
  634. EXPECT_EQ(2U, CDbgVals.size());
  635. EXPECT_TRUE(any_of(CDbgVals, [](DbgVariableIntrinsic *DII) {
  636. return isa<DbgAddrIntrinsic>(DII);
  637. }));
  638. EXPECT_TRUE(any_of(CDbgVals, [](DbgVariableIntrinsic *DII) {
  639. return isa<DbgDeclareInst>(DII);
  640. }));
  641. EXPECT_TRUE(replaceAllDbgUsesWith(C, D, D, DT));
  642. SmallVector<DbgVariableIntrinsic *, 2> DDbgVals;
  643. findDbgUsers(DDbgVals, &D);
  644. EXPECT_EQ(2U, DDbgVals.size());
  645. EXPECT_TRUE(any_of(DDbgVals, [](DbgVariableIntrinsic *DII) {
  646. return isa<DbgAddrIntrinsic>(DII);
  647. }));
  648. EXPECT_TRUE(any_of(DDbgVals, [](DbgVariableIntrinsic *DII) {
  649. return isa<DbgDeclareInst>(DII);
  650. }));
  651. // Introduce a use-before-def. Check that the dbg.value for %a is salvaged.
  652. EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT));
  653. auto *ADbgVal = cast<DbgValueInst>(A.getNextNode());
  654. EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocation());
  655. // Introduce a use-before-def. Check that the dbg.values for %f are deleted.
  656. EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT));
  657. SmallVector<DbgValueInst *, 1> FDbgVals;
  658. findDbgValues(FDbgVals, &F);
  659. EXPECT_EQ(0U, FDbgVals.size());
  660. // Simulate i32 -> i64 conversion to test sign-extension. Here are some
  661. // interesting cases to handle:
  662. // 1) debug user has empty DIExpression
  663. // 2) debug user has non-empty, non-stack-value'd DIExpression
  664. // 3) debug user has non-empty, stack-value'd DIExpression
  665. // 4-6) like (1-3), but with a fragment
  666. EXPECT_TRUE(replaceAllDbgUsesWith(B, A, A, DT));
  667. SmallVector<DbgValueInst *, 8> ADbgVals;
  668. findDbgValues(ADbgVals, &A);
  669. EXPECT_EQ(6U, ADbgVals.size());
  670. // Check that %a has a dbg.value with a DIExpression matching \p Ops.
  671. auto hasADbgVal = [&](ArrayRef<uint64_t> Ops) {
  672. return any_of(ADbgVals, [&](DbgValueInst *DVI) {
  673. assert(DVI->getVariable()->getName() == "2");
  674. return DVI->getExpression()->getElements() == Ops;
  675. });
  676. };
  677. // Case 1: The original expr is empty, so no deref is needed.
  678. EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
  679. DW_OP_LLVM_convert, 64, DW_ATE_signed,
  680. DW_OP_stack_value}));
  681. // Case 2: Perform an address calculation with the original expr, deref it,
  682. // then sign-extend the result.
  683. EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
  684. DW_OP_LLVM_convert, 32, DW_ATE_signed,
  685. DW_OP_LLVM_convert, 64, DW_ATE_signed,
  686. DW_OP_stack_value}));
  687. // Case 3: Insert the sign-extension logic before the DW_OP_stack_value.
  688. EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
  689. DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
  690. DW_OP_stack_value}));
  691. // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end.
  692. EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
  693. DW_OP_LLVM_convert, 64, DW_ATE_signed,
  694. DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
  695. EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
  696. DW_OP_LLVM_convert, 32, DW_ATE_signed,
  697. DW_OP_LLVM_convert, 64, DW_ATE_signed,
  698. DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
  699. EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
  700. DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
  701. DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
  702. verifyModule(*M, &errs(), &BrokenDebugInfo);
  703. ASSERT_FALSE(BrokenDebugInfo);
  704. }
  705. TEST(Local, RemoveUnreachableBlocks) {
  706. LLVMContext C;
  707. std::unique_ptr<Module> M = parseIR(C,
  708. R"(
  709. define void @br_simple() {
  710. entry:
  711. br label %bb0
  712. bb0:
  713. ret void
  714. bb1:
  715. ret void
  716. }
  717. define void @br_self_loop() {
  718. entry:
  719. br label %bb0
  720. bb0:
  721. br i1 true, label %bb1, label %bb0
  722. bb1:
  723. br i1 true, label %bb0, label %bb2
  724. bb2:
  725. br label %bb2
  726. }
  727. define void @br_constant() {
  728. entry:
  729. br label %bb0
  730. bb0:
  731. br i1 true, label %bb1, label %bb2
  732. bb1:
  733. br i1 true, label %bb0, label %bb2
  734. bb2:
  735. br label %bb2
  736. }
  737. define void @br_loop() {
  738. entry:
  739. br label %bb0
  740. bb0:
  741. br label %bb0
  742. bb1:
  743. br label %bb2
  744. bb2:
  745. br label %bb1
  746. }
  747. declare i32 @__gxx_personality_v0(...)
  748. define void @invoke_terminator() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
  749. entry:
  750. br i1 undef, label %invoke.block, label %exit
  751. invoke.block:
  752. %cond = invoke zeroext i1 @invokable()
  753. to label %continue.block unwind label %lpad.block
  754. continue.block:
  755. br i1 %cond, label %if.then, label %if.end
  756. if.then:
  757. unreachable
  758. if.end:
  759. unreachable
  760. lpad.block:
  761. %lp = landingpad { i8*, i32 }
  762. catch i8* null
  763. br label %exit
  764. exit:
  765. ret void
  766. }
  767. declare i1 @invokable()
  768. )");
  769. auto runEager = [&](Function &F, DominatorTree *DT) {
  770. PostDominatorTree PDT = PostDominatorTree(F);
  771. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
  772. removeUnreachableBlocks(F, &DTU);
  773. EXPECT_TRUE(DTU.getDomTree().verify());
  774. EXPECT_TRUE(DTU.getPostDomTree().verify());
  775. };
  776. auto runLazy = [&](Function &F, DominatorTree *DT) {
  777. PostDominatorTree PDT = PostDominatorTree(F);
  778. DomTreeUpdater DTU(*DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  779. removeUnreachableBlocks(F, &DTU);
  780. EXPECT_TRUE(DTU.getDomTree().verify());
  781. EXPECT_TRUE(DTU.getPostDomTree().verify());
  782. };
  783. // Test removeUnreachableBlocks under Eager UpdateStrategy.
  784. runWithDomTree(*M, "br_simple", runEager);
  785. runWithDomTree(*M, "br_self_loop", runEager);
  786. runWithDomTree(*M, "br_constant", runEager);
  787. runWithDomTree(*M, "br_loop", runEager);
  788. runWithDomTree(*M, "invoke_terminator", runEager);
  789. // Test removeUnreachableBlocks under Lazy UpdateStrategy.
  790. runWithDomTree(*M, "br_simple", runLazy);
  791. runWithDomTree(*M, "br_self_loop", runLazy);
  792. runWithDomTree(*M, "br_constant", runLazy);
  793. runWithDomTree(*M, "br_loop", runLazy);
  794. runWithDomTree(*M, "invoke_terminator", runLazy);
  795. M = parseIR(C,
  796. R"(
  797. define void @f() {
  798. entry:
  799. ret void
  800. bb0:
  801. ret void
  802. }
  803. )");
  804. auto checkRUBlocksRetVal = [&](Function &F, DominatorTree *DT) {
  805. DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
  806. EXPECT_TRUE(removeUnreachableBlocks(F, &DTU));
  807. EXPECT_FALSE(removeUnreachableBlocks(F, &DTU));
  808. EXPECT_TRUE(DTU.getDomTree().verify());
  809. };
  810. runWithDomTree(*M, "f", checkRUBlocksRetVal);
  811. }