Skip to content

Commit b159987

Browse files
author
Simon Moll
committed
[VP] Improve the VP intrinsic unittests
Test that all VP intrinsics are tested. Test intrinsic id -> opcode -> intrinsic id round tripping. Test property scopes in the include/llvm/IR/VPIntrinsics.def file. Reviewed By: frasercrmck Differential Revision: https://reviews.llvm.org/D93534
1 parent d7086af commit b159987

File tree

1 file changed

+81
-15
lines changed

1 file changed

+81
-15
lines changed

llvm/unittests/IR/VPIntrinsicTest.cpp

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "llvm/ADT/SmallVector.h"
1010
#include "llvm/AsmParser/Parser.h"
11+
#include "llvm/CodeGen/ISDOpcodes.h"
1112
#include "llvm/IR/Constants.h"
1213
#include "llvm/IR/IRBuilder.h"
1314
#include "llvm/IR/IntrinsicInst.h"
@@ -16,6 +17,7 @@
1617
#include "llvm/IR/Verifier.h"
1718
#include "llvm/Support/SourceMgr.h"
1819
#include "gtest/gtest.h"
20+
#include <sstream>
1921

2022
using namespace llvm;
2123

@@ -31,24 +33,65 @@ class VPIntrinsicTest : public testing::Test {
3133
SMDiagnostic Err;
3234

3335
std::unique_ptr<Module> CreateVPDeclarationModule() {
34-
return parseAssemblyString(
35-
" declare <8 x i32> @llvm.vp.add.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
36-
" declare <8 x i32> @llvm.vp.sub.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
37-
" declare <8 x i32> @llvm.vp.mul.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
38-
" declare <8 x i32> @llvm.vp.sdiv.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
39-
" declare <8 x i32> @llvm.vp.srem.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
40-
" declare <8 x i32> @llvm.vp.udiv.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
41-
" declare <8 x i32> @llvm.vp.urem.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
42-
" declare <8 x i32> @llvm.vp.and.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
43-
" declare <8 x i32> @llvm.vp.xor.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
44-
" declare <8 x i32> @llvm.vp.or.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
45-
" declare <8 x i32> @llvm.vp.ashr.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
46-
" declare <8 x i32> @llvm.vp.lshr.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) "
47-
" declare <8 x i32> @llvm.vp.shl.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) ",
48-
Err, C);
36+
const char *BinaryIntOpcodes[] = {"add", "sub", "mul", "sdiv", "srem",
37+
"udiv", "urem", "and", "xor", "or",
38+
"ashr", "lshr", "shl"};
39+
std::stringstream Str;
40+
for (const char *BinaryIntOpcode : BinaryIntOpcodes)
41+
Str << " declare <8 x i32> @llvm.vp." << BinaryIntOpcode
42+
<< ".v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) ";
43+
44+
return parseAssemblyString(Str.str(), Err, C);
4945
}
5046
};
5147

48+
/// Check that the property scopes include/llvm/IR/VPIntrinsics.def are closed.
49+
TEST_F(VPIntrinsicTest, VPIntrinsicsDefScopes) {
50+
Optional<Intrinsic::ID> ScopeVPID;
51+
#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) \
52+
ASSERT_FALSE(ScopeVPID.hasValue()); \
53+
ScopeVPID = Intrinsic::VPID;
54+
#define END_REGISTER_VP_INTRINSIC(VPID) \
55+
ASSERT_TRUE(ScopeVPID.hasValue()); \
56+
ASSERT_EQ(ScopeVPID.getValue(), Intrinsic::VPID); \
57+
ScopeVPID = None;
58+
59+
Optional<ISD::NodeType> ScopeOPC;
60+
#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) \
61+
ASSERT_FALSE(ScopeOPC.hasValue()); \
62+
ScopeOPC = ISD::SDOPC;
63+
#define END_REGISTER_VP_SDNODE(SDOPC) \
64+
ASSERT_TRUE(ScopeOPC.hasValue()); \
65+
ASSERT_EQ(ScopeOPC.getValue(), ISD::SDOPC); \
66+
ScopeOPC = None;
67+
#include "llvm/IR/VPIntrinsics.def"
68+
69+
ASSERT_FALSE(ScopeVPID.hasValue());
70+
ASSERT_FALSE(ScopeOPC.hasValue());
71+
}
72+
73+
/// Check that every VP intrinsic in the test module is recognized as a VP
74+
/// intrinsic.
75+
TEST_F(VPIntrinsicTest, VPModuleComplete) {
76+
std::unique_ptr<Module> M = CreateVPDeclarationModule();
77+
assert(M);
78+
79+
// Check that all @llvm.vp.* functions in the module are recognized vp
80+
// intrinsics.
81+
std::set<Intrinsic::ID> SeenIDs;
82+
for (const auto &VPDecl : *M) {
83+
ASSERT_TRUE(VPDecl.isIntrinsic());
84+
ASSERT_TRUE(VPIntrinsic::IsVPIntrinsic(VPDecl.getIntrinsicID()));
85+
SeenIDs.insert(VPDecl.getIntrinsicID());
86+
}
87+
88+
// Check that every registered VP intrinsic has an instance in the test
89+
// module.
90+
#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) \
91+
ASSERT_TRUE(SeenIDs.count(Intrinsic::VPID));
92+
#include "llvm/IR/VPIntrinsics.def"
93+
}
94+
5295
/// Check that VPIntrinsic:canIgnoreVectorLengthParam() returns true
5396
/// if the vector length parameter does not mask off any lanes.
5497
TEST_F(VPIntrinsicTest, CanIgnoreVectorLength) {
@@ -155,4 +198,27 @@ TEST_F(VPIntrinsicTest, OpcodeRoundTrip) {
155198
ASSERT_NE(FullTripCounts, 0u);
156199
}
157200

201+
/// Check that going from VP intrinsic to Opcode and back results in the same
202+
/// intrinsic id.
203+
TEST_F(VPIntrinsicTest, IntrinsicIDRoundTrip) {
204+
std::unique_ptr<Module> M = CreateVPDeclarationModule();
205+
assert(M);
206+
207+
unsigned FullTripCounts = 0;
208+
for (const auto &VPDecl : *M) {
209+
auto VPID = VPDecl.getIntrinsicID();
210+
unsigned OC = VPIntrinsic::GetFunctionalOpcodeForVP(VPID);
211+
212+
// no equivalent Opcode available
213+
if (OC == Instruction::Call)
214+
continue;
215+
216+
Intrinsic::ID RoundTripVPID = VPIntrinsic::GetForOpcode(OC);
217+
218+
ASSERT_EQ(RoundTripVPID, VPID);
219+
++FullTripCounts;
220+
}
221+
ASSERT_NE(FullTripCounts, 0u);
222+
}
223+
158224
} // end anonymous namespace

0 commit comments

Comments
 (0)