1 //===- BasicBlockUtils.cpp - Unit tests for BasicBlockUtils ---------------===// 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/BasicBlockUtils.h" 10 #include "llvm/Analysis/PostDominators.h" 11 #include "llvm/AsmParser/Parser.h" 12 #include "llvm/IR/BasicBlock.h" 13 #include "llvm/IR/Dominators.h" 14 #include "llvm/IR/LLVMContext.h" 15 #include "llvm/Support/SourceMgr.h" 16 #include "gtest/gtest.h" 17 18 using namespace llvm; 19 20 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { 21 SMDiagnostic Err; 22 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); 23 if (!Mod) 24 Err.print("BasicBlockUtilsTests", errs()); 25 return Mod; 26 } 27 28 TEST(BasicBlockUtils, EliminateUnreachableBlocks) { 29 LLVMContext C; 30 31 std::unique_ptr<Module> M = parseIR( 32 C, 33 "define i32 @has_unreachable(i1 %cond) {\n" 34 "entry:\n" 35 " br i1 %cond, label %bb0, label %bb1\n" 36 "bb0:\n" 37 " br label %bb1\n" 38 "bb1:\n" 39 " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]" 40 " ret i32 %phi\n" 41 "bb2:\n" 42 " ret i32 42\n" 43 "}\n" 44 "\n" 45 ); 46 47 auto *F = M->getFunction("has_unreachable"); 48 DominatorTree DT(*F); 49 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); 50 51 EXPECT_EQ(F->size(), (size_t)4); 52 bool Result = EliminateUnreachableBlocks(*F, &DTU); 53 EXPECT_TRUE(Result); 54 EXPECT_EQ(F->size(), (size_t)3); 55 EXPECT_TRUE(DT.verify()); 56 } 57 58 TEST(BasicBlockUtils, NoUnreachableBlocksToEliminate) { 59 LLVMContext C; 60 61 std::unique_ptr<Module> M = parseIR( 62 C, 63 "define i32 @no_unreachable(i1 %cond) {\n" 64 "entry:\n" 65 " br i1 %cond, label %bb0, label %bb1\n" 66 "bb0:\n" 67 " br label %bb1\n" 68 "bb1:\n" 69 " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]" 70 " ret i32 %phi\n" 71 "}\n" 72 "\n" 73 ); 74 75 auto *F = M->getFunction("no_unreachable"); 76 DominatorTree DT(*F); 77 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); 78 79 EXPECT_EQ(F->size(), (size_t)3); 80 bool Result = EliminateUnreachableBlocks(*F, &DTU); 81 EXPECT_FALSE(Result); 82 EXPECT_EQ(F->size(), (size_t)3); 83 EXPECT_TRUE(DT.verify()); 84 } 85 86 TEST(BasicBlockUtils, SplitBlockPredecessors) { 87 LLVMContext C; 88 89 std::unique_ptr<Module> M = parseIR( 90 C, 91 "define i32 @basic_func(i1 %cond) {\n" 92 "entry:\n" 93 " br i1 %cond, label %bb0, label %bb1\n" 94 "bb0:\n" 95 " br label %bb1\n" 96 "bb1:\n" 97 " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]" 98 " ret i32 %phi\n" 99 "}\n" 100 "\n" 101 ); 102 103 auto *F = M->getFunction("basic_func"); 104 DominatorTree DT(*F); 105 106 // Make sure the dominator tree is properly updated if calling this on the 107 // entry block. 108 SplitBlockPredecessors(&F->getEntryBlock(), {}, "split.entry", &DT); 109 EXPECT_TRUE(DT.verify()); 110 } 111 112 TEST(BasicBlockUtils, SplitCriticalEdge) { 113 LLVMContext C; 114 115 std::unique_ptr<Module> M = parseIR( 116 C, 117 "define void @crit_edge(i1 %cond0, i1 %cond1) {\n" 118 "entry:\n" 119 " br i1 %cond0, label %bb0, label %bb1\n" 120 "bb0:\n" 121 " br label %bb1\n" 122 "bb1:\n" 123 " br label %bb2\n" 124 "bb2:\n" 125 " ret void\n" 126 "}\n" 127 "\n" 128 ); 129 130 auto *F = M->getFunction("crit_edge"); 131 DominatorTree DT(*F); 132 PostDominatorTree PDT(*F); 133 134 CriticalEdgeSplittingOptions CESO(&DT, nullptr, nullptr, &PDT); 135 EXPECT_EQ(1u, SplitAllCriticalEdges(*F, CESO)); 136 EXPECT_TRUE(DT.verify()); 137 EXPECT_TRUE(PDT.verify()); 138 } 139