[llvm] [SandboxIR] Added setVolatile function to LoadInst and StoreInst (PR #101759)
Julius Alexandre via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 2 16:42:35 PDT 2024
https://github.com/medievalghoul updated https://github.com/llvm/llvm-project/pull/101759
>From b661b196a77767b5df424b000deff8cd4806d50f Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Fri, 2 Aug 2024 13:57:29 -0400
Subject: [PATCH 1/3] [SandboxIR] Added setVolatile() function to LoadInst and
StoreInst
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 5 +++-
llvm/include/llvm/SandboxIR/Tracker.h | 21 +++++++++++++
llvm/lib/SandboxIR/SandboxIR.cpp | 15 ++++++++++
llvm/lib/SandboxIR/Tracker.cpp | 29 ++++++++++++++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 34 ++++++++++++++++++++++
llvm/unittests/SandboxIR/TrackerTest.cpp | 32 ++++++++++++++++++++
6 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 313b541ddcaca..ed0aaeb4f9a8e 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -870,7 +870,8 @@ class LoadInst final : public UnaryInstruction {
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);
unsigned getUseOperandNo(const Use &Use) const final {
return getUseOperandNoDefault(Use);
}
@@ -919,6 +920,8 @@ 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);
unsigned getUseOperandNo(const Use &Use) const final {
return getUseOperandNoDefault(Use);
}
diff --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
index 238e4e9dacd34..5cbab10028ebd 100644
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ b/llvm/include/llvm/SandboxIR/Tracker.h
@@ -54,6 +54,8 @@ namespace llvm::sandboxir {
class BasicBlock;
class CallBrInst;
+class LoadInst;
+class StoreInst;
class Instruction;
class Tracker;
@@ -271,6 +273,25 @@ class CallBrInstSetIndirectDest : public IRChangeBase {
#endif
};
+class SetVolatile : public IRChangeBase {
+ /// This holds the properties of whether LoadInst or StoreInst was volatile
+ bool WasVolatile;
+ /// This could either be StoreInst or LoadInst
+ PointerUnion<StoreInst *, LoadInst *> StoreOrLoad;
+
+public:
+ SetVolatile(Instruction *I, 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;
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index a67cb2a5bb25a..faf1e8ed0e3ce 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -610,6 +610,13 @@ void BranchInst::dump() const {
}
#endif // NDEBUG
+void LoadInst::setVolatile(bool V) {
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(std::make_unique<SetVolatile>(this, Tracker));
+ cast<llvm::LoadInst>(Val)->setVolatile(V);
+}
+
LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
Instruction *InsertBefore, Context &Ctx,
const Twine &Name) {
@@ -664,6 +671,14 @@ void LoadInst::dump() const {
dbgs() << "\n";
}
#endif // NDEBUG
+
+void StoreInst::setVolatile(bool V) {
+ auto &Tracker = Ctx.getTracker();
+ if (Tracker.isTracking())
+ Tracker.track(std::make_unique<SetVolatile>(this, Tracker));
+ cast<llvm::StoreInst>(Val)->setVolatile(V);
+}
+
StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
Instruction *InsertBefore, Context &Ctx) {
return create(V, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx);
diff --git a/llvm/lib/SandboxIR/Tracker.cpp b/llvm/lib/SandboxIR/Tracker.cpp
index 0310160e8bf35..f587c96f15787 100644
--- a/llvm/lib/SandboxIR/Tracker.cpp
+++ b/llvm/lib/SandboxIR/Tracker.cpp
@@ -235,6 +235,35 @@ void CallBrInstSetIndirectDest::dump() const {
}
#endif
+SetVolatile::SetVolatile(Instruction *I, Tracker &Tracker)
+ : IRChangeBase(Tracker) {
+ if (auto *Load = dyn_cast<LoadInst>(I)) {
+ WasVolatile = Load->isVolatile();
+ StoreOrLoad = Load;
+ } else if (auto *Store = dyn_cast<StoreInst>(I)) {
+ WasVolatile = Store->isVolatile();
+ StoreOrLoad = Store;
+ } else {
+ llvm_unreachable("Expected LoadInst or StoreInst");
+ }
+}
+
+void SetVolatile::revert() {
+ if (auto *Load = StoreOrLoad.dyn_cast<LoadInst *>()) {
+ Load->setVolatile(WasVolatile);
+ } else if (auto *Store = StoreOrLoad.dyn_cast<StoreInst *>()) {
+ Store->setVolatile(WasVolatile);
+ } else {
+ llvm_unreachable("Expected LoadInst or StoreInst");
+ }
+}
+#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())
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index bc4e97c48bffe..53e84f351b076 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -754,6 +754,7 @@ define void @foo(ptr %arg0, ptr %arg1) {
EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld));
auto *VLd = cast<sandboxir::LoadInst>(&*It++);
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+ bool OrigVolatileValue;
// Check isVolatile()
EXPECT_FALSE(Ld->isVolatile());
@@ -768,6 +769,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_TRUE(NewLd->isVolatile());
+ NewLd->setVolatile(OrigVolatileValue);
EXPECT_EQ(NewLd->getType(), Ld->getType());
EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
EXPECT_EQ(NewLd->getAlign(), 8);
@@ -779,12 +784,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);
@@ -797,6 +810,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);
@@ -823,6 +840,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());
@@ -837,6 +855,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);
@@ -848,6 +870,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);
@@ -858,6 +884,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);
@@ -870,6 +900,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);
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index d016c7793a52c..2775739900ded 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -708,3 +708,35 @@ define void @foo(i8 %arg0, i8 %arg1, i8 %arg2) {
EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
}
+
+TEST_F(TrackerTest, SetVolatile) {
+ parseIR(C, R"IR(
+define void @foo(ptr %arg0, i8 %val) {
+ %ld = load i8, ptr %arg0, align 64
+ store i8 %val, ptr %arg0, align 64
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+
+ auto *F = Ctx.createFunction(&LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Load = cast<sandboxir::LoadInst>(&*It++);
+ auto *Store = cast<sandboxir::StoreInst>(&*It++);
+
+ EXPECT_FALSE(Load->isVolatile());
+ EXPECT_FALSE(Store->isVolatile());
+ Ctx.save();
+ Load->setVolatile(true);
+ EXPECT_TRUE(Load->isVolatile());
+ Ctx.revert();
+ EXPECT_FALSE(Load->isVolatile());
+
+ Ctx.save();
+ Store->setVolatile(true);
+ EXPECT_TRUE(Store->isVolatile());
+ Ctx.revert();
+ EXPECT_FALSE(Store->isVolatile());
+}
>From 453d44ec949d212ed4a7d976612270f91b773cec Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Fri, 2 Aug 2024 18:05:29 -0400
Subject: [PATCH 2/3] added more checks
---
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 53e84f351b076..0102ded408a4c 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -773,6 +773,7 @@ define void @foo(ptr %arg0, ptr %arg1) {
NewLd->setVolatile(true);
EXPECT_TRUE(NewLd->isVolatile());
NewLd->setVolatile(OrigVolatileValue);
+ EXPECT_FALSE(NewLd->isVolatile());
EXPECT_EQ(NewLd->getType(), Ld->getType());
EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
EXPECT_EQ(NewLd->getAlign(), 8);
@@ -788,6 +789,7 @@ define void @foo(ptr %arg0, ptr %arg1) {
NewVLd->setVolatile(false);
EXPECT_FALSE(NewVLd->isVolatile());
NewVLd->setVolatile(OrigVolatileValue);
+ EXPECT_TRUE(NewVLd->isVolatile());
EXPECT_EQ(NewVLd->getName(), "NewVLd");
// Check create(InsertAtEnd)
sandboxir::LoadInst *NewLdEnd =
@@ -798,6 +800,7 @@ define void @foo(ptr %arg0, ptr %arg1) {
NewLdEnd->setVolatile(true);
EXPECT_TRUE(NewLdEnd->isVolatile());
NewLdEnd->setVolatile(OrigVolatileValue);
+ EXPECT_FALSE(NewLdEnd->isVolatile());
EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd");
EXPECT_EQ(NewLdEnd->getType(), Ld->getType());
EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1);
@@ -859,6 +862,7 @@ define void @foo(i8 %val, ptr %ptr) {
NewSt->setVolatile(true);
EXPECT_TRUE(NewSt->isVolatile());
NewSt->setVolatile(OrigVolatileValue);
+ EXPECT_FALSE(NewSt->isVolatile());
EXPECT_EQ(NewSt->getType(), St->getType());
EXPECT_EQ(NewSt->getValueOperand(), Val);
EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
@@ -874,6 +878,7 @@ define void @foo(i8 %val, ptr %ptr) {
NewVSt->setVolatile(false);
EXPECT_FALSE(NewVSt->isVolatile());
NewVSt->setVolatile(OrigVolatileValue);
+ EXPECT_TRUE(NewVSt->isVolatile());
EXPECT_EQ(NewVSt->getType(), VSt->getType());
EXPECT_EQ(NewVSt->getValueOperand(), Val);
EXPECT_EQ(NewVSt->getPointerOperand(), Ptr);
@@ -888,6 +893,7 @@ define void @foo(i8 %val, ptr %ptr) {
NewStEnd->setVolatile(true);
EXPECT_TRUE(NewStEnd->isVolatile());
NewStEnd->setVolatile(OrigVolatileValue);
+ EXPECT_FALSE(NewStEnd->isVolatile());
EXPECT_EQ(NewStEnd->getType(), St->getType());
EXPECT_EQ(NewStEnd->getValueOperand(), Val);
EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr);
@@ -904,6 +910,7 @@ define void @foo(i8 %val, ptr %ptr) {
NewVStEnd->setVolatile(false);
EXPECT_FALSE(NewVStEnd->isVolatile());
NewVStEnd->setVolatile(OrigVolatileValue);
+ EXPECT_TRUE(NewVStEnd->isVolatile());
EXPECT_EQ(NewVStEnd->getType(), VSt->getType());
EXPECT_EQ(NewVStEnd->getValueOperand(), Val);
EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr);
>From 6152c41e4a3299ecf91f973b8646bed391486f04 Mon Sep 17 00:00:00 2001
From: medievalghoul <61852278+medievalghoul at users.noreply.github.com>
Date: Fri, 2 Aug 2024 19:42:21 -0400
Subject: [PATCH 3/3] simple fix
---
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 0102ded408a4c..550c0576e0237 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -796,11 +796,6 @@ define void @foo(ptr %arg0, ptr %arg1) {
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_FALSE(NewLdEnd->isVolatile());
EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd");
EXPECT_EQ(NewLdEnd->getType(), Ld->getType());
EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1);
@@ -813,10 +808,6 @@ 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);
@@ -889,11 +880,6 @@ 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_FALSE(NewStEnd->isVolatile());
EXPECT_EQ(NewStEnd->getType(), St->getType());
EXPECT_EQ(NewStEnd->getValueOperand(), Val);
EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr);
@@ -906,11 +892,6 @@ 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_TRUE(NewVStEnd->isVolatile());
EXPECT_EQ(NewVStEnd->getType(), VSt->getType());
EXPECT_EQ(NewVStEnd->getValueOperand(), Val);
EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr);
More information about the llvm-commits
mailing list