Skip to content

Commit 43d51d6

Browse files
authored
[SandboxIR] Implement IntrinsicInst (llvm#110900)
This patch implements sandboxir::IntrinsicInst mirroring llvm::IntrinsicInst.
1 parent 81fcdc6 commit 43d51d6

File tree

5 files changed

+141
-3
lines changed

5 files changed

+141
-3
lines changed

llvm/include/llvm/SandboxIR/Instruction.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
namespace llvm::sandboxir {
2020

21+
// Forward declaration for MSVC.
22+
class IntrinsicInst;
23+
2124
/// A sandboxir::User with operands, opcode and linked with previous/next
2225
/// instructions in an instruction list.
2326
class Instruction : public User {
@@ -1422,13 +1425,13 @@ class CallBase : public SingleLLVMInstructionImpl<llvm::CallBase> {
14221425
bool isInlineAsm() const { return cast<llvm::CallBase>(Val)->isInlineAsm(); }
14231426
};
14241427

1425-
class CallInst final : public CallBase {
1428+
class CallInst : public CallBase {
14261429
/// Use Context::createCallInst(). Don't call the
14271430
/// constructor directly.
14281431
CallInst(llvm::Instruction *I, Context &Ctx)
14291432
: CallBase(ClassID::Call, Opcode::Call, I, Ctx) {}
1430-
friend class Context; // For accessing the constructor in
1431-
// create*()
1433+
friend class Context; // For accessing the constructor in create*()
1434+
friend class IntrinsicInst; // For constructor
14321435

14331436
public:
14341437
static CallInst *create(FunctionType *FTy, Value *Func,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===- IntrinsicInst.h ------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_SANDBOXIR_INTRINSICINST_H
10+
#define LLVM_SANDBOXIR_INTRINSICINST_H
11+
12+
#include "llvm/IR/IntrinsicInst.h"
13+
#include "llvm/SandboxIR/Instruction.h"
14+
15+
namespace llvm::sandboxir {
16+
17+
class IntrinsicInst : public CallInst {
18+
IntrinsicInst(llvm::IntrinsicInst *I, Context &Ctx) : CallInst(I, Ctx) {}
19+
20+
public:
21+
Intrinsic::ID getIntrinsicID() const {
22+
return cast<llvm::IntrinsicInst>(Val)->getIntrinsicID();
23+
}
24+
bool isAssociative() const {
25+
return cast<llvm::IntrinsicInst>(Val)->isAssociative();
26+
}
27+
bool isCommutative() const {
28+
return cast<llvm::IntrinsicInst>(Val)->isCommutative();
29+
}
30+
bool isAssumeLikeIntrinsic() const {
31+
return cast<llvm::IntrinsicInst>(Val)->isAssumeLikeIntrinsic();
32+
}
33+
static bool mayLowerToFunctionCall(Intrinsic::ID IID) {
34+
return llvm::IntrinsicInst::mayLowerToFunctionCall(IID);
35+
}
36+
static bool classof(const Value *V) {
37+
auto *LLVMV = V->Val;
38+
return isa<llvm::IntrinsicInst>(LLVMV);
39+
}
40+
};
41+
42+
} // namespace llvm::sandboxir
43+
44+
#endif // LLVM_SANDBOXIR_INTRINSICINST_H

llvm/include/llvm/SandboxIR/Value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class GlobalObject;
2727
class Module;
2828
class UnaryInstruction;
2929
class CmpInst;
30+
class IntrinsicInst;
3031

3132
/// Iterator for the `Use` edges of a Value's users.
3233
/// \Returns a `Use` when dereferenced.
@@ -156,6 +157,7 @@ class Value {
156157
friend class ConstantExpr; // For `Val`.
157158
friend class Utils; // For `Val`.
158159
friend class Module; // For `Val`.
160+
friend class IntrinsicInst; // For `Val`.
159161
// Region needs to manipulate metadata in the underlying LLVM Value, we don't
160162
// expose metadata in sandboxir.
161163
friend class Region;

llvm/unittests/SandboxIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
66
)
77

88
add_llvm_unittest(SandboxIRTests
9+
IntrinsicInstTest.cpp
910
PassTest.cpp
1011
RegionTest.cpp
1112
SandboxIRTest.cpp
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//===- IntrinsicInstTest.cpp ----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/SandboxIR/IntrinsicInst.h"
10+
#include "llvm/AsmParser/Parser.h"
11+
#include "llvm/IR/BasicBlock.h"
12+
#include "llvm/IR/Function.h"
13+
#include "llvm/IR/Instruction.h"
14+
#include "llvm/IR/IntrinsicInst.h"
15+
#include "llvm/IR/Value.h"
16+
#include "llvm/SandboxIR/Context.h"
17+
#include "llvm/SandboxIR/Function.h"
18+
#include "llvm/Support/SourceMgr.h"
19+
#include "gtest/gtest.h"
20+
21+
using namespace llvm;
22+
23+
struct IntrinsicInstTest : public testing::Test {
24+
LLVMContext C;
25+
std::unique_ptr<Module> M;
26+
27+
void parseIR(LLVMContext &C, const char *IR) {
28+
SMDiagnostic Err;
29+
M = parseAssemblyString(IR, Err, C);
30+
if (!M)
31+
Err.print("SandboxIRTest", errs());
32+
}
33+
BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
34+
for (BasicBlock &BB : F)
35+
if (BB.getName() == Name)
36+
return &BB;
37+
llvm_unreachable("Expected to find basic block!");
38+
}
39+
};
40+
41+
TEST_F(IntrinsicInstTest, Basic) {
42+
parseIR(C, R"IR(
43+
declare void @llvm.sideeffect()
44+
declare void @llvm.assume(i1)
45+
declare i8 @llvm.uadd.sat.i8(i8, i8)
46+
declare i8 @llvm.smax.i8(i8, i8)
47+
48+
define void @foo(i8 %v1, i1 %cond) {
49+
call void @llvm.sideeffect()
50+
call void @llvm.assume(i1 %cond)
51+
call i8 @llvm.uadd.sat.i8(i8 %v1, i8 %v1)
52+
call i8 @llvm.smax.i8(i8 %v1, i8 %v1)
53+
ret void
54+
}
55+
)IR");
56+
57+
llvm::Function *LLVMF = &*M->getFunction("foo");
58+
auto *LLVMBB = &*LLVMF->begin();
59+
auto LLVMIt = LLVMBB->begin();
60+
61+
sandboxir::Context Ctx(C);
62+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
63+
auto *BB = &*F->begin();
64+
auto It = BB->begin();
65+
auto ItE = BB->getTerminator()->getIterator();
66+
for (; It != ItE; ++It, ++LLVMIt) {
67+
auto *I = &*It;
68+
auto *LLVMI = &*LLVMIt;
69+
// Check classof().
70+
EXPECT_TRUE(isa<sandboxir::IntrinsicInst>(I));
71+
// Check getIntrinsicID().
72+
EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->getIntrinsicID(),
73+
cast<llvm::IntrinsicInst>(LLVMI)->getIntrinsicID());
74+
// Check isAssociative().
75+
EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isAssociative(),
76+
cast<llvm::IntrinsicInst>(LLVMI)->isAssociative());
77+
// Check isCommutative().
78+
EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isCommutative(),
79+
cast<llvm::IntrinsicInst>(LLVMI)->isCommutative());
80+
// Check isAssumeLikeIntrinsic().
81+
EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isAssumeLikeIntrinsic(),
82+
cast<llvm::IntrinsicInst>(LLVMI)->isAssumeLikeIntrinsic());
83+
// Check mayLowerToFunctionCall().
84+
auto ID = cast<sandboxir::IntrinsicInst>(I)->getIntrinsicID();
85+
EXPECT_EQ(sandboxir::IntrinsicInst::mayLowerToFunctionCall(ID),
86+
llvm::IntrinsicInst::mayLowerToFunctionCall(ID));
87+
}
88+
}

0 commit comments

Comments
 (0)