WebAssemblyExceptionInfoTest.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. //=== WebAssemblyExceptionInfoTest.cpp - WebAssebmlyExceptionInfo unit tests =//
  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 "WebAssemblyExceptionInfo.h"
  9. #include "llvm/CodeGen/MIRParser/MIRParser.h"
  10. #include "llvm/CodeGen/MachineDominanceFrontier.h"
  11. #include "llvm/CodeGen/MachineDominators.h"
  12. #include "llvm/CodeGen/MachineModuleInfo.h"
  13. #include "llvm/Support/SourceMgr.h"
  14. #include "llvm/Support/TargetRegistry.h"
  15. #include "llvm/Support/TargetSelect.h"
  16. #include "llvm/Target/TargetMachine.h"
  17. #include "gtest/gtest.h"
  18. using namespace llvm;
  19. namespace {
  20. std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
  21. auto TT(Triple::normalize("wasm32-unknown-unknown"));
  22. std::string CPU("");
  23. std::string FS("");
  24. LLVMInitializeWebAssemblyTargetInfo();
  25. LLVMInitializeWebAssemblyTarget();
  26. LLVMInitializeWebAssemblyTargetMC();
  27. std::string Error;
  28. const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
  29. assert(TheTarget);
  30. return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine*>(
  31. TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), None, None,
  32. CodeGenOpt::Default)));
  33. }
  34. std::unique_ptr<Module> parseMIR(LLVMContext &Context,
  35. std::unique_ptr<MIRParser> &MIR,
  36. const TargetMachine &TM, StringRef MIRCode,
  37. const char *FuncName, MachineModuleInfo &MMI) {
  38. SMDiagnostic Diagnostic;
  39. std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
  40. MIR = createMIRParser(std::move(MBuffer), Context);
  41. if (!MIR)
  42. return nullptr;
  43. std::unique_ptr<Module> M = MIR->parseIRModule();
  44. if (!M)
  45. return nullptr;
  46. M->setDataLayout(TM.createDataLayout());
  47. if (MIR->parseMachineFunctions(*M, MMI))
  48. return nullptr;
  49. return M;
  50. }
  51. } // namespace
  52. TEST(WebAssemblyExceptionInfoTest, TEST0) {
  53. std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
  54. ASSERT_TRUE(TM);
  55. StringRef MIRString = R"MIR(
  56. --- |
  57. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
  58. target triple = "wasm32-unknown-unknown"
  59. declare i32 @__gxx_wasm_personality_v0(...)
  60. define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
  61. unreachable
  62. }
  63. ...
  64. ---
  65. name: test0
  66. liveins:
  67. - { reg: '$arguments' }
  68. - { reg: '$value_stack' }
  69. body: |
  70. bb.0:
  71. successors: %bb.1, %bb.2
  72. liveins: $arguments, $value_stack
  73. BR %bb.1, implicit-def dead $arguments
  74. bb.1:
  75. ; predecessors: %bb.0
  76. successors: %bb.7
  77. liveins: $value_stack
  78. BR %bb.7, implicit-def $arguments
  79. bb.2 (landing-pad):
  80. ; predecessors: %bb.0
  81. successors: %bb.3, %bb.9
  82. liveins: $value_stack
  83. %0:exnref = CATCH implicit-def $arguments
  84. CLEANUPRET implicit-def dead $arguments
  85. bb.3 (landing-pad):
  86. ; predecessors: %bb.2
  87. successors: %bb.4, %bb.6
  88. liveins: $value_stack
  89. %1:exnref = CATCH implicit-def $arguments
  90. BR_IF %bb.4, %58:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
  91. BR %bb.6, implicit-def $arguments
  92. bb.4:
  93. ; predecessors: %bb.3
  94. successors: %bb.5, %bb.8
  95. liveins: $value_stack
  96. BR %bb.5, implicit-def dead $arguments
  97. bb.5:
  98. ; predecessors: %bb.4
  99. successors: %bb.7
  100. liveins: $value_stack
  101. CATCHRET %bb.7, %bb.0, implicit-def dead $arguments
  102. bb.6:
  103. ; predecessors: %bb.3
  104. successors: %bb.10, %bb.9
  105. liveins: $value_stack
  106. BR %bb.10, implicit-def dead $arguments
  107. bb.7:
  108. ; predecessors: %bb.5, %bb.1
  109. liveins: $value_stack
  110. RETURN implicit-def $arguments
  111. bb.8 (landing-pad):
  112. ; predecessors: %bb.4
  113. successors: %bb.9
  114. liveins: $value_stack
  115. %2:exnref = CATCH implicit-def $arguments
  116. CLEANUPRET implicit-def dead $arguments
  117. bb.9 (landing-pad):
  118. ; predecessors: %bb.2, %bb.6, %bb.8
  119. liveins: $value_stack
  120. %3:exnref = CATCH implicit-def $arguments
  121. CLEANUPRET implicit-def dead $arguments
  122. bb.10:
  123. ; predecessors: %bb.6
  124. liveins: $value_stack
  125. UNREACHABLE implicit-def $arguments
  126. )MIR";
  127. LLVMContext Context;
  128. std::unique_ptr<MIRParser> MIR;
  129. MachineModuleInfo MMI(TM.get());
  130. std::unique_ptr<Module> M =
  131. parseMIR(Context, MIR, *TM, MIRString, "test0", MMI);
  132. ASSERT_TRUE(M);
  133. Function *F = M->getFunction("test0");
  134. auto *MF = MMI.getMachineFunction(*F);
  135. ASSERT_TRUE(MF);
  136. WebAssemblyExceptionInfo WEI;
  137. MachineDominatorTree MDT;
  138. MachineDominanceFrontier MDF;
  139. MDT.runOnMachineFunction(*MF);
  140. MDF.getBase().analyze(MDT.getBase());
  141. WEI.recalculate(MDT, MDF);
  142. // Exception info structure:
  143. // |- bb2 (ehpad), bb3, bb4, bb5, bb6, bb8, bb9, bb10
  144. // |- bb3 (ehpad), bb4, bb5, bb6, bb8, bb10
  145. // |- bb8 (ehpad)
  146. // |- bb9 (ehpad)
  147. auto *MBB2 = MF->getBlockNumbered(2);
  148. auto *WE0 = WEI.getExceptionFor(MBB2);
  149. ASSERT_TRUE(WE0);
  150. EXPECT_EQ(WE0->getEHPad(), MBB2);
  151. EXPECT_EQ(WE0->getParentException(), nullptr);
  152. EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1);
  153. auto *MBB3 = MF->getBlockNumbered(3);
  154. auto *WE0_0 = WEI.getExceptionFor(MBB3);
  155. ASSERT_TRUE(WE0_0);
  156. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  157. EXPECT_EQ(WE0_0->getParentException(), WE0);
  158. EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2);
  159. auto *MBB4 = MF->getBlockNumbered(4);
  160. WE0_0 = WEI.getExceptionFor(MBB4);
  161. ASSERT_TRUE(WE0_0);
  162. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  163. auto *MBB5 = MF->getBlockNumbered(5);
  164. WE0_0 = WEI.getExceptionFor(MBB5);
  165. ASSERT_TRUE(WE0_0);
  166. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  167. auto *MBB6 = MF->getBlockNumbered(6);
  168. WE0_0 = WEI.getExceptionFor(MBB6);
  169. ASSERT_TRUE(WE0_0);
  170. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  171. auto *MBB10 = MF->getBlockNumbered(10);
  172. WE0_0 = WEI.getExceptionFor(MBB10);
  173. ASSERT_TRUE(WE0_0);
  174. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  175. auto *MBB8 = MF->getBlockNumbered(8);
  176. auto *WE0_0_0 = WEI.getExceptionFor(MBB8);
  177. ASSERT_TRUE(WE0_0_0);
  178. EXPECT_EQ(WE0_0_0->getEHPad(), MBB8);
  179. EXPECT_EQ(WE0_0_0->getParentException(), WE0_0);
  180. EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3);
  181. auto *MBB9 = MF->getBlockNumbered(9);
  182. auto *WE0_1 = WEI.getExceptionFor(MBB9);
  183. ASSERT_TRUE(WE0_1);
  184. EXPECT_EQ(WE0_1->getEHPad(), MBB9);
  185. EXPECT_EQ(WE0_1->getParentException(), WE0);
  186. EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2);
  187. }
  188. TEST(WebAssemblyExceptionInfoTest, TEST1) {
  189. std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
  190. ASSERT_TRUE(TM);
  191. StringRef MIRString = R"MIR(
  192. --- |
  193. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
  194. target triple = "wasm32-unknown-unknown"
  195. declare i32 @__gxx_wasm_personality_v0(...)
  196. define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
  197. unreachable
  198. }
  199. ...
  200. ---
  201. name: test1
  202. liveins:
  203. - { reg: '$arguments' }
  204. - { reg: '$value_stack' }
  205. body: |
  206. bb.0:
  207. successors: %bb.9, %bb.1
  208. liveins: $arguments, $value_stack
  209. BR %bb.9, implicit-def dead $arguments
  210. bb.1 (landing-pad):
  211. ; predecessors: %bb.0
  212. successors: %bb.2, %bb.8
  213. liveins: $value_stack
  214. %0:exnref = CATCH implicit-def $arguments
  215. BR_IF %bb.2, %32:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
  216. BR %bb.8, implicit-def $arguments
  217. bb.2:
  218. ; predecessors: %bb.1
  219. successors: %bb.7, %bb.3, %bb.11
  220. liveins: $value_stack
  221. BR %bb.7, implicit-def dead $arguments
  222. bb.3 (landing-pad):
  223. ; predecessors: %bb.2
  224. successors: %bb.4, %bb.6
  225. liveins: $value_stack
  226. %1:exnref = CATCH implicit-def $arguments
  227. BR_IF %bb.4, %43:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
  228. BR %bb.6, implicit-def $arguments
  229. bb.4:
  230. ; predecessors: %bb.3
  231. successors: %bb.5, %bb.10
  232. liveins: $value_stack
  233. BR %bb.5, implicit-def dead $arguments
  234. bb.5:
  235. ; predecessors: %bb.4
  236. successors: %bb.7(0x80000000); %bb.7(200.00%)
  237. liveins: $value_stack
  238. CATCHRET %bb.7, %bb.1, implicit-def dead $arguments
  239. bb.6:
  240. ; predecessors: %bb.3
  241. successors: %bb.12, %bb.11
  242. liveins: $value_stack
  243. BR %bb.12, implicit-def dead $arguments
  244. bb.7:
  245. ; predecessors: %bb.2, %bb.5
  246. successors: %bb.9(0x80000000); %bb.9(200.00%)
  247. liveins: $value_stack
  248. CATCHRET %bb.9, %bb.0, implicit-def dead $arguments
  249. bb.8:
  250. ; predecessors: %bb.1
  251. liveins: $value_stack
  252. UNREACHABLE implicit-def $arguments
  253. bb.9:
  254. ; predecessors: %bb.0, %bb.7
  255. liveins: $value_stack
  256. RETURN implicit-def $arguments
  257. bb.10 (landing-pad):
  258. ; predecessors: %bb.4
  259. successors: %bb.11
  260. liveins: $value_stack
  261. %2:exnref = CATCH implicit-def $arguments
  262. CLEANUPRET implicit-def dead $arguments
  263. bb.11 (landing-pad):
  264. ; predecessors: %bb.2, %bb.6, %bb.10
  265. liveins: $value_stack
  266. %3:exnref = CATCH implicit-def $arguments
  267. CLEANUPRET implicit-def dead $arguments
  268. bb.12:
  269. ; predecessors: %bb.6
  270. liveins: $value_stack
  271. UNREACHABLE implicit-def $arguments
  272. )MIR";
  273. LLVMContext Context;
  274. std::unique_ptr<MIRParser> MIR;
  275. MachineModuleInfo MMI(TM.get());
  276. std::unique_ptr<Module> M =
  277. parseMIR(Context, MIR, *TM, MIRString, "test1", MMI);
  278. ASSERT_TRUE(M);
  279. Function *F = M->getFunction("test1");
  280. auto *MF = MMI.getMachineFunction(*F);
  281. ASSERT_TRUE(MF);
  282. WebAssemblyExceptionInfo WEI;
  283. MachineDominatorTree MDT;
  284. MachineDominanceFrontier MDF;
  285. MDT.runOnMachineFunction(*MF);
  286. MDF.getBase().analyze(MDT.getBase());
  287. WEI.recalculate(MDT, MDF);
  288. // Exception info structure:
  289. // |- bb1 (ehpad), bb2, bb3, bb4, bb5, bb6, bb7, bb8, bb10, bb11, bb12
  290. // |- bb3 (ehpad), bb4, bb5, bb6, bb10, bb12
  291. // |- bb10 (ehpad)
  292. // |- bb11 (ehpad)
  293. auto *MBB1 = MF->getBlockNumbered(1);
  294. auto *WE0 = WEI.getExceptionFor(MBB1);
  295. ASSERT_TRUE(WE0);
  296. EXPECT_EQ(WE0->getEHPad(), MBB1);
  297. EXPECT_EQ(WE0->getParentException(), nullptr);
  298. EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1);
  299. auto *MBB2 = MF->getBlockNumbered(2);
  300. WE0 = WEI.getExceptionFor(MBB2);
  301. ASSERT_TRUE(WE0);
  302. EXPECT_EQ(WE0->getEHPad(), MBB1);
  303. auto *MBB7 = MF->getBlockNumbered(7);
  304. WE0 = WEI.getExceptionFor(MBB7);
  305. ASSERT_TRUE(WE0);
  306. EXPECT_EQ(WE0->getEHPad(), MBB1);
  307. auto *MBB8 = MF->getBlockNumbered(8);
  308. WE0 = WEI.getExceptionFor(MBB8);
  309. ASSERT_TRUE(WE0);
  310. EXPECT_EQ(WE0->getEHPad(), MBB1);
  311. auto *MBB3 = MF->getBlockNumbered(3);
  312. auto *WE0_0 = WEI.getExceptionFor(MBB3);
  313. ASSERT_TRUE(WE0_0);
  314. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  315. EXPECT_EQ(WE0_0->getParentException(), WE0);
  316. EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2);
  317. auto *MBB4 = MF->getBlockNumbered(4);
  318. WE0_0 = WEI.getExceptionFor(MBB4);
  319. ASSERT_TRUE(WE0_0);
  320. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  321. auto *MBB5 = MF->getBlockNumbered(5);
  322. WE0_0 = WEI.getExceptionFor(MBB5);
  323. ASSERT_TRUE(WE0_0);
  324. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  325. auto *MBB6 = MF->getBlockNumbered(6);
  326. WE0_0 = WEI.getExceptionFor(MBB6);
  327. ASSERT_TRUE(WE0_0);
  328. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  329. auto *MBB12 = MF->getBlockNumbered(12);
  330. WE0_0 = WEI.getExceptionFor(MBB12);
  331. ASSERT_TRUE(WE0_0);
  332. EXPECT_EQ(WE0_0->getEHPad(), MBB3);
  333. auto *MBB10 = MF->getBlockNumbered(10);
  334. auto *WE0_0_0 = WEI.getExceptionFor(MBB10);
  335. ASSERT_TRUE(WE0_0_0);
  336. EXPECT_EQ(WE0_0_0->getEHPad(), MBB10);
  337. EXPECT_EQ(WE0_0_0->getParentException(), WE0_0);
  338. EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3);
  339. auto *MBB11 = MF->getBlockNumbered(11);
  340. auto *WE0_1 = WEI.getExceptionFor(MBB11);
  341. ASSERT_TRUE(WE0_1);
  342. EXPECT_EQ(WE0_1->getEHPad(), MBB11);
  343. EXPECT_EQ(WE0_1->getParentException(), WE0);
  344. EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2);
  345. }