Skip to content

Commit e758e7c

Browse files
vporpotmsri
authored andcommitted
[SandboxIR] Add Instruction::isStackSaveRestoreIntrinsic() and isMemDepCandidate() (llvm#109212)
These are helper functions to be used by the vectorizer's dependency graph.
1 parent 5435f61 commit e758e7c

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@
105105
#include "llvm/IR/Function.h"
106106
#include "llvm/IR/IRBuilder.h"
107107
#include "llvm/IR/Instruction.h"
108+
#include "llvm/IR/IntrinsicInst.h"
109+
#include "llvm/IR/PatternMatch.h"
108110
#include "llvm/IR/User.h"
109111
#include "llvm/IR/Value.h"
110112
#include "llvm/SandboxIR/Tracker.h"
@@ -1943,6 +1945,26 @@ class Instruction : public sandboxir::User {
19431945
/// LangRef.html for the meaning of these flags.
19441946
void copyFastMathFlags(FastMathFlags FMF);
19451947

1948+
bool isStackSaveOrRestoreIntrinsic() const {
1949+
auto *I = cast<llvm::Instruction>(Val);
1950+
return match(I,
1951+
PatternMatch::m_Intrinsic<llvm::Intrinsic::stackrestore>()) ||
1952+
match(I, PatternMatch::m_Intrinsic<llvm::Intrinsic::stacksave>());
1953+
}
1954+
1955+
/// We consider \p I as a Memory Dependency Candidate instruction if it
1956+
/// reads/write memory or if it has side-effects. This is used by the
1957+
/// dependency graph.
1958+
bool isMemDepCandidate() const {
1959+
auto *I = cast<llvm::Instruction>(Val);
1960+
return I->mayReadOrWriteMemory() &&
1961+
(!isa<llvm::IntrinsicInst>(I) ||
1962+
(cast<llvm::IntrinsicInst>(I)->getIntrinsicID() !=
1963+
Intrinsic::sideeffect &&
1964+
cast<llvm::IntrinsicInst>(I)->getIntrinsicID() !=
1965+
Intrinsic::pseudoprobe));
1966+
}
1967+
19461968
#ifndef NDEBUG
19471969
void dumpOS(raw_ostream &OS) const override;
19481970
#endif

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,77 @@ define void @foo(i8 %v1) {
17021702
EXPECT_EQ(I0->getNextNode(), Ret);
17031703
}
17041704

1705+
TEST_F(SandboxIRTest, Instruction_isStackSaveOrRestoreIntrinsic) {
1706+
parseIR(C, R"IR(
1707+
declare void @llvm.sideeffect()
1708+
define void @foo(i8 %v1, ptr %ptr) {
1709+
%add = add i8 %v1, %v1
1710+
%stacksave = call ptr @llvm.stacksave()
1711+
call void @llvm.stackrestore(ptr %stacksave)
1712+
call void @llvm.sideeffect()
1713+
ret void
1714+
}
1715+
)IR");
1716+
llvm::Function *LLVMF = &*M->getFunction("foo");
1717+
sandboxir::Context Ctx(C);
1718+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
1719+
auto *BB = &*F->begin();
1720+
auto It = BB->begin();
1721+
auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
1722+
auto *StackSave = cast<sandboxir::CallInst>(&*It++);
1723+
auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
1724+
auto *Other = cast<sandboxir::CallInst>(&*It++);
1725+
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1726+
1727+
EXPECT_FALSE(Add->isStackSaveOrRestoreIntrinsic());
1728+
EXPECT_TRUE(StackSave->isStackSaveOrRestoreIntrinsic());
1729+
EXPECT_TRUE(StackRestore->isStackSaveOrRestoreIntrinsic());
1730+
EXPECT_FALSE(Other->isStackSaveOrRestoreIntrinsic());
1731+
EXPECT_FALSE(Ret->isStackSaveOrRestoreIntrinsic());
1732+
}
1733+
1734+
TEST_F(SandboxIRTest, Instruction_isMemDepCandidate) {
1735+
parseIR(C, R"IR(
1736+
declare void @llvm.fake.use(...)
1737+
declare void @llvm.sideeffect()
1738+
declare void @llvm.pseudoprobe(i64, i64, i32, i64)
1739+
declare void @bar()
1740+
define void @foo(i8 %v1, ptr %ptr) {
1741+
%add0 = add i8 %v1, %v1
1742+
%ld0 = load i8, ptr %ptr
1743+
store i8 %v1, ptr %ptr
1744+
call void @llvm.sideeffect()
1745+
call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
1746+
call void @llvm.fake.use(ptr %ptr)
1747+
call void @bar()
1748+
ret void
1749+
}
1750+
)IR");
1751+
llvm::Function *LLVMF = &*M->getFunction("foo");
1752+
sandboxir::Context Ctx(C);
1753+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
1754+
auto *Arg = F->getArg(0);
1755+
auto *BB = &*F->begin();
1756+
auto It = BB->begin();
1757+
auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
1758+
auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
1759+
auto *St0 = cast<sandboxir::StoreInst>(&*It++);
1760+
auto *SideEffect0 = cast<sandboxir::CallInst>(&*It++);
1761+
auto *PseudoProbe0 = cast<sandboxir::CallInst>(&*It++);
1762+
auto *OtherIntrinsic0 = cast<sandboxir::CallInst>(&*It++);
1763+
auto *CallBar = cast<sandboxir::CallInst>(&*It++);
1764+
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
1765+
1766+
EXPECT_FALSE(Add0->isMemDepCandidate());
1767+
EXPECT_TRUE(Ld0->isMemDepCandidate());
1768+
EXPECT_TRUE(St0->isMemDepCandidate());
1769+
EXPECT_FALSE(SideEffect0->isMemDepCandidate());
1770+
EXPECT_FALSE(PseudoProbe0->isMemDepCandidate());
1771+
EXPECT_TRUE(OtherIntrinsic0->isMemDepCandidate());
1772+
EXPECT_TRUE(CallBar->isMemDepCandidate());
1773+
EXPECT_FALSE(Ret->isMemDepCandidate());
1774+
}
1775+
17051776
TEST_F(SandboxIRTest, VAArgInst) {
17061777
parseIR(C, R"IR(
17071778
define void @foo(ptr %va) {

0 commit comments

Comments
 (0)