Skip to content

[SandboxIR] Implement UnreachableInst #101856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions llvm/include/llvm/SandboxIR/SandboxIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
// | +- CastInst
// |
// +- UnaryOperator
// |
// +- UnreachableInst
//
// Use
//
Expand Down Expand Up @@ -115,6 +117,7 @@ class LoadInst;
class ReturnInst;
class StoreInst;
class User;
class UnreachableInst;
class Value;
class CallBase;
class CallInst;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -952,6 +957,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)
Expand Down Expand Up @@ -1732,6 +1767,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)
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/SandboxIR/SandboxIRValues.def
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,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
Expand Down
45 changes: 45 additions & 0 deletions llvm/lib/SandboxIR/SandboxIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1464,6 +1497,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;
}
Expand Down Expand Up @@ -1522,6 +1561,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 =
Expand Down
26 changes: 26 additions & 0 deletions llvm/unittests/SandboxIR/SandboxIRTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2037,3 +2037,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);
}
Loading