Skip to content
9 changes: 8 additions & 1 deletion llvm/include/llvm/SandboxIR/SandboxIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,8 @@ class LoadInst final : public Instruction {
public:
/// Return true if this is a load from a volatile memory location.
bool isVolatile() const { return cast<llvm::LoadInst>(Val)->isVolatile(); }
/// Specify whether this is a volatile load or not.
void setVolatile(bool V) { return cast<llvm::LoadInst>(Val)->setVolatile(V); }

unsigned getUseOperandNo(const Use &Use) const final {
return getUseOperandNoDefault(Use);
Expand Down Expand Up @@ -825,6 +827,11 @@ class StoreInst final : public Instruction {
public:
/// Return true if this is a store from a volatile memory location.
bool isVolatile() const { return cast<llvm::StoreInst>(Val)->isVolatile(); }
/// Specify whether this is a volatile store or not.
void setVolatile(bool V) {
return cast<llvm::StoreInst>(Val)->setVolatile(V);
}

unsigned getUseOperandNo(const Use &Use) const final {
return getUseOperandNoDefault(Use);
}
Expand Down Expand Up @@ -1334,7 +1341,7 @@ class CastInst : public Instruction {
/// constructor directly.
CastInst(llvm::CastInst *CI, Context &Ctx)
: Instruction(ClassID::Cast, getCastOpcode(CI->getOpcode()), CI, Ctx) {}
friend Context; // for SBCastInstruction()
friend Context; // for SBCastInstruction()
friend class PtrToInt; // For constructor.
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
return getOperandUseDefault(OpIdx, Verify);
Expand Down
19 changes: 19 additions & 0 deletions llvm/include/llvm/SandboxIR/Tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,25 @@ class CallBrInstSetIndirectDest : public IRChangeBase {
#endif
};

class SetVolatile : public IRChangeBase {
Instruction *Inst;
bool WasVolatile;
/// This could either be StoreInst or LoadInst
PointerUnion<StoreInst *, LoadInst *> InstUnion;

public:
SetVolatile(Instruction *I, bool WasVolatile, Tracker &Tracker);
void revert() final;
void accept() final {}
#ifndef NDEBUG
void dump(raw_ostream &OS) const final {
dumpCommon(OS);
OS << "SetVolatile";
}
LLVM_DUMP_METHOD void dump() const final;
#endif
};

class MoveInstr : public IRChangeBase {
/// The instruction that moved.
Instruction *MovedI;
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/SandboxIR/Tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,34 @@ void CallBrInstSetIndirectDest::dump() const {
}
#endif

SetVolatile::SetVolatile(Instruction *I, bool WasBool, Tracker &Tracker)
: IRChangeBase(Tracker), Inst(I) {
if (auto *Load = cast<llvm::LoadInst>(Inst)) {
WasVolatile = Load->isVolatile();
InstUnion = Load;
}
if (auto *Store = cast<llvm::StoreInst>(Inst)) {
WasVolatile = Store->isVolatile();
InstUnion = Store;
}
}

void SetVolatile::revert() {
if (llvm::LoadInst *Load = InstUnion.dyn_cast<llvm::LoadInst *>()) {
// It's a LoadInst
Load->setVolatile(WasVolatile);
} else if (llvm::StoreInst *Store = InstUnion.dyn_cast<llvm::StoreInst *>()) {
// It's a StoreInst
Store->setVolatile(WasVolatile);
}
}
#ifndef NDEBUG
void SetVolatile::dump() const {
dump(dbgs());
dbgs() << "\n";
}
#endif

MoveInstr::MoveInstr(Instruction *MovedI, Tracker &Tracker)
: IRChangeBase(Tracker), MovedI(MovedI) {
if (auto *NextI = MovedI->getNextNode())
Expand Down
33 changes: 33 additions & 0 deletions llvm/unittests/SandboxIR/SandboxIRTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ define void @foo(ptr %arg0, ptr %arg1) {
auto *Ld = cast<sandboxir::LoadInst>(&*It++);
auto *VLd = cast<sandboxir::LoadInst>(&*It++);
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
bool OrigVolatileValue;

// Check isVolatile()
EXPECT_FALSE(Ld->isVolatile());
Expand All @@ -767,7 +768,10 @@ define void @foo(ptr %arg0, ptr %arg1) {
sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
/*InsertBefore=*/Ret, Ctx, "NewLd");
EXPECT_FALSE(NewLd->isVolatile());
OrigVolatileValue = NewLd->isVolatile();
NewLd->setVolatile(true);
EXPECT_EQ(NewLd->getType(), Ld->getType());
NewLd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
EXPECT_EQ(NewLd->getAlign(), 8);
EXPECT_EQ(NewLd->getName(), "NewLd");
Expand All @@ -778,12 +782,20 @@ define void @foo(ptr %arg0, ptr %arg1) {
/*IsVolatile=*/true, Ctx, "NewVLd");

EXPECT_TRUE(NewVLd->isVolatile());
OrigVolatileValue = NewVLd->isVolatile();
NewVLd->setVolatile(false);
EXPECT_FALSE(NewVLd->isVolatile());
NewVLd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewVLd->getName(), "NewVLd");
// Check create(InsertAtEnd)
sandboxir::LoadInst *NewLdEnd =
sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
/*InsertAtEnd=*/BB, Ctx, "NewLdEnd");
EXPECT_FALSE(NewLdEnd->isVolatile());
OrigVolatileValue = NewLdEnd->isVolatile();
NewLdEnd->setVolatile(true);
EXPECT_TRUE(NewLdEnd->isVolatile());
NewLdEnd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd");
EXPECT_EQ(NewLdEnd->getType(), Ld->getType());
EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1);
Expand All @@ -796,6 +808,10 @@ define void @foo(ptr %arg0, ptr %arg1) {
/*InsertAtEnd=*/BB,
/*IsVolatile=*/true, Ctx, "NewVLdEnd");
EXPECT_TRUE(NewVLdEnd->isVolatile());
OrigVolatileValue = NewVLdEnd->isVolatile();
NewVLdEnd->setVolatile(false);
EXPECT_FALSE(NewVLdEnd->isVolatile());
NewVLdEnd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewVLdEnd->getName(), "NewVLdEnd");
EXPECT_EQ(NewVLdEnd->getType(), VLd->getType());
EXPECT_EQ(NewVLdEnd->getPointerOperand(), Arg1);
Expand All @@ -822,6 +838,7 @@ define void @foo(i8 %val, ptr %ptr) {
auto *St = cast<sandboxir::StoreInst>(&*It++);
auto *VSt = cast<sandboxir::StoreInst>(&*It++);
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
bool OrigVolatileValue;

// Check that the StoreInst has been created correctly.
EXPECT_FALSE(St->isVolatile());
Expand All @@ -836,6 +853,10 @@ define void @foo(i8 %val, ptr %ptr) {
sandboxir::StoreInst::create(Val, Ptr, Align(8),
/*InsertBefore=*/Ret, Ctx);
EXPECT_FALSE(NewSt->isVolatile());
OrigVolatileValue = NewSt->isVolatile();
NewSt->setVolatile(true);
EXPECT_TRUE(NewSt->isVolatile());
NewSt->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewSt->getType(), St->getType());
EXPECT_EQ(NewSt->getValueOperand(), Val);
EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
Expand All @@ -847,6 +868,10 @@ define void @foo(i8 %val, ptr %ptr) {
/*InsertBefore=*/Ret,
/*IsVolatile=*/true, Ctx);
EXPECT_TRUE(NewVSt->isVolatile());
OrigVolatileValue = NewVSt->isVolatile();
NewVSt->setVolatile(false);
EXPECT_FALSE(NewVSt->isVolatile());
NewVSt->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewVSt->getType(), VSt->getType());
EXPECT_EQ(NewVSt->getValueOperand(), Val);
EXPECT_EQ(NewVSt->getPointerOperand(), Ptr);
Expand All @@ -857,6 +882,10 @@ define void @foo(i8 %val, ptr %ptr) {
sandboxir::StoreInst::create(Val, Ptr, Align(8),
/*InsertAtEnd=*/BB, Ctx);
EXPECT_FALSE(NewStEnd->isVolatile());
OrigVolatileValue = NewStEnd->isVolatile();
NewStEnd->setVolatile(true);
EXPECT_TRUE(NewStEnd->isVolatile());
NewStEnd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewStEnd->getType(), St->getType());
EXPECT_EQ(NewStEnd->getValueOperand(), Val);
EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr);
Expand All @@ -869,6 +898,10 @@ define void @foo(i8 %val, ptr %ptr) {
/*InsertAtEnd=*/BB,
/*IsVolatile=*/true, Ctx);
EXPECT_TRUE(NewVStEnd->isVolatile());
OrigVolatileValue = NewVStEnd->isVolatile();
NewVStEnd->setVolatile(false);
EXPECT_FALSE(NewVStEnd->isVolatile());
NewVStEnd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewVStEnd->getType(), VSt->getType());
EXPECT_EQ(NewVStEnd->getValueOperand(), Val);
EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr);
Expand Down