CFGTest.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. //===- CFGTest.cpp - CFG tests --------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/Analysis/CFG.h"
  10. #include "llvm/Analysis/LoopInfo.h"
  11. #include "llvm/AsmParser/Parser.h"
  12. #include "llvm/IR/Dominators.h"
  13. #include "llvm/IR/Function.h"
  14. #include "llvm/IR/InstIterator.h"
  15. #include "llvm/IR/LLVMContext.h"
  16. #include "llvm/IR/Module.h"
  17. #include "llvm/Pass.h"
  18. #include "llvm/IR/LegacyPassManager.h"
  19. #include "llvm/Support/ErrorHandling.h"
  20. #include "llvm/Support/SourceMgr.h"
  21. #include "gtest/gtest.h"
  22. using namespace llvm;
  23. namespace {
  24. // This fixture assists in running the isPotentiallyReachable utility four ways
  25. // and ensuring it produces the correct answer each time.
  26. class IsPotentiallyReachableTest : public testing::Test {
  27. protected:
  28. void ParseAssembly(const char *Assembly) {
  29. SMDiagnostic Error;
  30. M = parseAssemblyString(Assembly, Error, getGlobalContext());
  31. std::string errMsg;
  32. raw_string_ostream os(errMsg);
  33. Error.print("", os);
  34. // A failure here means that the test itself is buggy.
  35. if (!M)
  36. report_fatal_error(os.str().c_str());
  37. Function *F = M->getFunction("test");
  38. if (F == nullptr)
  39. report_fatal_error("Test must have a function named @test");
  40. A = B = nullptr;
  41. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
  42. if (I->hasName()) {
  43. if (I->getName() == "A")
  44. A = &*I;
  45. else if (I->getName() == "B")
  46. B = &*I;
  47. }
  48. }
  49. if (A == nullptr)
  50. report_fatal_error("@test must have an instruction %A");
  51. if (B == nullptr)
  52. report_fatal_error("@test must have an instruction %B");
  53. }
  54. void ExpectPath(bool ExpectedResult) {
  55. static char ID;
  56. class IsPotentiallyReachableTestPass : public FunctionPass {
  57. public:
  58. IsPotentiallyReachableTestPass(bool ExpectedResult,
  59. Instruction *A, Instruction *B)
  60. : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {}
  61. static int initialize() {
  62. PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
  63. "", &ID, nullptr, true, true);
  64. PassRegistry::getPassRegistry()->registerPass(*PI, false);
  65. initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
  66. initializeDominatorTreeWrapperPassPass(
  67. *PassRegistry::getPassRegistry());
  68. return 0;
  69. }
  70. void getAnalysisUsage(AnalysisUsage &AU) const override {
  71. AU.setPreservesAll();
  72. AU.addRequired<LoopInfoWrapperPass>();
  73. AU.addRequired<DominatorTreeWrapperPass>();
  74. }
  75. bool runOnFunction(Function &F) override {
  76. if (!F.hasName() || F.getName() != "test")
  77. return false;
  78. LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
  79. DominatorTree *DT =
  80. &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  81. EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
  82. ExpectedResult);
  83. EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult);
  84. EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult);
  85. EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
  86. return false;
  87. }
  88. bool ExpectedResult;
  89. Instruction *A, *B;
  90. };
  91. static int initialize = IsPotentiallyReachableTestPass::initialize();
  92. (void)initialize;
  93. IsPotentiallyReachableTestPass *P =
  94. new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
  95. legacy::PassManager PM;
  96. PM.add(P);
  97. PM.run(*M);
  98. }
  99. std::unique_ptr<Module> M;
  100. Instruction *A, *B;
  101. };
  102. }
  103. TEST_F(IsPotentiallyReachableTest, SameBlockNoPath) {
  104. ParseAssembly(
  105. "define void @test() {\n"
  106. "entry:\n"
  107. " bitcast i8 undef to i8\n"
  108. " %B = bitcast i8 undef to i8\n"
  109. " bitcast i8 undef to i8\n"
  110. " bitcast i8 undef to i8\n"
  111. " %A = bitcast i8 undef to i8\n"
  112. " ret void\n"
  113. "}\n");
  114. ExpectPath(false);
  115. }
  116. TEST_F(IsPotentiallyReachableTest, SameBlockPath) {
  117. ParseAssembly(
  118. "define void @test() {\n"
  119. "entry:\n"
  120. " %A = bitcast i8 undef to i8\n"
  121. " bitcast i8 undef to i8\n"
  122. " bitcast i8 undef to i8\n"
  123. " %B = bitcast i8 undef to i8\n"
  124. " ret void\n"
  125. "}\n");
  126. ExpectPath(true);
  127. }
  128. TEST_F(IsPotentiallyReachableTest, SameBlockNoLoop) {
  129. ParseAssembly(
  130. "define void @test() {\n"
  131. "entry:\n"
  132. " br label %middle\n"
  133. "middle:\n"
  134. " %B = bitcast i8 undef to i8\n"
  135. " bitcast i8 undef to i8\n"
  136. " bitcast i8 undef to i8\n"
  137. " %A = bitcast i8 undef to i8\n"
  138. " br label %nextblock\n"
  139. "nextblock:\n"
  140. " ret void\n"
  141. "}\n");
  142. ExpectPath(false);
  143. }
  144. TEST_F(IsPotentiallyReachableTest, StraightNoPath) {
  145. ParseAssembly(
  146. "define void @test() {\n"
  147. "entry:\n"
  148. " %B = bitcast i8 undef to i8\n"
  149. " br label %exit\n"
  150. "exit:\n"
  151. " %A = bitcast i8 undef to i8\n"
  152. " ret void\n"
  153. "}");
  154. ExpectPath(false);
  155. }
  156. TEST_F(IsPotentiallyReachableTest, StraightPath) {
  157. ParseAssembly(
  158. "define void @test() {\n"
  159. "entry:\n"
  160. " %A = bitcast i8 undef to i8\n"
  161. " br label %exit\n"
  162. "exit:\n"
  163. " %B = bitcast i8 undef to i8\n"
  164. " ret void\n"
  165. "}");
  166. ExpectPath(true);
  167. }
  168. TEST_F(IsPotentiallyReachableTest, DestUnreachable) {
  169. ParseAssembly(
  170. "define void @test() {\n"
  171. "entry:\n"
  172. " br label %midblock\n"
  173. "midblock:\n"
  174. " %A = bitcast i8 undef to i8\n"
  175. " ret void\n"
  176. "unreachable:\n"
  177. " %B = bitcast i8 undef to i8\n"
  178. " br label %midblock\n"
  179. "}");
  180. ExpectPath(false);
  181. }
  182. TEST_F(IsPotentiallyReachableTest, BranchToReturn) {
  183. ParseAssembly(
  184. "define void @test(i1 %x) {\n"
  185. "entry:\n"
  186. " %A = bitcast i8 undef to i8\n"
  187. " br i1 %x, label %block1, label %block2\n"
  188. "block1:\n"
  189. " ret void\n"
  190. "block2:\n"
  191. " %B = bitcast i8 undef to i8\n"
  192. " ret void\n"
  193. "}");
  194. ExpectPath(true);
  195. }
  196. TEST_F(IsPotentiallyReachableTest, SimpleLoop1) {
  197. ParseAssembly(
  198. "declare i1 @switch()\n"
  199. "\n"
  200. "define void @test() {\n"
  201. "entry:\n"
  202. " br label %loop\n"
  203. "loop:\n"
  204. " %B = bitcast i8 undef to i8\n"
  205. " %A = bitcast i8 undef to i8\n"
  206. " %x = call i1 @switch()\n"
  207. " br i1 %x, label %loop, label %exit\n"
  208. "exit:\n"
  209. " ret void\n"
  210. "}");
  211. ExpectPath(true);
  212. }
  213. TEST_F(IsPotentiallyReachableTest, SimpleLoop2) {
  214. ParseAssembly(
  215. "declare i1 @switch()\n"
  216. "\n"
  217. "define void @test() {\n"
  218. "entry:\n"
  219. " %B = bitcast i8 undef to i8\n"
  220. " br label %loop\n"
  221. "loop:\n"
  222. " %A = bitcast i8 undef to i8\n"
  223. " %x = call i1 @switch()\n"
  224. " br i1 %x, label %loop, label %exit\n"
  225. "exit:\n"
  226. " ret void\n"
  227. "}");
  228. ExpectPath(false);
  229. }
  230. TEST_F(IsPotentiallyReachableTest, SimpleLoop3) {
  231. ParseAssembly(
  232. "declare i1 @switch()\n"
  233. "\n"
  234. "define void @test() {\n"
  235. "entry:\n"
  236. " br label %loop\n"
  237. "loop:\n"
  238. " %B = bitcast i8 undef to i8\n"
  239. " %x = call i1 @switch()\n"
  240. " br i1 %x, label %loop, label %exit\n"
  241. "exit:\n"
  242. " %A = bitcast i8 undef to i8\n"
  243. " ret void\n"
  244. "}");
  245. ExpectPath(false);
  246. }
  247. TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther1) {
  248. ParseAssembly(
  249. "declare i1 @switch()\n"
  250. "\n"
  251. "define void @test() {\n"
  252. "entry:\n"
  253. " br label %loop1\n"
  254. "loop1:\n"
  255. " %A = bitcast i8 undef to i8\n"
  256. " %x = call i1 @switch()\n"
  257. " br i1 %x, label %loop1, label %loop1exit\n"
  258. "loop1exit:\n"
  259. " br label %loop2\n"
  260. "loop2:\n"
  261. " %B = bitcast i8 undef to i8\n"
  262. " %y = call i1 @switch()\n"
  263. " br i1 %x, label %loop2, label %loop2exit\n"
  264. "loop2exit:"
  265. " ret void\n"
  266. "}");
  267. ExpectPath(true);
  268. }
  269. TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther2) {
  270. ParseAssembly(
  271. "declare i1 @switch()\n"
  272. "\n"
  273. "define void @test() {\n"
  274. "entry:\n"
  275. " br label %loop1\n"
  276. "loop1:\n"
  277. " %B = bitcast i8 undef to i8\n"
  278. " %x = call i1 @switch()\n"
  279. " br i1 %x, label %loop1, label %loop1exit\n"
  280. "loop1exit:\n"
  281. " br label %loop2\n"
  282. "loop2:\n"
  283. " %A = bitcast i8 undef to i8\n"
  284. " %y = call i1 @switch()\n"
  285. " br i1 %x, label %loop2, label %loop2exit\n"
  286. "loop2exit:"
  287. " ret void\n"
  288. "}");
  289. ExpectPath(false);
  290. }
  291. TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
  292. ParseAssembly(
  293. "declare i1 @switch()\n"
  294. "\n"
  295. "define void @test() {\n"
  296. "entry:\n"
  297. " br label %outerloop3\n"
  298. "outerloop3:\n"
  299. " br label %innerloop1\n"
  300. "innerloop1:\n"
  301. " %B = bitcast i8 undef to i8\n"
  302. " %x = call i1 @switch()\n"
  303. " br i1 %x, label %innerloop1, label %innerloop1exit\n"
  304. "innerloop1exit:\n"
  305. " br label %innerloop2\n"
  306. "innerloop2:\n"
  307. " %A = bitcast i8 undef to i8\n"
  308. " %y = call i1 @switch()\n"
  309. " br i1 %x, label %innerloop2, label %innerloop2exit\n"
  310. "innerloop2exit:"
  311. " ;; In outer loop3 now.\n"
  312. " %z = call i1 @switch()\n"
  313. " br i1 %z, label %outerloop3, label %exit\n"
  314. "exit:\n"
  315. " ret void\n"
  316. "}");
  317. ExpectPath(true);
  318. }
  319. static const char *BranchInsideLoopIR =
  320. "declare i1 @switch()\n"
  321. "\n"
  322. "define void @test() {\n"
  323. "entry:\n"
  324. " br label %loop\n"
  325. "loop:\n"
  326. " %x = call i1 @switch()\n"
  327. " br i1 %x, label %nextloopblock, label %exit\n"
  328. "nextloopblock:\n"
  329. " %y = call i1 @switch()\n"
  330. " br i1 %y, label %left, label %right\n"
  331. "left:\n"
  332. " %A = bitcast i8 undef to i8\n"
  333. " br label %loop\n"
  334. "right:\n"
  335. " %B = bitcast i8 undef to i8\n"
  336. " br label %loop\n"
  337. "exit:\n"
  338. " ret void\n"
  339. "}";
  340. TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
  341. ParseAssembly(BranchInsideLoopIR);
  342. ExpectPath(true);
  343. }
  344. TEST_F(IsPotentiallyReachableTest, ModifyTest) {
  345. ParseAssembly(BranchInsideLoopIR);
  346. succ_iterator S = succ_begin(++M->getFunction("test")->begin());
  347. BasicBlock *OldBB = S[0];
  348. S[0] = S[1];
  349. ExpectPath(false);
  350. S[0] = OldBB;
  351. ExpectPath(true);
  352. }