[llvm] [SandboxIR] Add Instruction::isStackSaveRestoreIntrinsic() and isMemDepCandidate() (PR #109212)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 18 15:38:54 PDT 2024
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/109212
These are helper functions to be used by the vectorizer's dependency graph.
>From dbb3106ee9f7ce34d1ffec7a582761ad15ea79ec Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Wed, 18 Sep 2024 11:00:03 -0700
Subject: [PATCH] [SandboxIR] Add Instruction::isStackSaveRestoreIntrinsic()
and isMemDepCandidate()
These are helper functions to be used by the vectorizer's dependency graph.
---
llvm/include/llvm/SandboxIR/SandboxIR.h | 22 +++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 71 ++++++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index c01516aa9d31ac..0180f7112f2ab4 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -105,6 +105,8 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/SandboxIR/Tracker.h"
@@ -1943,6 +1945,26 @@ class Instruction : public sandboxir::User {
/// LangRef.html for the meaning of these flags.
void copyFastMathFlags(FastMathFlags FMF);
+ bool isStackSaveRestoreIntrinsic() const {
+ auto *I = cast<llvm::Instruction>(Val);
+ return match(I,
+ PatternMatch::m_Intrinsic<llvm::Intrinsic::stackrestore>()) ||
+ match(I, PatternMatch::m_Intrinsic<llvm::Intrinsic::stacksave>());
+ }
+
+ /// We consider \p I as a Memory Dependency Candidate instruction if it
+ /// reads/write memory or if it has side-effects. This is used by the
+ /// dependency graph.
+ bool isMemDepCandidate() const {
+ auto *I = cast<llvm::Instruction>(Val);
+ return I->mayReadOrWriteMemory() &&
+ (!isa<llvm::IntrinsicInst>(I) ||
+ (cast<llvm::IntrinsicInst>(I)->getIntrinsicID() !=
+ Intrinsic::sideeffect &&
+ cast<llvm::IntrinsicInst>(I)->getIntrinsicID() !=
+ Intrinsic::pseudoprobe));
+ }
+
#ifndef NDEBUG
void dumpOS(raw_ostream &OS) const override;
#endif
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 8807716a52738f..df4ed783fa376e 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1702,6 +1702,77 @@ define void @foo(i8 %v1) {
EXPECT_EQ(I0->getNextNode(), Ret);
}
+TEST_F(SandboxIRTest, Instruction_isStackSaveRestoreIntrinsic) {
+ parseIR(C, R"IR(
+declare void @llvm.sideeffect()
+define void @foo(i8 %v1, ptr %ptr) {
+ %add = add i8 %v1, %v1
+ %stacksave = call ptr @llvm.stacksave()
+ call void @llvm.stackrestore(ptr %stacksave)
+ call void @llvm.sideeffect()
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
+ auto *StackSave = cast<sandboxir::CallInst>(&*It++);
+ auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
+ auto *Other = cast<sandboxir::CallInst>(&*It++);
+ auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+
+ EXPECT_FALSE(Add->isStackSaveRestoreIntrinsic());
+ EXPECT_TRUE(StackSave->isStackSaveRestoreIntrinsic());
+ EXPECT_TRUE(StackRestore->isStackSaveRestoreIntrinsic());
+ EXPECT_FALSE(Other->isStackSaveRestoreIntrinsic());
+ EXPECT_FALSE(Ret->isStackSaveRestoreIntrinsic());
+}
+
+TEST_F(SandboxIRTest, Instruction_isMemDepCandidate) {
+ parseIR(C, R"IR(
+declare void @llvm.fake.use(...)
+declare void @llvm.sideeffect()
+declare void @llvm.pseudoprobe(i64, i64, i32, i64)
+declare void @bar()
+define void @foo(i8 %v1, ptr %ptr) {
+ %add0 = add i8 %v1, %v1
+ %ld0 = load i8, ptr %ptr
+ store i8 %v1, ptr %ptr
+ call void @llvm.sideeffect()
+ call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
+ call void @llvm.fake.use(ptr %ptr)
+ call void @bar()
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *Arg = F->getArg(0);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
+ auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
+ auto *St0 = cast<sandboxir::StoreInst>(&*It++);
+ auto *SideEffect0 = cast<sandboxir::CallInst>(&*It++);
+ auto *PseudoProbe0 = cast<sandboxir::CallInst>(&*It++);
+ auto *OtherIntrinsic0 = cast<sandboxir::CallInst>(&*It++);
+ auto *CallBar = cast<sandboxir::CallInst>(&*It++);
+ auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+
+ EXPECT_FALSE(Add0->isMemDepCandidate());
+ EXPECT_TRUE(Ld0->isMemDepCandidate());
+ EXPECT_TRUE(St0->isMemDepCandidate());
+ EXPECT_FALSE(SideEffect0->isMemDepCandidate());
+ EXPECT_FALSE(PseudoProbe0->isMemDepCandidate());
+ EXPECT_TRUE(OtherIntrinsic0->isMemDepCandidate());
+ EXPECT_TRUE(CallBar->isMemDepCandidate());
+ EXPECT_FALSE(Ret->isMemDepCandidate());
+}
+
TEST_F(SandboxIRTest, VAArgInst) {
parseIR(C, R"IR(
define void @foo(ptr %va) {
More information about the llvm-commits
mailing list