Skip to content

[SandboxIR] Implement IntrinsicInst #110900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions llvm/include/llvm/SandboxIR/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
44 changes: 44 additions & 0 deletions llvm/include/llvm/SandboxIR/IntrinsicInst.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions llvm/include/llvm/SandboxIR/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/SandboxIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
)

add_llvm_unittest(SandboxIRTests
IntrinsicInstTest.cpp
PassTest.cpp
RegionTest.cpp
SandboxIRTest.cpp
Expand Down
88 changes: 88 additions & 0 deletions llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
Original file line number Diff line number Diff line change
@@ -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));
}
}
Loading