[llvm] e546430 - [SandboxIR] Implement UnreachableInst (#101856)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 6 22:02:52 PDT 2024
Author: Julius Alexandre
Date: 2024-08-06T22:02:49-07:00
New Revision: e546430959dfe2bc02685eb1d3601bd3f2e5321c
URL: https://github.com/llvm/llvm-project/commit/e546430959dfe2bc02685eb1d3601bd3f2e5321c
DIFF: https://github.com/llvm/llvm-project/commit/e546430959dfe2bc02685eb1d3601bd3f2e5321c.diff
LOG: [SandboxIR] Implement UnreachableInst (#101856)
This patch implements the `UnreachableInst` instruction in SandboxIR. Mirroring `llvm::UnreachableInst`.
Added:
Modified:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/include/llvm/SandboxIR/SandboxIRValues.def
llvm/lib/SandboxIR/SandboxIR.cpp
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 7765e7d5891413..12ecd304ce8336 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;
@@ -244,6 +247,7 @@ class Value {
friend class AllocaInst; // 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;
@@ -638,6 +642,7 @@ class Instruction : public sandboxir::User {
friend class AllocaInst; // 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.
@@ -955,6 +960,36 @@ class StoreInst final : public Instruction {
#endif
};
+class UnreachableInst final : public Instruction {
+ /// Use UnreachableInst::create() instead of calling the constructor.
+ UnreachableInst(llvm::UnreachableInst *I, Context &Ctx)
+ : Instruction(ClassID::Unreachable, 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; }
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("UnreachableInst has no operands!");
+ }
+ 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)
@@ -1832,6 +1867,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 3b16bdee6d15cf..dda629fcfc747e 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -60,7 +60,8 @@ 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 70d8f8ba068d97..d1d238f9608c48 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -747,6 +747,39 @@ void StoreInst::dump() const {
}
#endif // NDEBUG
+UnreachableInst *UnreachableInst::create(Instruction *InsertBefore,
+ Context &Ctx) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
+ Builder.SetInsertPoint(LLVMBefore);
+ 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;
@@ -1562,6 +1595,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
return It->second.get();
}
+ case llvm::Instruction::Unreachable: {
+ auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
+ It->second = std::unique_ptr<UnreachableInst>(
+ new UnreachableInst(LLVMUnreachable, *this));
+ return It->second.get();
+ }
default:
break;
}
@@ -1620,6 +1659,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 cbc63a118773ba..f4b23784dc36bc 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2207,3 +2207,29 @@ define void @foo(i32 %arg) {
}
EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues());
}
+
+TEST_F(SandboxIRTest, UnreachableInst) {
+ parseIR(C, R"IR(
+define void @foo() {
+ 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 *UI = cast<sandboxir::UnreachableInst>(&*It++);
+
+ EXPECT_EQ(UI->getNumSuccessors(), 0u);
+ EXPECT_EQ(UI->getNumOfIRInstrs(), 1u);
+ // Check create(InsertBefore)
+ sandboxir::UnreachableInst *NewUI =
+ sandboxir::UnreachableInst::create(/*InsertBefore=*/UI, Ctx);
+ EXPECT_EQ(NewUI->getNextNode(), UI);
+ // Check create(InsertAtEnd)
+ sandboxir::UnreachableInst *NewUIEnd =
+ sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx);
+ EXPECT_EQ(NewUIEnd->getParent(), BB);
+ EXPECT_EQ(NewUIEnd->getNextNode(), nullptr);
+}
More information about the llvm-commits
mailing list