[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