[llvm] [SandboxIR] Implement IntrinsicInst (PR #110900)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 2 13:08:22 PDT 2024
https://github.com/vporpo updated https://github.com/llvm/llvm-project/pull/110900
>From b17e26b65915e79c6e6ce160e203db115efde942 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Wed, 2 Oct 2024 10:20:13 -0700
Subject: [PATCH] [SandboxIR] Implement IntrinsicInst
This patch implements sandboxir::IntrinsicInst mirroring llvm::IntrinsicInst.
---
llvm/include/llvm/SandboxIR/Instruction.h | 9 +-
llvm/include/llvm/SandboxIR/IntrinsicInst.h | 44 ++++++++++
llvm/include/llvm/SandboxIR/Value.h | 2 +
llvm/unittests/SandboxIR/CMakeLists.txt | 1 +
.../unittests/SandboxIR/IntrinsicInstTest.cpp | 88 +++++++++++++++++++
5 files changed, 141 insertions(+), 3 deletions(-)
create mode 100644 llvm/include/llvm/SandboxIR/IntrinsicInst.h
create mode 100644 llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
diff --git a/llvm/include/llvm/SandboxIR/Instruction.h b/llvm/include/llvm/SandboxIR/Instruction.h
index c17188ce90c7d0..ccbcae6cec7440 100644
--- a/llvm/include/llvm/SandboxIR/Instruction.h
+++ b/llvm/include/llvm/SandboxIR/Instruction.h
@@ -18,6 +18,9 @@
namespace llvm::sandboxir {
+// Forward declaration for MSVC.
+class IntrinsicInst;
+
/// A sandboxir::User with operands, opcode and linked with previous/next
/// instructions in an instruction list.
class Instruction : public User {
@@ -1422,13 +1425,13 @@ class CallBase : public SingleLLVMInstructionImpl<llvm::CallBase> {
bool isInlineAsm() const { return cast<llvm::CallBase>(Val)->isInlineAsm(); }
};
-class CallInst final : public CallBase {
+class CallInst : public CallBase {
/// Use Context::createCallInst(). Don't call the
/// constructor directly.
CallInst(llvm::Instruction *I, Context &Ctx)
: CallBase(ClassID::Call, Opcode::Call, I, Ctx) {}
- friend class Context; // For accessing the constructor in
- // create*()
+ friend class Context; // For accessing the constructor in create*()
+ friend class IntrinsicInst; // For constructor
public:
static CallInst *create(FunctionType *FTy, Value *Func,
diff --git a/llvm/include/llvm/SandboxIR/IntrinsicInst.h b/llvm/include/llvm/SandboxIR/IntrinsicInst.h
new file mode 100644
index 00000000000000..33d3746f15119e
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/IntrinsicInst.h
@@ -0,0 +1,44 @@
+//===- IntrinsicInst.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SANDBOXIR_INTRINSICINST_H
+#define LLVM_SANDBOXIR_INTRINSICINST_H
+
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/SandboxIR/Instruction.h"
+
+namespace llvm::sandboxir {
+
+class IntrinsicInst : public CallInst {
+ IntrinsicInst(llvm::IntrinsicInst *I, Context &Ctx) : CallInst(I, Ctx) {}
+
+public:
+ Intrinsic::ID getIntrinsicID() const {
+ return cast<llvm::IntrinsicInst>(Val)->getIntrinsicID();
+ }
+ bool isAssociative() const {
+ return cast<llvm::IntrinsicInst>(Val)->isAssociative();
+ }
+ bool isCommutative() const {
+ return cast<llvm::IntrinsicInst>(Val)->isCommutative();
+ }
+ bool isAssumeLikeIntrinsic() const {
+ return cast<llvm::IntrinsicInst>(Val)->isAssumeLikeIntrinsic();
+ }
+ static bool mayLowerToFunctionCall(Intrinsic::ID IID) {
+ return llvm::IntrinsicInst::mayLowerToFunctionCall(IID);
+ }
+ static bool classof(const Value *V) {
+ auto *LLVMV = V->Val;
+ return isa<llvm::IntrinsicInst>(LLVMV);
+ }
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_SANDBOXIR_INTRINSICINST_H
diff --git a/llvm/include/llvm/SandboxIR/Value.h b/llvm/include/llvm/SandboxIR/Value.h
index b28f0e664f80be..3509f2a8d83650 100644
--- a/llvm/include/llvm/SandboxIR/Value.h
+++ b/llvm/include/llvm/SandboxIR/Value.h
@@ -27,6 +27,7 @@ class GlobalObject;
class Module;
class UnaryInstruction;
class CmpInst;
+class IntrinsicInst;
/// Iterator for the `Use` edges of a Value's users.
/// \Returns a `Use` when dereferenced.
@@ -156,6 +157,7 @@ class Value {
friend class ConstantExpr; // For `Val`.
friend class Utils; // For `Val`.
friend class Module; // For `Val`.
+ friend class IntrinsicInst; // For `Val`.
// Region needs to manipulate metadata in the underlying LLVM Value, we don't
// expose metadata in sandboxir.
friend class Region;
diff --git a/llvm/unittests/SandboxIR/CMakeLists.txt b/llvm/unittests/SandboxIR/CMakeLists.txt
index 622496ada567fc..1e83bda7a1f6d1 100644
--- a/llvm/unittests/SandboxIR/CMakeLists.txt
+++ b/llvm/unittests/SandboxIR/CMakeLists.txt
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_unittest(SandboxIRTests
+ IntrinsicInstTest.cpp
PassTest.cpp
RegionTest.cpp
SandboxIRTest.cpp
diff --git a/llvm/unittests/SandboxIR/IntrinsicInstTest.cpp b/llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
new file mode 100644
index 00000000000000..2272cfc1146169
--- /dev/null
+++ b/llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
@@ -0,0 +1,88 @@
+//===- IntrinsicInstTest.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/SandboxIR/IntrinsicInst.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Value.h"
+#include "llvm/SandboxIR/Context.h"
+#include "llvm/SandboxIR/Function.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+struct IntrinsicInstTest : public testing::Test {
+ LLVMContext C;
+ std::unique_ptr<Module> M;
+
+ void parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ M = parseAssemblyString(IR, Err, C);
+ if (!M)
+ Err.print("SandboxIRTest", errs());
+ }
+ BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
+ for (BasicBlock &BB : F)
+ if (BB.getName() == Name)
+ return &BB;
+ llvm_unreachable("Expected to find basic block!");
+ }
+};
+
+TEST_F(IntrinsicInstTest, Basic) {
+ parseIR(C, R"IR(
+declare void @llvm.sideeffect()
+declare void @llvm.assume(i1)
+declare i8 @llvm.uadd.sat.i8(i8, i8)
+declare i8 @llvm.smax.i8(i8, i8)
+
+define void @foo(i8 %v1, i1 %cond) {
+ call void @llvm.sideeffect()
+ call void @llvm.assume(i1 %cond)
+ call i8 @llvm.uadd.sat.i8(i8 %v1, i8 %v1)
+ call i8 @llvm.smax.i8(i8 %v1, i8 %v1)
+ ret void
+}
+)IR");
+
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ auto *LLVMBB = &*LLVMF->begin();
+ auto LLVMIt = LLVMBB->begin();
+
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto ItE = BB->getTerminator()->getIterator();
+ for (; It != ItE; ++It, ++LLVMIt) {
+ auto *I = &*It;
+ auto *LLVMI = &*LLVMIt;
+ // Check classof().
+ EXPECT_TRUE(isa<sandboxir::IntrinsicInst>(I));
+ // Check getIntrinsicID().
+ EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->getIntrinsicID(),
+ cast<llvm::IntrinsicInst>(LLVMI)->getIntrinsicID());
+ // Check isAssociative().
+ EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isAssociative(),
+ cast<llvm::IntrinsicInst>(LLVMI)->isAssociative());
+ // Check isCommutative().
+ EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isCommutative(),
+ cast<llvm::IntrinsicInst>(LLVMI)->isCommutative());
+ // Check isAssumeLikeIntrinsic().
+ EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isAssumeLikeIntrinsic(),
+ cast<llvm::IntrinsicInst>(LLVMI)->isAssumeLikeIntrinsic());
+ // Check mayLowerToFunctionCall().
+ auto ID = cast<sandboxir::IntrinsicInst>(I)->getIntrinsicID();
+ EXPECT_EQ(sandboxir::IntrinsicInst::mayLowerToFunctionCall(ID),
+ llvm::IntrinsicInst::mayLowerToFunctionCall(ID));
+ }
+}
More information about the llvm-commits
mailing list