@@ -1643,6 +1643,110 @@ define void @foo(i32 %arg, float %farg) {
16431643 EXPECT_FALSE (FAdd->getFastMathFlags () != LLVMFAdd->getFastMathFlags ());
16441644}
16451645
1646+ TEST_F (SandboxIRTest, CatchSwitchInst) {
1647+ parseIR (C, R"IR(
1648+ define void @foo(i32 %cond0, i32 %cond1) {
1649+ bb0:
1650+ %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller
1651+ bb1:
1652+ %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup
1653+ handler0:
1654+ ret void
1655+ handler1:
1656+ ret void
1657+ cleanup:
1658+ ret void
1659+ }
1660+ )IR" );
1661+ Function &LLVMF = *M->getFunction (" foo" );
1662+ auto *LLVMBB0 = getBasicBlockByName (LLVMF, " bb0" );
1663+ auto *LLVMBB1 = getBasicBlockByName (LLVMF, " bb1" );
1664+ auto *LLVMHandler0 = getBasicBlockByName (LLVMF, " handler0" );
1665+ auto *LLVMHandler1 = getBasicBlockByName (LLVMF, " handler1" );
1666+ auto *LLVMCleanup = getBasicBlockByName (LLVMF, " cleanup" );
1667+ auto *LLVMCS0 = cast<llvm::CatchSwitchInst>(&*LLVMBB0->begin ());
1668+ auto *LLVMCS1 = cast<llvm::CatchSwitchInst>(&*LLVMBB1->begin ());
1669+
1670+ sandboxir::Context Ctx (C);
1671+ [[maybe_unused]] auto &F = *Ctx.createFunction (&LLVMF);
1672+ auto *BB0 = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMBB0));
1673+ auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMBB1));
1674+ auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMHandler0));
1675+ auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMHandler1));
1676+ auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMCleanup));
1677+ auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin ());
1678+ auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin ());
1679+
1680+ // Check getParentPad().
1681+ EXPECT_EQ (CS0->getParentPad (), Ctx.getValue (LLVMCS0->getParentPad ()));
1682+ EXPECT_EQ (CS1->getParentPad (), Ctx.getValue (LLVMCS1->getParentPad ()));
1683+ // Check setParentPad().
1684+ auto *OrigPad = CS0->getParentPad ();
1685+ auto *NewPad = CS1;
1686+ EXPECT_NE (NewPad, OrigPad);
1687+ CS0->setParentPad (NewPad);
1688+ EXPECT_EQ (CS0->getParentPad (), NewPad);
1689+ CS0->setParentPad (OrigPad);
1690+ EXPECT_EQ (CS0->getParentPad (), OrigPad);
1691+ // Check hasUnwindDest().
1692+ EXPECT_EQ (CS0->hasUnwindDest (), LLVMCS0->hasUnwindDest ());
1693+ EXPECT_EQ (CS1->hasUnwindDest (), LLVMCS1->hasUnwindDest ());
1694+ // Check unwindsToCaller().
1695+ EXPECT_EQ (CS0->unwindsToCaller (), LLVMCS0->unwindsToCaller ());
1696+ EXPECT_EQ (CS1->unwindsToCaller (), LLVMCS1->unwindsToCaller ());
1697+ // Check getUnwindDest().
1698+ EXPECT_EQ (CS0->getUnwindDest (), Ctx.getValue (LLVMCS0->getUnwindDest ()));
1699+ EXPECT_EQ (CS1->getUnwindDest (), Ctx.getValue (LLVMCS1->getUnwindDest ()));
1700+ // Check setUnwindDest().
1701+ auto *OrigUnwindDest = CS1->getUnwindDest ();
1702+ auto *NewUnwindDest = BB0;
1703+ EXPECT_NE (NewUnwindDest, OrigUnwindDest);
1704+ CS1->setUnwindDest (NewUnwindDest);
1705+ EXPECT_EQ (CS1->getUnwindDest (), NewUnwindDest);
1706+ CS1->setUnwindDest (OrigUnwindDest);
1707+ EXPECT_EQ (CS1->getUnwindDest (), OrigUnwindDest);
1708+ // Check getNumHandlers().
1709+ EXPECT_EQ (CS0->getNumHandlers (), LLVMCS0->getNumHandlers ());
1710+ EXPECT_EQ (CS1->getNumHandlers (), LLVMCS1->getNumHandlers ());
1711+ // Check handler_begin(), handler_end().
1712+ auto It = CS0->handler_begin ();
1713+ EXPECT_EQ (*It++, Handler0);
1714+ EXPECT_EQ (*It++, Handler1);
1715+ EXPECT_EQ (It, CS0->handler_end ());
1716+ // Check handlers().
1717+ SmallVector<sandboxir::BasicBlock *, 2 > Handlers;
1718+ for (sandboxir::BasicBlock *Handler : CS0->handlers ())
1719+ Handlers.push_back (Handler);
1720+ EXPECT_EQ (Handlers.size (), 2u );
1721+ EXPECT_EQ (Handlers[0 ], Handler0);
1722+ EXPECT_EQ (Handlers[1 ], Handler1);
1723+ // Check addHandler().
1724+ CS0->addHandler (BB0);
1725+ EXPECT_EQ (CS0->getNumHandlers (), 3u );
1726+ EXPECT_EQ (*std::next (CS0->handler_begin (), 2 ), BB0);
1727+ // Check getNumSuccessors().
1728+ EXPECT_EQ (CS0->getNumSuccessors (), LLVMCS0->getNumSuccessors ());
1729+ EXPECT_EQ (CS1->getNumSuccessors (), LLVMCS1->getNumSuccessors ());
1730+ // Check getSuccessor().
1731+ for (auto SuccIdx : seq<unsigned >(0 , CS0->getNumSuccessors ()))
1732+ EXPECT_EQ (CS0->getSuccessor (SuccIdx),
1733+ Ctx.getValue (LLVMCS0->getSuccessor (SuccIdx)));
1734+ // Check setSuccessor().
1735+ auto *OrigSuccessor = CS0->getSuccessor (0 );
1736+ auto *NewSuccessor = BB0;
1737+ EXPECT_NE (NewSuccessor, OrigSuccessor);
1738+ CS0->setSuccessor (0 , NewSuccessor);
1739+ EXPECT_EQ (CS0->getSuccessor (0 ), NewSuccessor);
1740+ CS0->setSuccessor (0 , OrigSuccessor);
1741+ EXPECT_EQ (CS0->getSuccessor (0 ), OrigSuccessor);
1742+ // Check create().
1743+ CS1->eraseFromParent ();
1744+ auto *NewCSI = sandboxir::CatchSwitchInst::create (
1745+ CS0, Cleanup, 2 , BB1->begin (), BB1, Ctx, " NewCSI" );
1746+ EXPECT_TRUE (isa<sandboxir::CatchSwitchInst>(NewCSI));
1747+ EXPECT_EQ (NewCSI->getParentPad (), CS0);
1748+ }
1749+
16461750TEST_F (SandboxIRTest, SwitchInst) {
16471751 parseIR (C, R"IR(
16481752define void @foo(i32 %cond0, i32 %cond1) {
0 commit comments