[llvm] 52a46bc - [SandboxIR] Implement StoreInst (#99707)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 20 14:22:09 PDT 2024
Author: vporpo
Date: 2024-07-20T14:22:05-07:00
New Revision: 52a46bc31de238f9d5ee3a8be2388781b2af56e4
URL: https://github.com/llvm/llvm-project/commit/52a46bc31de238f9d5ee3a8be2388781b2af56e4
DIFF: https://github.com/llvm/llvm-project/commit/52a46bc31de238f9d5ee3a8be2388781b2af56e4.diff
LOG: [SandboxIR] Implement StoreInst (#99707)
This patch adds the SandboxIR StoreInst instruction which mirrors
llvm::StoreInst.
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 f168fdf8b1056..dfffe5c96f1cf 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -76,6 +76,7 @@ class Context;
class Function;
class Instruction;
class LoadInst;
+class StoreInst;
class User;
class Value;
@@ -172,10 +173,11 @@ class Value {
/// order.
llvm::Value *Val = nullptr;
- friend class Context; // For getting `Val`.
- friend class User; // For getting `Val`.
- friend class Use; // For getting `Val`.
- friend class LoadInst; // For getting `Val`.
+ friend class Context; // For getting `Val`.
+ friend class User; // For getting `Val`.
+ friend class Use; // For getting `Val`.
+ friend class LoadInst; // For getting `Val`.
+ friend class StoreInst; // For getting `Val`.
/// All values point to the context.
Context &Ctx;
@@ -495,7 +497,8 @@ class Instruction : public sandboxir::User {
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
/// returns its topmost LLVM IR instruction.
llvm::Instruction *getTopmostLLVMInstruction() const;
- friend class LoadInst; // For getTopmostLLVMInstruction().
+ friend class LoadInst; // For getTopmostLLVMInstruction().
+ friend class StoreInst; // For getTopmostLLVMInstruction().
/// \Returns the LLVM IR Instructions that this SandboxIR maps to in program
/// order.
@@ -599,6 +602,43 @@ class LoadInst final : public Instruction {
#endif
};
+class StoreInst final : public Instruction {
+ /// Use StoreInst::create().
+ StoreInst(llvm::StoreInst *SI, Context &Ctx)
+ : Instruction(ClassID::Store, Opcode::Store, SI, Ctx) {}
+ friend Context; // for StoreInst()
+ 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:
+ unsigned getUseOperandNo(const Use &Use) const final {
+ return getUseOperandNoDefault(Use);
+ }
+ unsigned getNumOfIRInstrs() const final { return 1u; }
+ static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
+ Instruction *InsertBefore, Context &Ctx);
+ static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
+ BasicBlock *InsertAtEnd, Context &Ctx);
+ /// For isa/dyn_cast.
+ static bool classof(const Value *From);
+ Value *getValueOperand() const;
+ Value *getPointerOperand() const;
+ Align getAlign() const { return cast<llvm::StoreInst>(Val)->getAlign(); }
+ bool isSimple() const { return cast<llvm::StoreInst>(Val)->isSimple(); }
+ bool isUnordered() const { return cast<llvm::StoreInst>(Val)->isUnordered(); }
+#ifndef NDEBUG
+ void verify() const final {
+ assert(isa<llvm::StoreInst>(Val) && "Expected StoreInst!");
+ }
+ void dump(raw_ostream &OS) const override;
+ LLVM_DUMP_METHOD void dump() const override;
+#endif
+};
+
/// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
/// an OpaqueInstr.
class OpaqueInst : public sandboxir::Instruction {
@@ -734,6 +774,8 @@ class Context {
LoadInst *createLoadInst(llvm::LoadInst *LI);
friend LoadInst; // For createLoadInst()
+ StoreInst *createStoreInst(llvm::StoreInst *SI);
+ friend StoreInst; // For createStoreInst()
public:
Context(LLVMContext &LLVMCtx)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index e1ed3cdac6bba..90365ca7a1c45 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -26,6 +26,7 @@ DEF_USER(Constant, Constant)
// ClassID, Opcode(s), Class
DEF_INSTR(Opaque, OP(Opaque), OpaqueInst)
DEF_INSTR(Load, OP(Load), LoadInst)
+DEF_INSTR(Store, OP(Store), StoreInst)
#ifdef DEF_VALUE
#undef DEF_VALUE
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index d49ec0c91e599..209b677bafbb5 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -496,6 +496,50 @@ void LoadInst::dump() const {
dump(dbgs());
dbgs() << "\n";
}
+#endif // NDEBUG
+StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
+ Instruction *InsertBefore, Context &Ctx) {
+ llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ Builder.SetInsertPoint(BeforeIR);
+ auto *NewSI =
+ Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false);
+ auto *NewSBI = Ctx.createStoreInst(NewSI);
+ return NewSBI;
+}
+StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
+ BasicBlock *InsertAtEnd, Context &Ctx) {
+ auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->Val);
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ Builder.SetInsertPoint(InsertAtEndIR);
+ auto *NewSI =
+ Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false);
+ auto *NewSBI = Ctx.createStoreInst(NewSI);
+ return NewSBI;
+}
+
+bool StoreInst::classof(const Value *From) {
+ return From->getSubclassID() == ClassID::Store;
+}
+
+Value *StoreInst::getValueOperand() const {
+ return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
+}
+
+Value *StoreInst::getPointerOperand() const {
+ return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
+}
+
+#ifndef NDEBUG
+void StoreInst::dump(raw_ostream &OS) const {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+}
+
+void StoreInst::dump() const {
+ dump(dbgs());
+ dbgs() << "\n";
+}
void OpaqueInst::dump(raw_ostream &OS) const {
dumpCommonPrefix(OS);
@@ -619,6 +663,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
return It->second.get();
}
+ case llvm::Instruction::Store: {
+ auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
+ It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
+ return It->second.get();
+ }
default:
break;
}
@@ -642,6 +691,11 @@ LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {
return cast<LoadInst>(registerValue(std::move(NewPtr)));
}
+StoreInst *Context::createStoreInst(llvm::StoreInst *SI) {
+ auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
+ return cast<StoreInst>(registerValue(std::move(NewPtr)));
+}
+
Value *Context::getValue(llvm::Value *V) const {
auto It = LLVMValueToValueMap.find(V);
if (It != LLVMValueToValueMap.end())
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 04beb429502bc..054a81e9cf308 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -591,3 +591,36 @@ define void @foo(ptr %arg0, ptr %arg1) {
EXPECT_EQ(NewLd->getAlign(), 8);
EXPECT_EQ(NewLd->getName(), "NewLd");
}
+
+TEST_F(SandboxIRTest, StoreInst) {
+ parseIR(C, R"IR(
+define void @foo(i8 %val, ptr %ptr) {
+ store i8 %val, ptr %ptr, align 64
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *Val = F->getArg(0);
+ auto *Ptr = F->getArg(1);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *St = cast<sandboxir::StoreInst>(&*It++);
+ auto *Ret = &*It++;
+
+ // Check that the StoreInst has been created correctly.
+ // Check getPointerOperand()
+ EXPECT_EQ(St->getValueOperand(), Val);
+ EXPECT_EQ(St->getPointerOperand(), Ptr);
+ // Check getAlign()
+ EXPECT_EQ(St->getAlign(), 64);
+ // Check create(InsertBefore)
+ sandboxir::StoreInst *NewSt =
+ sandboxir::StoreInst::create(Val, Ptr, Align(8),
+ /*InsertBefore=*/Ret, Ctx);
+ EXPECT_EQ(NewSt->getType(), St->getType());
+ EXPECT_EQ(NewSt->getValueOperand(), Val);
+ EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
+ EXPECT_EQ(NewSt->getAlign(), 8);
+}
More information about the llvm-commits
mailing list