Skip to content

Commit 52a46bc

Browse files
authored
[SandboxIR] Implement StoreInst (#99707)
This patch adds the SandboxIR StoreInst instruction which mirrors llvm::StoreInst.
1 parent 28045ce commit 52a46bc

File tree

4 files changed

+135
-5
lines changed

4 files changed

+135
-5
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class Context;
7676
class Function;
7777
class Instruction;
7878
class LoadInst;
79+
class StoreInst;
7980
class User;
8081
class Value;
8182

@@ -172,10 +173,11 @@ class Value {
172173
/// order.
173174
llvm::Value *Val = nullptr;
174175

175-
friend class Context; // For getting `Val`.
176-
friend class User; // For getting `Val`.
177-
friend class Use; // For getting `Val`.
178-
friend class LoadInst; // For getting `Val`.
176+
friend class Context; // For getting `Val`.
177+
friend class User; // For getting `Val`.
178+
friend class Use; // For getting `Val`.
179+
friend class LoadInst; // For getting `Val`.
180+
friend class StoreInst; // For getting `Val`.
179181

180182
/// All values point to the context.
181183
Context &Ctx;
@@ -495,7 +497,8 @@ class Instruction : public sandboxir::User {
495497
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
496498
/// returns its topmost LLVM IR instruction.
497499
llvm::Instruction *getTopmostLLVMInstruction() const;
498-
friend class LoadInst; // For getTopmostLLVMInstruction().
500+
friend class LoadInst; // For getTopmostLLVMInstruction().
501+
friend class StoreInst; // For getTopmostLLVMInstruction().
499502

500503
/// \Returns the LLVM IR Instructions that this SandboxIR maps to in program
501504
/// order.
@@ -599,6 +602,43 @@ class LoadInst final : public Instruction {
599602
#endif
600603
};
601604

605+
class StoreInst final : public Instruction {
606+
/// Use StoreInst::create().
607+
StoreInst(llvm::StoreInst *SI, Context &Ctx)
608+
: Instruction(ClassID::Store, Opcode::Store, SI, Ctx) {}
609+
friend Context; // for StoreInst()
610+
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
611+
return getOperandUseDefault(OpIdx, Verify);
612+
}
613+
SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
614+
return {cast<llvm::Instruction>(Val)};
615+
}
616+
617+
public:
618+
unsigned getUseOperandNo(const Use &Use) const final {
619+
return getUseOperandNoDefault(Use);
620+
}
621+
unsigned getNumOfIRInstrs() const final { return 1u; }
622+
static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
623+
Instruction *InsertBefore, Context &Ctx);
624+
static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
625+
BasicBlock *InsertAtEnd, Context &Ctx);
626+
/// For isa/dyn_cast.
627+
static bool classof(const Value *From);
628+
Value *getValueOperand() const;
629+
Value *getPointerOperand() const;
630+
Align getAlign() const { return cast<llvm::StoreInst>(Val)->getAlign(); }
631+
bool isSimple() const { return cast<llvm::StoreInst>(Val)->isSimple(); }
632+
bool isUnordered() const { return cast<llvm::StoreInst>(Val)->isUnordered(); }
633+
#ifndef NDEBUG
634+
void verify() const final {
635+
assert(isa<llvm::StoreInst>(Val) && "Expected StoreInst!");
636+
}
637+
void dump(raw_ostream &OS) const override;
638+
LLVM_DUMP_METHOD void dump() const override;
639+
#endif
640+
};
641+
602642
/// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
603643
/// an OpaqueInstr.
604644
class OpaqueInst : public sandboxir::Instruction {
@@ -734,6 +774,8 @@ class Context {
734774

735775
LoadInst *createLoadInst(llvm::LoadInst *LI);
736776
friend LoadInst; // For createLoadInst()
777+
StoreInst *createStoreInst(llvm::StoreInst *SI);
778+
friend StoreInst; // For createStoreInst()
737779

738780
public:
739781
Context(LLVMContext &LLVMCtx)

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ DEF_USER(Constant, Constant)
2626
// ClassID, Opcode(s), Class
2727
DEF_INSTR(Opaque, OP(Opaque), OpaqueInst)
2828
DEF_INSTR(Load, OP(Load), LoadInst)
29+
DEF_INSTR(Store, OP(Store), StoreInst)
2930

3031
#ifdef DEF_VALUE
3132
#undef DEF_VALUE

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,50 @@ void LoadInst::dump() const {
496496
dump(dbgs());
497497
dbgs() << "\n";
498498
}
499+
#endif // NDEBUG
500+
StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
501+
Instruction *InsertBefore, Context &Ctx) {
502+
llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
503+
auto &Builder = Ctx.getLLVMIRBuilder();
504+
Builder.SetInsertPoint(BeforeIR);
505+
auto *NewSI =
506+
Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false);
507+
auto *NewSBI = Ctx.createStoreInst(NewSI);
508+
return NewSBI;
509+
}
510+
StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
511+
BasicBlock *InsertAtEnd, Context &Ctx) {
512+
auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->Val);
513+
auto &Builder = Ctx.getLLVMIRBuilder();
514+
Builder.SetInsertPoint(InsertAtEndIR);
515+
auto *NewSI =
516+
Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false);
517+
auto *NewSBI = Ctx.createStoreInst(NewSI);
518+
return NewSBI;
519+
}
520+
521+
bool StoreInst::classof(const Value *From) {
522+
return From->getSubclassID() == ClassID::Store;
523+
}
524+
525+
Value *StoreInst::getValueOperand() const {
526+
return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
527+
}
528+
529+
Value *StoreInst::getPointerOperand() const {
530+
return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
531+
}
532+
533+
#ifndef NDEBUG
534+
void StoreInst::dump(raw_ostream &OS) const {
535+
dumpCommonPrefix(OS);
536+
dumpCommonSuffix(OS);
537+
}
538+
539+
void StoreInst::dump() const {
540+
dump(dbgs());
541+
dbgs() << "\n";
542+
}
499543

