[llvm] [SandboxIR] Implement UnreachableInst (PR #101856)
Julius Alexandre via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 17:25:06 PDT 2024
https://github.com/medievalghoul created https://github.com/llvm/llvm-project/pull/101856
This patch implements the `UnreachableInst` instruction in SandboxIR. Mirroring `llvm::UnreachableInst`.
cc: @vporpo
>From f0a3cb13c0ded19be5f364f19bd3f242ffde3b4d Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sat, 3 Aug 2024 20:22:41 -0400
Subject: [PATCH] [SandboxIR] Implement UnreachableInst
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 45 +++++++++++++++++++
.../llvm/SandboxIR/SandboxIRValues.def | 4 +-
llvm/lib/SandboxIR/SandboxIR.cpp | 38 ++++++++++++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 29 ++++++++++++
4 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index ed0aaeb4f9a8e..bbe4ea5dd8d24 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -81,6 +81,8 @@
// | +- CastInst
// |
// +- UnaryOperator
+// |
+// +- UnreachableInst
//
// Use
//
@@ -115,6 +117,7 @@ class LoadInst;
class ReturnInst;
class StoreInst;
class User;
+class UnreachableInst;
class Value;
class CallBase;
class CallInst;
@@ -242,6 +245,7 @@ class Value {
friend class GetElementPtrInst; // For getting `Val`.
friend class CastInst; // For getting `Val`.
friend class PHINode; // For getting `Val`.
+ friend class UnreachableInst; // For getting `Val`.
/// All values point to the context.
Context &Ctx;
@@ -635,6 +639,7 @@ class Instruction : public sandboxir::User {
friend class GetElementPtrInst; // For getTopmostLLVMInstruction().
friend class CastInst; // For getTopmostLLVMInstruction().
friend class PHINode; // For getTopmostLLVMInstruction().
+ friend class UnreachableInst; // For getTopmostLLVMInstruction().
/// \Returns the LLVM IR Instructions that this SandboxIR maps to in program
/// order.
@@ -952,6 +957,44 @@ class StoreInst final : public Instruction {
#endif
};
+class UnreachableInst final : public Instruction {
+ /// Use UnreachableInst::create() instead of calling the constructor.
+ UnreachableInst(llvm::Instruction *I, Context &Ctx)
+ : Instruction(ClassID::Unreachable, Opcode::Unreachable, I, Ctx) {}
+ UnreachableInst(ClassID SubclassID, llvm::Instruction *I, Context &Ctx)
+ : Instruction(SubclassID, Opcode::Unreachable, I, Ctx) {}
+ friend Context;
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
+ return getOperandUseDefault(OpIdx, Verify);
+ }
+ SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
+ return {cast<llvm::Instruction>(Val)};
+ }
+
+public:
+ static UnreachableInst *create(Instruction *InsertBefore, Context &Ctx);
+ static UnreachableInst *create(BasicBlock *InsertAtEnd, Context &Ctx);
+ static bool classof(const Value *From);
+ unsigned getNumSuccessors() const { return 0; }
+ BasicBlock *getSuccessor(unsigned idx) const {
+ llvm_unreachable("UnreachableInst has no successors!");
+ }
+ void setSuccessor(unsigned idx, BasicBlock *B) {
+ llvm_unreachable("UnreachableInst has no successors!");
+ }
+ unsigned getUseOperandNo(const Use &Use) const final {
+ return getUseOperandNoDefault(Use);
+ }
+ unsigned getNumOfIRInstrs() const final { return 1u; }
+#ifndef NDEBUG
+ void verify() const final {
+ assert(isa<llvm::UnreachableInst>(Val) && "Expected UnreachableInst!");
+ }
+ void dump(raw_ostream &OS) const override;
+ LLVM_DUMP_METHOD void dump() const override;
+#endif
+};
+
class ReturnInst final : public Instruction {
/// Use ReturnInst::create() instead of calling the constructor.
ReturnInst(llvm::Instruction *I, Context &Ctx)
@@ -1732,6 +1775,8 @@ class Context {
friend CastInst; // For createCastInst()
PHINode *createPHINode(llvm::PHINode *I);
friend PHINode; // For createPHINode()
+ UnreachableInst *createUnreachableInst(llvm::UnreachableInst *UI);
+ friend UnreachableInst; // For createUnreachableInst()
public:
Context(LLVMContext &LLVMCtx)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 4cb601128a507..61c5f7d79412d 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -59,7 +59,9 @@ DEF_INSTR(Cast, OPCODES(\
OP(AddrSpaceCast) \
), CastInst)
DEF_INSTR(PHI, OP(PHI), PHINode)
-
+DEF_INSTR(Unreachable, OP(Unreachable), UnreachableInst)
+
+
// clang-format on
#ifdef DEF_VALUE
#undef DEF_VALUE
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 00abee48821ff..8438cb84a35bb 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -747,6 +747,38 @@ void StoreInst::dump() const {
}
#endif // NDEBUG
+UnreachableInst *UnreachableInst::create(Instruction *InsertBefore,
+ Context &Ctx) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ Builder.SetInsertPoint(cast<llvm::Instruction>(InsertBefore->Val));
+ llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
+ return Ctx.createUnreachableInst(NewUI);
+}
+
+UnreachableInst *UnreachableInst::create(BasicBlock *InsertAtEnd,
+ Context &Ctx) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
+ llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
+ return Ctx.createUnreachableInst(NewUI);
+}
+
+bool UnreachableInst::classof(const Value *From) {
+ return From->getSubclassID() == ClassID::Unreachable;
+}
+
+#ifndef NDEBUG
+void UnreachableInst::dump(raw_ostream &OS) const {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+}
+
+void UnreachableInst::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
Context &Ctx) {
llvm::ReturnInst *NewRI;
@@ -1522,6 +1554,12 @@ CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) {
return cast<CallBrInst>(registerValue(std::move(NewPtr)));
}
+UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) {
+ auto NewPtr =
+ std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
+ return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
+}
+
GetElementPtrInst *
Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
auto NewPtr =
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 550c0576e0237..a14992c530309 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2037,3 +2037,32 @@ define void @foo(i32 %arg) {
}
EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues());
}
+
+TEST_F(SandboxIRTest, UnreachableInst) {
+ parseIR(C, R"IR(
+define void @foo() {
+ ret void
+ unreachable
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Ret = &*It++;
+ auto *UI = cast<sandboxir::UnreachableInst>(&*It++);
+
+ EXPECT_TRUE(llvm::isa<sandboxir::UnreachableInst>(UI));
+
+ // Check create(InsertBefore)
+ sandboxir::UnreachableInst *NewUI =
+ sandboxir::UnreachableInst::create(/*InsertBefore=*/Ret, Ctx);
+ EXPECT_NE(NewUI, nullptr);
+ EXPECT_EQ(NewUI->getParent(), BB);
+ // Check create(InsertAtEnd)
+ sandboxir::UnreachableInst *NewUIEnd =
+ sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx);
+ EXPECT_NE(NewUIEnd, nullptr);
+ EXPECT_EQ(NewUIEnd->getParent(), BB);
+}
More information about the llvm-commits
mailing list