417 lines · cpp
1//=== WebAssemblyExceptionInfoTest.cpp - WebAssemblyExceptionInfo 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "WebAssemblyExceptionInfo.h"10#include "llvm/CodeGen/MIRParser/MIRParser.h"11#include "llvm/CodeGen/MachineDominanceFrontier.h"12#include "llvm/CodeGen/MachineDominators.h"13#include "llvm/CodeGen/MachineModuleInfo.h"14#include "llvm/IR/Module.h"15#include "llvm/MC/TargetRegistry.h"16#include "llvm/Support/SourceMgr.h"17#include "llvm/Support/TargetSelect.h"18#include "llvm/Target/TargetMachine.h"19#include "gtest/gtest.h"20 21using namespace llvm;22 23namespace {24 25std::unique_ptr<TargetMachine> createTargetMachine() {26 Triple TT("wasm32-unknown-unknown");27 std::string CPU;28 std::string FS;29 30 LLVMInitializeWebAssemblyTargetInfo();31 LLVMInitializeWebAssemblyTarget();32 LLVMInitializeWebAssemblyTargetMC();33 34 std::string Error;35 const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);36 assert(TheTarget);37 38 return std::unique_ptr<TargetMachine>(39 TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), std::nullopt,40 std::nullopt, CodeGenOptLevel::Default));41}42 43std::unique_ptr<Module> parseMIR(LLVMContext &Context,44 std::unique_ptr<MIRParser> &MIR,45 const TargetMachine &TM, StringRef MIRCode,46 MachineModuleInfo &MMI) {47 SMDiagnostic Diagnostic;48 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);49 MIR = createMIRParser(std::move(MBuffer), Context);50 if (!MIR)51 return nullptr;52 53 std::unique_ptr<Module> M = MIR->parseIRModule();54 if (!M)55 return nullptr;56 57 M->setDataLayout(TM.createDataLayout());58 59 if (MIR->parseMachineFunctions(*M, MMI))60 return nullptr;61 62 return M;63}64 65} // namespace66 67TEST(WebAssemblyExceptionInfoTest, TEST0) {68 std::unique_ptr<TargetMachine> TM = createTargetMachine();69 ASSERT_TRUE(TM);70 71 StringRef MIRString = R"MIR(72--- |73 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"74 target triple = "wasm32-unknown-unknown"75 76 declare i32 @__gxx_wasm_personality_v0(...)77 78 define void @test0() personality ptr @__gxx_wasm_personality_v0 {79 unreachable80 }81 82...83---84name: test085liveins:86 - { reg: '$arguments' }87 - { reg: '$value_stack' }88body: |89 bb.0:90 successors: %bb.1, %bb.291 liveins: $arguments, $value_stack92 BR %bb.1, implicit-def dead $arguments93 94 bb.1:95 ; predecessors: %bb.096 successors: %bb.797 liveins: $value_stack98 BR %bb.7, implicit-def $arguments99 100 bb.2 (landing-pad):101 ; predecessors: %bb.0102 successors: %bb.3, %bb.9103 liveins: $value_stack104 CATCH_ALL_LEGACY implicit-def $arguments105 RETHROW 0, implicit-def dead $arguments106 107 bb.3 (landing-pad):108 ; predecessors: %bb.2109 successors: %bb.4, %bb.6110 liveins: $value_stack111 %1:i32 = CATCH_LEGACY &__cpp_exception, implicit-def $arguments112 BR_IF %bb.4, %58:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack113 BR %bb.6, implicit-def $arguments114 115 bb.4:116 ; predecessors: %bb.3117 successors: %bb.5, %bb.8118 liveins: $value_stack119 BR %bb.5, implicit-def dead $arguments120 121 bb.5:122 ; predecessors: %bb.4123 successors: %bb.7124 liveins: $value_stack125 BR %bb.7, implicit-def dead $arguments126 127 bb.6:128 ; predecessors: %bb.3129 successors: %bb.10, %bb.9130 liveins: $value_stack131 BR %bb.10, implicit-def dead $arguments132 133 bb.7:134 ; predecessors: %bb.5, %bb.1135 liveins: $value_stack136 RETURN implicit-def $arguments137 138 bb.8 (landing-pad):139 ; predecessors: %bb.4140 successors: %bb.9141 liveins: $value_stack142 CATCH_ALL_LEGACY implicit-def $arguments143 RETHROW 0, implicit-def dead $arguments144 145 bb.9 (landing-pad):146 ; predecessors: %bb.2, %bb.6, %bb.8147 liveins: $value_stack148 CATCH_ALL_LEGACY implicit-def $arguments149 RETHROW 0, implicit-def dead $arguments150 151 bb.10:152 ; predecessors: %bb.6153 liveins: $value_stack154 UNREACHABLE implicit-def $arguments155)MIR";156 157 LLVMContext Context;158 std::unique_ptr<MIRParser> MIR;159 MachineModuleInfo MMI(TM.get());160 std::unique_ptr<Module> M = parseMIR(Context, MIR, *TM, MIRString, MMI);161 ASSERT_TRUE(M);162 163 Function *F = M->getFunction("test0");164 auto *MF = MMI.getMachineFunction(*F);165 ASSERT_TRUE(MF);166 167 WebAssemblyExceptionInfo WEI;168 MachineDominatorTree MDT;169 MachineDominanceFrontier MDF;170 MDT.recalculate(*MF);171 MDF.getBase().analyze(MDT);172 WEI.recalculate(*MF, MDT, MDF);173 174 // Exception info structure:175 // |- bb2 (ehpad), bb3, bb4, bb5, bb6, bb8, bb9, bb10176 // |- bb3 (ehpad), bb4, bb5, bb6, bb8, bb10177 // |- bb8 (ehpad)178 // |- bb9 (ehpad)179 180 auto *MBB2 = MF->getBlockNumbered(2);181 auto *WE0 = WEI.getExceptionFor(MBB2);182 ASSERT_TRUE(WE0);183 EXPECT_EQ(WE0->getEHPad(), MBB2);184 EXPECT_EQ(WE0->getParentException(), nullptr);185 EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1);186 187 auto *MBB3 = MF->getBlockNumbered(3);188 auto *WE0_0 = WEI.getExceptionFor(MBB3);189 ASSERT_TRUE(WE0_0);190 EXPECT_EQ(WE0_0->getEHPad(), MBB3);191 EXPECT_EQ(WE0_0->getParentException(), WE0);192 EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2);193 194 auto *MBB4 = MF->getBlockNumbered(4);195 WE0_0 = WEI.getExceptionFor(MBB4);196 ASSERT_TRUE(WE0_0);197 EXPECT_EQ(WE0_0->getEHPad(), MBB3);198 199 auto *MBB5 = MF->getBlockNumbered(5);200 WE0_0 = WEI.getExceptionFor(MBB5);201 ASSERT_TRUE(WE0_0);202 EXPECT_EQ(WE0_0->getEHPad(), MBB3);203 204 auto *MBB6 = MF->getBlockNumbered(6);205 WE0_0 = WEI.getExceptionFor(MBB6);206 ASSERT_TRUE(WE0_0);207 EXPECT_EQ(WE0_0->getEHPad(), MBB3);208 209 auto *MBB10 = MF->getBlockNumbered(10);210 WE0_0 = WEI.getExceptionFor(MBB10);211 ASSERT_TRUE(WE0_0);212 EXPECT_EQ(WE0_0->getEHPad(), MBB3);213 214 auto *MBB8 = MF->getBlockNumbered(8);215 auto *WE0_0_0 = WEI.getExceptionFor(MBB8);216 ASSERT_TRUE(WE0_0_0);217 EXPECT_EQ(WE0_0_0->getEHPad(), MBB8);218 EXPECT_EQ(WE0_0_0->getParentException(), WE0_0);219 EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3);220 221 auto *MBB9 = MF->getBlockNumbered(9);222 auto *WE0_1 = WEI.getExceptionFor(MBB9);223 ASSERT_TRUE(WE0_1);224 EXPECT_EQ(WE0_1->getEHPad(), MBB9);225 EXPECT_EQ(WE0_1->getParentException(), WE0);226 EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2);227}228 229TEST(WebAssemblyExceptionInfoTest, TEST1) {230 std::unique_ptr<TargetMachine> TM = createTargetMachine();231 ASSERT_TRUE(TM);232 233 StringRef MIRString = R"MIR(234--- |235 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"236 target triple = "wasm32-unknown-unknown"237 238 declare i32 @__gxx_wasm_personality_v0(...)239 240 define void @test1() personality ptr @__gxx_wasm_personality_v0 {241 unreachable242 }243 244...245---246name: test1247liveins:248 - { reg: '$arguments' }249 - { reg: '$value_stack' }250body: |251 bb.0:252 successors: %bb.9, %bb.1253 liveins: $arguments, $value_stack254 BR %bb.9, implicit-def dead $arguments255 256 bb.1 (landing-pad):257 ; predecessors: %bb.0258 successors: %bb.2, %bb.8259 liveins: $value_stack260 %0:i32 = CATCH_LEGACY &__cpp_exception, implicit-def $arguments261 BR_IF %bb.2, %32:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack262 BR %bb.8, implicit-def $arguments263 264 bb.2:265 ; predecessors: %bb.1266 successors: %bb.7, %bb.3, %bb.11267 liveins: $value_stack268 BR %bb.7, implicit-def dead $arguments269 270 bb.3 (landing-pad):271 ; predecessors: %bb.2272 successors: %bb.4, %bb.6273 liveins: $value_stack274 %1:i32 = CATCH_LEGACY &__cpp_exception, implicit-def $arguments275 BR_IF %bb.4, %43:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack276 BR %bb.6, implicit-def $arguments277 278 bb.4:279 ; predecessors: %bb.3280 successors: %bb.5, %bb.10281 liveins: $value_stack282 BR %bb.5, implicit-def dead $arguments283 284 bb.5:285 ; predecessors: %bb.4286 successors: %bb.7(0x80000000); %bb.7(200.00%)287 liveins: $value_stack288 BR %bb.7, implicit-def dead $arguments289 290 bb.6:291 ; predecessors: %bb.3292 successors: %bb.12, %bb.11293 liveins: $value_stack294 BR %bb.12, implicit-def dead $arguments295 296 bb.7:297 ; predecessors: %bb.2, %bb.5298 successors: %bb.9(0x80000000); %bb.9(200.00%)299 liveins: $value_stack300 BR %bb.9, implicit-def dead $arguments301 302 bb.8:303 ; predecessors: %bb.1304 liveins: $value_stack305 UNREACHABLE implicit-def $arguments306 307 bb.9:308 ; predecessors: %bb.0, %bb.7309 liveins: $value_stack310 RETURN implicit-def $arguments311 312 bb.10 (landing-pad):313 ; predecessors: %bb.4314 successors: %bb.11315 liveins: $value_stack316 CATCH_ALL_LEGACY implicit-def $arguments317 RETHROW 0, implicit-def dead $arguments318 319 bb.11 (landing-pad):320 ; predecessors: %bb.2, %bb.6, %bb.10321 liveins: $value_stack322 CATCH_ALL_LEGACY implicit-def $arguments323 RETHROW 0, implicit-def dead $arguments324 325 bb.12:326 ; predecessors: %bb.6327 liveins: $value_stack328 UNREACHABLE implicit-def $arguments329)MIR";330 331 LLVMContext Context;332 std::unique_ptr<MIRParser> MIR;333 MachineModuleInfo MMI(TM.get());334 std::unique_ptr<Module> M = parseMIR(Context, MIR, *TM, MIRString, MMI);335 ASSERT_TRUE(M);336 337 Function *F = M->getFunction("test1");338 auto *MF = MMI.getMachineFunction(*F);339 ASSERT_TRUE(MF);340 341 WebAssemblyExceptionInfo WEI;342 MachineDominatorTree MDT;343 MachineDominanceFrontier MDF;344 MDT.recalculate(*MF);345 MDF.getBase().analyze(MDT);346 WEI.recalculate(*MF, MDT, MDF);347 348 // Exception info structure:349 // |- bb1 (ehpad), bb2, bb3, bb4, bb5, bb6, bb7, bb8, bb10, bb11, bb12350 // |- bb3 (ehpad), bb4, bb5, bb6, bb10, bb12351 // |- bb10 (ehpad)352 // |- bb11 (ehpad)353 354 auto *MBB1 = MF->getBlockNumbered(1);355 auto *WE0 = WEI.getExceptionFor(MBB1);356 ASSERT_TRUE(WE0);357 EXPECT_EQ(WE0->getEHPad(), MBB1);358 EXPECT_EQ(WE0->getParentException(), nullptr);359 EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1);360 361 auto *MBB2 = MF->getBlockNumbered(2);362 WE0 = WEI.getExceptionFor(MBB2);363 ASSERT_TRUE(WE0);364 EXPECT_EQ(WE0->getEHPad(), MBB1);365 366 auto *MBB7 = MF->getBlockNumbered(7);367 WE0 = WEI.getExceptionFor(MBB7);368 ASSERT_TRUE(WE0);369 EXPECT_EQ(WE0->getEHPad(), MBB1);370 371 auto *MBB8 = MF->getBlockNumbered(8);372 WE0 = WEI.getExceptionFor(MBB8);373 ASSERT_TRUE(WE0);374 EXPECT_EQ(WE0->getEHPad(), MBB1);375 376 auto *MBB3 = MF->getBlockNumbered(3);377 auto *WE0_0 = WEI.getExceptionFor(MBB3);378 ASSERT_TRUE(WE0_0);379 EXPECT_EQ(WE0_0->getEHPad(), MBB3);380 EXPECT_EQ(WE0_0->getParentException(), WE0);381 EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2);382 383 auto *MBB4 = MF->getBlockNumbered(4);384 WE0_0 = WEI.getExceptionFor(MBB4);385 ASSERT_TRUE(WE0_0);386 EXPECT_EQ(WE0_0->getEHPad(), MBB3);387 388 auto *MBB5 = MF->getBlockNumbered(5);389 WE0_0 = WEI.getExceptionFor(MBB5);390 ASSERT_TRUE(WE0_0);391 EXPECT_EQ(WE0_0->getEHPad(), MBB3);392 393 auto *MBB6 = MF->getBlockNumbered(6);394 WE0_0 = WEI.getExceptionFor(MBB6);395 ASSERT_TRUE(WE0_0);396 EXPECT_EQ(WE0_0->getEHPad(), MBB3);397 398 auto *MBB12 = MF->getBlockNumbered(12);399 WE0_0 = WEI.getExceptionFor(MBB12);400 ASSERT_TRUE(WE0_0);401 EXPECT_EQ(WE0_0->getEHPad(), MBB3);402 403 auto *MBB10 = MF->getBlockNumbered(10);404 auto *WE0_0_0 = WEI.getExceptionFor(MBB10);405 ASSERT_TRUE(WE0_0_0);406 EXPECT_EQ(WE0_0_0->getEHPad(), MBB10);407 EXPECT_EQ(WE0_0_0->getParentException(), WE0_0);408 EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3);409 410 auto *MBB11 = MF->getBlockNumbered(11);411 auto *WE0_1 = WEI.getExceptionFor(MBB11);412 ASSERT_TRUE(WE0_1);413 EXPECT_EQ(WE0_1->getEHPad(), MBB11);414 EXPECT_EQ(WE0_1->getParentException(), WE0);415 EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2);416}417