500544
void OpaqueInst::dump(raw_ostream &OS) const {
501545
dumpCommonPrefix(OS);
@@ -619,6 +663,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
619663
It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
620664
return It->second.get();
621665
}
666+
case llvm::Instruction::Store: {
667+
auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
668+
It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
669+
return It->second.get();
670+
}
622671
default:
623672
break;
624673
}
@@ -642,6 +691,11 @@ LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {
642691
return cast<LoadInst>(registerValue(std::move(NewPtr)));
643692
}
644693

694+
StoreInst *Context::createStoreInst(llvm::StoreInst *SI) {
695+
auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
696+
return cast<StoreInst>(registerValue(std::move(NewPtr)));
697+
}
698+
645699
Value *Context::getValue(llvm::Value *V) const {
646700
auto It = LLVMValueToValueMap.find(V);
647701
if (It != LLVMValueToValueMap.end())

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,36 @@ define void @foo(ptr %arg0, ptr %arg1) {
591591
EXPECT_EQ(NewLd->getAlign(), 8);
592592
EXPECT_EQ(NewLd->getName(), "NewLd");
593593
}
594+
595+
TEST_F(SandboxIRTest, StoreInst) {
596+
parseIR(C, R"IR(
597+
define void @foo(i8 %val, ptr %ptr) {
598+
store i8 %val, ptr %ptr, align 64
599+
ret void
600+
}
601+
)IR");
602+
llvm::Function *LLVMF = &*M->getFunction("foo");
603+
sandboxir::Context Ctx(C);
604+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
605+
auto *Val = F->getArg(0);
606+
auto *Ptr = F->getArg(1);
607+
auto *BB = &*F->begin();
608+
auto It = BB->begin();
609+
auto *St = cast<sandboxir::StoreInst>(&*It++);
610+
auto *Ret = &*It++;
611+
612+
// Check that the StoreInst has been created correctly.
613+
// Check getPointerOperand()
614+
EXPECT_EQ(St->getValueOperand(), Val);
615+
EXPECT_EQ(St->getPointerOperand(), Ptr);
616+
// Check getAlign()
617+
EXPECT_EQ(St->getAlign(), 64);
618+
// Check create(InsertBefore)
619+
sandboxir::StoreInst *NewSt =
620+
sandboxir::StoreInst::create(Val, Ptr, Align(8),
621+
/*InsertBefore=*/Ret, Ctx);
622+
EXPECT_EQ(NewSt->getType(), St->getType());
623+
EXPECT_EQ(NewSt->getValueOperand(), Val);
624+
EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
625+
EXPECT_EQ(NewSt->getAlign(), 8);
626+
}

0 commit comments

Comments
 (0)