Skip to content

Commit eced2ce

Browse files
vporpocjdb
authored andcommitted
[SandboxIR] Implement CatchReturnInst (llvm#105605)
This patch implements sandboxir::CatchReturnInst mirroring llvm::CatchReturnInst.
1 parent 31fbf2b commit eced2ce

File tree

5 files changed

+199
-0
lines changed

5 files changed

+199
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class CallBrInst;
130130
class FuncletPadInst;
131131
class CatchPadInst;
132132
class CleanupPadInst;
133+
class CatchReturnInst;
133134
class GetElementPtrInst;
134135
class CastInst;
135136
class PtrToIntInst;
@@ -262,6 +263,7 @@ class Value {
262263
friend class FuncletPadInst; // For getting `Val`.
263264
friend class CatchPadInst; // For getting `Val`.
264265
friend class CleanupPadInst; // For getting `Val`.
266+
friend class CatchReturnInst; // For getting `Val`.
265267
friend class GetElementPtrInst; // For getting `Val`.
266268
friend class CatchSwitchInst; // For getting `Val`.
267269
friend class SwitchInst; // For getting `Val`.
@@ -687,6 +689,7 @@ class Instruction : public sandboxir::User {
687689
friend class CallBrInst; // For getTopmostLLVMInstruction().
688690
friend class CatchPadInst; // For getTopmostLLVMInstruction().
689691
friend class CleanupPadInst; // For getTopmostLLVMInstruction().
692+
friend class CatchReturnInst; // For getTopmostLLVMInstruction().
690693
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
691694
friend class CatchSwitchInst; // For getTopmostLLVMInstruction().
692695
friend class SwitchInst; // For getTopmostLLVMInstruction().
@@ -1914,6 +1917,30 @@ class CleanupPadInst : public FuncletPadInst {
19141917
}
19151918
};
19161919

1920+
class CatchReturnInst
1921+
: public SingleLLVMInstructionImpl<llvm::CatchReturnInst> {
1922+
CatchReturnInst(llvm::CatchReturnInst *CRI, Context &Ctx)
1923+
: SingleLLVMInstructionImpl(ClassID::CatchRet, Opcode::CatchRet, CRI,
1924+
Ctx) {}
1925+
friend class Context; // For constructor.
1926+
1927+
public:
1928+
static CatchReturnInst *create(CatchPadInst *CatchPad, BasicBlock *BB,
1929+
BBIterator WhereIt, BasicBlock *WhereBB,
1930+
Context &Ctx);
1931+
CatchPadInst *getCatchPad() const;
1932+
void setCatchPad(CatchPadInst *CatchPad);
1933+
BasicBlock *getSuccessor() const;
1934+
void setSuccessor(BasicBlock *NewSucc);
1935+
unsigned getNumSuccessors() {
1936+
return cast<llvm::CatchReturnInst>(Val)->getNumSuccessors();
1937+
}
1938+
Value *getCatchSwitchParentPad() const;
1939+
static bool classof(const Value *From) {
1940+
return From->getSubclassID() == ClassID::CatchRet;
1941+
}
1942+
};
1943+
19171944
class GetElementPtrInst final
19181945
: public SingleLLVMInstructionImpl<llvm::GetElementPtrInst> {
19191946
/// Use Context::createGetElementPtrInst(). Don't call
@@ -2820,6 +2847,8 @@ class Context {
28202847
friend CatchPadInst; // For createCatchPadInst()
28212848
CleanupPadInst *createCleanupPadInst(llvm::CleanupPadInst *I);
28222849
friend CleanupPadInst; // For createCleanupPadInst()
2850+
CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
2851+
friend CatchReturnInst; // For createCatchReturnInst()
28232852
GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
28242853
friend GetElementPtrInst; // For createGetElementPtrInst()
28252854
CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ DEF_INSTR(Invoke, OP(Invoke), InvokeInst)
4848
DEF_INSTR(CallBr, OP(CallBr), CallBrInst)
4949
DEF_INSTR(CatchPad, OP(CatchPad), CatchPadInst)
5050
DEF_INSTR(CleanupPad, OP(CleanupPad), CleanupPadInst)
51+
DEF_INSTR(CatchRet, OP(CatchRet), CatchReturnInst)
5152
DEF_INSTR(GetElementPtr, OP(GetElementPtr), GetElementPtrInst)
5253
DEF_INSTR(CatchSwitch, OP(CatchSwitch), CatchSwitchInst)
5354
DEF_INSTR(Switch, OP(Switch), SwitchInst)

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,50 @@ CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
11051105
return Ctx.createCleanupPadInst(LLVMI);
11061106
}
11071107

1108+
CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
1109+
BBIterator WhereIt,
1110+
BasicBlock *WhereBB, Context &Ctx) {
1111+
auto &Builder = Ctx.getLLVMIRBuilder();
1112+
if (WhereIt != WhereBB->end())
1113+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1114+
else
1115+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1116+
llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
1117+
cast<llvm::CatchPadInst>(CatchPad->Val), cast<llvm::BasicBlock>(BB->Val));
1118+
return Ctx.createCatchReturnInst(LLVMI);
1119+
}
1120+
1121+
CatchPadInst *CatchReturnInst::getCatchPad() const {
1122+
return cast<CatchPadInst>(
1123+
Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
1124+
}
1125+
1126+
void CatchReturnInst::setCatchPad(CatchPadInst *CatchPad) {
1127+
Ctx.getTracker()
1128+
.emplaceIfTracking<GenericSetter<&CatchReturnInst::getCatchPad,
1129+
&CatchReturnInst::setCatchPad>>(this);
1130+
cast<llvm::CatchReturnInst>(Val)->setCatchPad(
1131+
cast<llvm::CatchPadInst>(CatchPad->Val));
1132+
}
1133+
1134+
BasicBlock *CatchReturnInst::getSuccessor() const {
1135+
return cast<BasicBlock>(
1136+
Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
1137+
}
1138+
1139+
void CatchReturnInst::setSuccessor(BasicBlock *NewSucc) {
1140+
Ctx.getTracker()
1141+
.emplaceIfTracking<GenericSetter<&CatchReturnInst::getSuccessor,
1142+
&CatchReturnInst::setSuccessor>>(this);
1143+
cast<llvm::CatchReturnInst>(Val)->setSuccessor(
1144+
cast<llvm::BasicBlock>(NewSucc->Val));
1145+
}
1146+
1147+
Value *CatchReturnInst::getCatchSwitchParentPad() const {
1148+
return Ctx.getValue(
1149+
cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
1150+
}
1151+
11081152
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
11091153
ArrayRef<Value *> IdxList,
11101154
BasicBlock::iterator WhereIt,
@@ -2138,6 +2182,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
21382182
std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this));
21392183
return It->second.get();
21402184
}
2185+
case llvm::Instruction::CatchRet: {
2186+
auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV);
2187+
It->second =
2188+
std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
2189+
return It->second.get();
2190+
}
21412191
case llvm::Instruction::GetElementPtr: {
21422192
auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
21432193
It->second = std::unique_ptr<GetElementPtrInst>(
@@ -2322,6 +2372,10 @@ CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) {
23222372
auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this));
23232373
return cast<CleanupPadInst>(registerValue(std::move(NewPtr)));
23242374
}
2375+
CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) {
2376+
auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
2377+
return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
2378+
}
23252379
GetElementPtrInst *
23262380
Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
23272381
auto NewPtr =

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,71 @@ define void @foo() {
19571957
#endif // NDEBUG
19581958
}
19591959

