[llvm] [SandboxIR] Implement UnreachableInst (PR #101856)
Julius Alexandre via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 4 19:08:59 PDT 2024
https://github.com/medievalghoul updated https://github.com/llvm/llvm-project/pull/101856
>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 1/8] [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);
+}
>From 3957c0b4cd66a5655b14310d2b42b72c42f1394b Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sat, 3 Aug 2024 20:29:46 -0400
Subject: [PATCH 2/8] removed space
---
llvm/include/llvm/SandboxIR/SandboxIRValues.def | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 61c5f7d79412d..2bf27b807bf80 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -61,7 +61,6 @@ DEF_INSTR(Cast, OPCODES(\
DEF_INSTR(PHI, OP(PHI), PHINode)
DEF_INSTR(Unreachable, OP(Unreachable), UnreachableInst)
-
// clang-format on
#ifdef DEF_VALUE
#undef DEF_VALUE
>From ceefe83fce37aedda1f958fd56dc8e7940574790 Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sun, 4 Aug 2024 00:54:25 -0400
Subject: [PATCH 3/8] remove some code
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 10 +---------
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 1 -
2 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index bbe4ea5dd8d24..98ad750453e06 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -959,10 +959,8 @@ class StoreInst final : public Instruction {
class UnreachableInst final : public Instruction {
/// Use UnreachableInst::create() instead of calling the constructor.
- UnreachableInst(llvm::Instruction *I, Context &Ctx)
+ UnreachableInst(llvm::UnreachableInst *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);
@@ -976,12 +974,6 @@ class UnreachableInst final : public Instruction {
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);
}
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index a14992c530309..4814d9f6776c8 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2054,7 +2054,6 @@ define void @foo() {
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);
>From 976e5006ac51898e38f244aac9666008e13b8f39 Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sun, 4 Aug 2024 01:37:46 -0400
Subject: [PATCH 4/8] fixed some code
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 2 +-
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 98ad750453e06..886c6ef061685 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -975,7 +975,7 @@ class UnreachableInst final : public Instruction {
static bool classof(const Value *From);
unsigned getNumSuccessors() const { return 0; }
unsigned getUseOperandNo(const Use &Use) const final {
- return getUseOperandNoDefault(Use);
+ llvm_unreachable("UnreachableInst has no operands!");
}
unsigned getNumOfIRInstrs() const final { return 1u; }
#ifndef NDEBUG
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 4814d9f6776c8..30c4947dc8347 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2053,7 +2053,8 @@ define void @foo() {
auto *Ret = &*It++;
auto *UI = cast<sandboxir::UnreachableInst>(&*It++);
- EXPECT_TRUE(llvm::isa<sandboxir::UnreachableInst>(UI));
+ EXPECT_EQ(UI->getNumSuccessors(), 0u);
+ EXPECT_EQ(UI->getNumOfIRInstrs(), 1u);
// Check create(InsertBefore)
sandboxir::UnreachableInst *NewUI =
sandboxir::UnreachableInst::create(/*InsertBefore=*/Ret, Ctx);
>From 68f7c79694a84424138785fc6b1d9fbd8da043d6 Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sun, 4 Aug 2024 02:12:42 -0400
Subject: [PATCH 5/8] added to getOrCreateValueInternal
---
llvm/lib/SandboxIR/SandboxIR.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 8438cb84a35bb..b3506ab3c53e1 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1496,6 +1496,11 @@ 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;
}
>From 17631f81131c82e56e7a1205ea175be4021904bf Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sun, 4 Aug 2024 02:18:47 -0400
Subject: [PATCH 6/8] clang format
---
llvm/lib/SandboxIR/SandboxIR.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index b3506ab3c53e1..8f57415e9ace5 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1498,7 +1498,8 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
}
case llvm::Instruction::Unreachable: {
auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
- It->second = std::unique_ptr<UnreachableInst>(new UnreachableInst(LLVMUnreachable, *this));
+ It->second = std::unique_ptr<UnreachableInst>(
+ new UnreachableInst(LLVMUnreachable, *this));
return It->second.get();
}
default:
>From 7ec071d6373e3081f3aca5e753425024eff9f663 Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sun, 4 Aug 2024 21:18:45 -0400
Subject: [PATCH 7/8] fixed ir test
---
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 30c4947dc8347..f7345034251cd 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -2041,8 +2041,9 @@ define void @foo(i32 %arg) {
TEST_F(SandboxIRTest, UnreachableInst) {
parseIR(C, R"IR(
define void @foo() {
- ret void
+ call void @llvm.donothing()
unreachable
+ ret void
}
)IR");
llvm::Function *LLVMF = &*M->getFunction("foo");
@@ -2050,14 +2051,14 @@ define void @foo() {
sandboxir::Function *F = Ctx.createFunction(LLVMF);
auto *BB = &*F->begin();
auto It = BB->begin();
- auto *Ret = &*It++;
+ auto *CallInst = dyn_cast<sandboxir::CallInst>(&*It++);
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=*/Ret, Ctx);
+ sandboxir::UnreachableInst::create(/*InsertBefore=*/CallInst, Ctx);
EXPECT_NE(NewUI, nullptr);
EXPECT_EQ(NewUI->getParent(), BB);
// Check create(InsertAtEnd)
>From 3b409222a9df63eab29a9745003b013c25b5c186 Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Sun, 4 Aug 2024 22:08:45 -0400
Subject: [PATCH 8/8] simple fix
---
llvm/lib/SandboxIR/SandboxIR.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 8f57415e9ace5..0d18794d77cd1 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -750,7 +750,8 @@ void StoreInst::dump() const {
UnreachableInst *UnreachableInst::create(Instruction *InsertBefore,
Context &Ctx) {
auto &Builder = Ctx.getLLVMIRBuilder();
- Builder.SetInsertPoint(cast<llvm::Instruction>(InsertBefore->Val));
+ llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
+ Builder.SetInsertPoint(LLVMBefore);
llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
return Ctx.createUnreachableInst(NewUI);
}
More information about the llvm-commits
mailing list