diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h index 667aeba1bda1f..f76ee1b64d3ca 100644 --- a/llvm/include/llvm/SandboxIR/SandboxIR.h +++ b/llvm/include/llvm/SandboxIR/SandboxIR.h @@ -804,14 +804,22 @@ class StoreInst final : public Instruction { } public: + /// Return true if this is a store from a volatile memory location. + bool isVolatile() const { return cast(Val)->isVolatile(); } 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, + Instruction *InsertBefore, bool IsVolatile, + Context &Ctx); static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align, BasicBlock *InsertAtEnd, Context &Ctx); + static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align, + BasicBlock *InsertAtEnd, bool IsVolatile, + Context &Ctx); /// For isa/dyn_cast. static bool classof(const Value *From); Value *getValueOperand() const; diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp index d2b4fb207ba3a..efcb1b74a5320 100644 --- a/llvm/lib/SandboxIR/SandboxIR.cpp +++ b/llvm/lib/SandboxIR/SandboxIR.cpp @@ -654,21 +654,32 @@ void LoadInst::dump() const { #endif // NDEBUG StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx) { + return create(V, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx); +} + +StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, + Instruction *InsertBefore, bool IsVolatile, + 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 *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile); auto *NewSBI = Ctx.createStoreInst(NewSI); return NewSBI; } + StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, BasicBlock *InsertAtEnd, Context &Ctx) { + return create(V, Ptr, Align, InsertAtEnd, /*IsVolatile=*/false, Ctx); +} + +StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, + BasicBlock *InsertAtEnd, bool IsVolatile, + Context &Ctx) { auto *InsertAtEndIR = cast(InsertAtEnd->Val); auto &Builder = Ctx.getLLVMIRBuilder(); Builder.SetInsertPoint(InsertAtEndIR); - auto *NewSI = - Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false); + auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile); auto *NewSBI = Ctx.createStoreInst(NewSI); return NewSBI; } diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp index 122508d15194f..e2c1b3c5bb845 100644 --- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp +++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp @@ -787,6 +787,7 @@ TEST_F(SandboxIRTest, StoreInst) { parseIR(C, R"IR( define void @foo(i8 %val, ptr %ptr) { store i8 %val, ptr %ptr, align 64 + store volatile i8 %val, ptr %ptr, align 64 ret void } )IR"); @@ -798,9 +799,12 @@ define void @foo(i8 %val, ptr %ptr) { auto *BB = &*F->begin(); auto It = BB->begin(); auto *St = cast(&*It++); + auto *VSt = cast(&*It++); auto *Ret = cast(&*It++); // Check that the StoreInst has been created correctly. + EXPECT_FALSE(St->isVolatile()); + EXPECT_TRUE(VSt->isVolatile()); // Check getPointerOperand() EXPECT_EQ(St->getValueOperand(), Val); EXPECT_EQ(St->getPointerOperand(), Ptr); @@ -810,10 +814,46 @@ define void @foo(i8 %val, ptr %ptr) { sandboxir::StoreInst *NewSt = sandboxir::StoreInst::create(Val, Ptr, Align(8), /*InsertBefore=*/Ret, Ctx); + EXPECT_FALSE(NewSt->isVolatile()); EXPECT_EQ(NewSt->getType(), St->getType()); EXPECT_EQ(NewSt->getValueOperand(), Val); EXPECT_EQ(NewSt->getPointerOperand(), Ptr); EXPECT_EQ(NewSt->getAlign(), 8); + EXPECT_EQ(NewSt->getNextNode(), Ret); + // Check create(InsertBefore, IsVolatile=true) + sandboxir::StoreInst *NewVSt = + sandboxir::StoreInst::create(Val, Ptr, Align(8), + /*InsertBefore=*/Ret, + /*IsVolatile=*/true, Ctx); + EXPECT_TRUE(NewVSt->isVolatile()); + EXPECT_EQ(NewVSt->getType(), VSt->getType()); + EXPECT_EQ(NewVSt->getValueOperand(), Val); + EXPECT_EQ(NewVSt->getPointerOperand(), Ptr); + EXPECT_EQ(NewVSt->getAlign(), 8); + EXPECT_EQ(NewVSt->getNextNode(), Ret); + // Check create(InsertAtEnd) + sandboxir::StoreInst *NewStEnd = + sandboxir::StoreInst::create(Val, Ptr, Align(8), + /*InsertAtEnd=*/BB, Ctx); + EXPECT_FALSE(NewStEnd->isVolatile()); + EXPECT_EQ(NewStEnd->getType(), St->getType()); + EXPECT_EQ(NewStEnd->getValueOperand(), Val); + EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr); + EXPECT_EQ(NewStEnd->getAlign(), 8); + EXPECT_EQ(NewStEnd->getParent(), BB); + EXPECT_EQ(NewStEnd->getNextNode(), nullptr); + // Check create(InsertAtEnd, IsVolatile=true) + sandboxir::StoreInst *NewVStEnd = + sandboxir::StoreInst::create(Val, Ptr, Align(8), + /*InsertAtEnd=*/BB, + /*IsVolatile=*/true, Ctx); + EXPECT_TRUE(NewVStEnd->isVolatile()); + EXPECT_EQ(NewVStEnd->getType(), VSt->getType()); + EXPECT_EQ(NewVStEnd->getValueOperand(), Val); + EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr); + EXPECT_EQ(NewVStEnd->getAlign(), 8); + EXPECT_EQ(NewVStEnd->getParent(), BB); + EXPECT_EQ(NewVStEnd->getNextNode(), nullptr); } TEST_F(SandboxIRTest, ReturnInst) {