1960+
TEST_F(SandboxIRTest, CatchReturnInst) {
1961+
parseIR(C, R"IR(
1962+
define void @foo() {
1963+
dispatch:
1964+
%cs = catchswitch within none [label %catch] unwind to caller
1965+
catch:
1966+
%catchpad = catchpad within %cs [ptr @foo]
1967+
catchret from %catchpad to label %continue
1968+
continue:
1969+
ret void
1970+
catch2:
1971+
%catchpad2 = catchpad within %cs [ptr @foo]
1972+
ret void
1973+
}
1974+
)IR");
1975+
Function &LLVMF = *M->getFunction("foo");
1976+
BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch");
1977+
auto LLVMIt = LLVMCatch->begin();
1978+
[[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++);
1979+
auto *LLVMCR = cast<llvm::CatchReturnInst>(&*LLVMIt++);
1980+
1981+
sandboxir::Context Ctx(C);
1982+
[[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
1983+
auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch));
1984+
auto *Catch2 = cast<sandboxir::BasicBlock>(
1985+
Ctx.getValue(getBasicBlockByName(LLVMF, "catch2")));
1986+
auto It = Catch->begin();
1987+
[[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++);
1988+
auto *CR = cast<sandboxir::CatchReturnInst>(&*It++);
1989+
auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin());
1990+
1991+
// Check getCatchPad().
1992+
EXPECT_EQ(CR->getCatchPad(), Ctx.getValue(LLVMCR->getCatchPad()));
1993+
// Check setCatchPad().
1994+
auto *OrigCP = CR->getCatchPad();
1995+
auto *NewCP = CP2;
1996+
EXPECT_NE(NewCP, OrigCP);
1997+
CR->setCatchPad(NewCP);
1998+
EXPECT_EQ(CR->getCatchPad(), NewCP);
1999+
CR->setCatchPad(OrigCP);
2000+
EXPECT_EQ(CR->getCatchPad(), OrigCP);
2001+
// Check getSuccessor().
2002+
EXPECT_EQ(CR->getSuccessor(), Ctx.getValue(LLVMCR->getSuccessor()));
2003+
// Check setSuccessor().
2004+
auto *OrigSucc = CR->getSuccessor();
2005+
auto *NewSucc = Catch;
2006+
EXPECT_NE(NewSucc, OrigSucc);
2007+
CR->setSuccessor(NewSucc);
2008+
EXPECT_EQ(CR->getSuccessor(), NewSucc);
2009+
CR->setSuccessor(OrigSucc);
2010+
EXPECT_EQ(CR->getSuccessor(), OrigSucc);
2011+
// Check getNumSuccessors().
2012+
EXPECT_EQ(CR->getNumSuccessors(), LLVMCR->getNumSuccessors());
2013+
// Check getCatchSwitchParentPad().
2014+
EXPECT_EQ(CR->getCatchSwitchParentPad(),
2015+
Ctx.getValue(LLVMCR->getCatchSwitchParentPad()));
2016+
// Check create().
2017+
auto *CRI =
2018+
cast<sandboxir::CatchReturnInst>(sandboxir::CatchReturnInst::create(
2019+
CP, Catch, CP->getIterator(), Catch, Ctx));
2020+
EXPECT_EQ(CRI->getNextNode(), CP);
2021+
EXPECT_EQ(CRI->getCatchPad(), CP);
2022+
EXPECT_EQ(CRI->getSuccessor(), Catch);
2023+
}
2024+
19602025
TEST_F(SandboxIRTest, GetElementPtrInstruction) {
19612026
parseIR(C, R"IR(
19622027
define void @foo(ptr %ptr, <2 x ptr> %ptrs) {

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,56 @@ define void @foo(i32 %cond0, i32 %cond1) {
713713
EXPECT_EQ(*HIt++, Handler1);
714714
}
715715

716+
TEST_F(TrackerTest, CatchReturnInstSetters) {
717+
parseIR(C, R"IR(
718+
define void @foo() {
719+
dispatch:
720+
%cs = catchswitch within none [label %catch] unwind to caller
721+
catch:
722+
%catchpad = catchpad within %cs [ptr @foo]
723+
catchret from %catchpad to label %continue
724+
continue:
725+
ret void
726+
catch2:
727+
%catchpad2 = catchpad within %cs [ptr @foo]
728+
ret void
729+
}
730+
)IR");
731+
Function &LLVMF = *M->getFunction("foo");
732+
BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch");
733+
auto LLVMIt = LLVMCatch->begin();
734+
[[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++);
735+
736+
sandboxir::Context Ctx(C);
737+
[[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
738+
auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch));
739+
auto *Catch2 = cast<sandboxir::BasicBlock>(
740+
Ctx.getValue(getBasicBlockByName(LLVMF, "catch2")));
741+
auto It = Catch->begin();
742+
[[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++);
743+
auto *CR = cast<sandboxir::CatchReturnInst>(&*It++);
744+
auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin());
745+
746+
// Check setCatchPad().
747+
auto *OrigCP = CR->getCatchPad();
748+
auto *NewCP = CP2;
749+
EXPECT_NE(NewCP, OrigCP);
750+
Ctx.save();
751+
CR->setCatchPad(NewCP);
752+
EXPECT_EQ(CR->getCatchPad(), NewCP);
753+
Ctx.revert();
754+
EXPECT_EQ(CR->getCatchPad(), OrigCP);
755+
// Check setSuccessor().
756+
auto *OrigSucc = CR->getSuccessor();
757+
auto *NewSucc = Catch;
758+
EXPECT_NE(NewSucc, OrigSucc);
759+
Ctx.save();
760+
CR->setSuccessor(NewSucc);
761+
EXPECT_EQ(CR->getSuccessor(), NewSucc);
762+
Ctx.revert();
763+
EXPECT_EQ(CR->getSuccessor(), OrigSucc);
764+
}
765+
716766
TEST_F(TrackerTest, SwitchInstSetters) {
717767
parseIR(C, R"IR(
718768
define void @foo(i32 %cond0, i32 %cond1) {

0 commit comments

Comments
 (0)