1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00
llvm-mirror/unittests/Analysis/VectorFunctionABITest.cpp
Francesco Petrogalli bb6e7b26a0 [SVFS] Vector Function ABI demangling.
This patch implements the demangling functionality as described in the
Vector Function ABI. This patch will be used to implement the
SearchVectorFunctionSystem (SVFS) as described in the RFC:

http://lists.llvm.org/pipermail/llvm-dev/2019-June/133484.html

A fuzzer is added to test the demangling utility.

Patch by Sumedh Arani <sumedh.arani@arm.com>

Differential revision: https://reviews.llvm.org/D66024

llvm-svn: 372343
2019-09-19 17:47:32 +00:00

440 lines
17 KiB
C++

//===------- VectorFunctionABITest.cpp - VFABI Unittests ---------===//
//
// 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/Analysis/VectorUtils.h"
#include "gtest/gtest.h"
using namespace llvm;
// This test makes sure that the getFromVFABI method succeeds only on
// valid values of the string.
TEST(VectorFunctionABITests, OnlyValidNames) {
// Incomplete string.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("").hasValue());
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGV").hasValue());
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVn").hasValue());
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN").hasValue());
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2").hasValue());
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v").hasValue());
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_").hasValue());
// Missing parameters.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2_foo").hasValue());
// Missing _ZGV prefix.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZVnN2v_foo").hasValue());
// Missing <isa>.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVN2v_foo").hasValue());
// Missing <mask>.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVn2v_foo").hasValue());
// Missing <vlen>.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnNv_foo").hasValue());
// Missing <scalarname>.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_").hasValue());
// Missing _ separator.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2vfoo").hasValue());
// Missing <vectorname>.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_foo()").hasValue());
// Unterminated name.
EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_foo(bar").hasValue());
}
TEST(VectorFunctionABITests, ParamListParsing) {
// Testing "vl16Ls32R3l"
const auto OptVFS = VFABI::tryDemangleForVFABI("_ZGVnN2vl16Ls32R3l_foo");
EXPECT_TRUE(OptVFS.hasValue());
const VFInfo VFS = OptVFS.getValue();
EXPECT_EQ(VFS.Shape.Parameters.size(), (unsigned)5);
EXPECT_EQ(VFS.Shape.Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
EXPECT_EQ(VFS.Shape.Parameters[1],
VFParameter({1, VFParamKind::OMP_Linear, 16}));
EXPECT_EQ(VFS.Shape.Parameters[2],
VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
EXPECT_EQ(VFS.Shape.Parameters[3],
VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
EXPECT_EQ(VFS.Shape.Parameters[4],
VFParameter({4, VFParamKind::OMP_Linear, 1}));
}
TEST(VectorFunctionABITests, ScalarNameAndVectorName) {
// Parse Scalar Name
const auto A = VFABI::tryDemangleForVFABI("_ZGVnM2v_sin");
const auto B = VFABI::tryDemangleForVFABI("_ZGVnM2v_sin(UserFunc)");
const auto C = VFABI::tryDemangleForVFABI("_ZGVnM2v___sin_sin_sin");
EXPECT_TRUE(A.hasValue());
EXPECT_TRUE(B.hasValue());
EXPECT_TRUE(C.hasValue());
EXPECT_EQ(A.getValue().ScalarName, "sin");
EXPECT_EQ(B.getValue().ScalarName, "sin");
EXPECT_EQ(C.getValue().ScalarName, "__sin_sin_sin");
EXPECT_EQ(A.getValue().VectorName, "_ZGVnM2v_sin");
EXPECT_EQ(B.getValue().VectorName, "UserFunc");
EXPECT_EQ(C.getValue().VectorName, "_ZGVnM2v___sin_sin_sin");
}
namespace {
// Test fixture needed that holds the veariables needed by the parser.
class VFABIParserTest : public ::testing::Test {
private:
// Parser output.
VFInfo Info;
// Reset the parser output references.
void reset() { Info = VFInfo(); }
protected:
// Referencies to the parser output field.
unsigned &VF = Info.Shape.VF;
VFISAKind &ISA = Info.Shape.ISA;
SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
StringRef &ScalarName = Info.ScalarName;
StringRef &VectorName = Info.VectorName;
bool &IsScalable = Info.Shape.IsScalable;
// Invoke the parser.
bool invokeParser(const StringRef MangledName) {
reset();
const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName);
if (OptInfo.hasValue()) {
Info = OptInfo.getValue();
return true;
}
return false;
}
// Checks that 1. the last Parameter in the Shape is of type
// VFParamKind::GlobalPredicate and 2. it is the only one of such
// type.
bool IsMasked() const {
const auto NGlobalPreds =
std::count_if(Info.Shape.Parameters.begin(),
Info.Shape.Parameters.end(), [](const VFParameter PK) {
return PK.ParamKind == VFParamKind::GlobalPredicate;
});
return NGlobalPreds == 1 && Info.Shape.Parameters.back().ParamKind ==
VFParamKind::GlobalPredicate;
}
};
} // unnamed namespace
TEST_F(VFABIParserTest, Parse) {
EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_FALSE(IsMasked());
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
EXPECT_FALSE(IsScalable);
EXPECT_EQ(Parameters.size(), (unsigned)9);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearPos, 2}));
EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 27}));
EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}));
EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}));
EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_Linear, 1}));
EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearVal, 10}));
EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, 100}));
EXPECT_EQ(Parameters[8], VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
EXPECT_EQ(ScalarName, "sin");
EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin");
}
TEST_F(VFABIParserTest, ParseVectorName) {
EXPECT_TRUE(invokeParser("_ZGVnN2v_sin(my_v_sin)"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_FALSE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
EXPECT_EQ(Parameters.size(), (unsigned)1);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
EXPECT_EQ(ScalarName, "sin");
EXPECT_EQ(VectorName, "my_v_sin");
}
TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_FALSE(IsMasked());
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
EXPECT_FALSE(IsScalable);
EXPECT_EQ(Parameters.size(), (unsigned)4);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, -1}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, -10}));
EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearUVal, -100}));
EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, -1000}));
EXPECT_EQ(ScalarName, "sin");
EXPECT_EQ(VectorName, "_ZGVnN2ln1Ln10Un100Rn1000_sin");
}
TEST_F(VFABIParserTest, ParseScalableSVE) {
EXPECT_TRUE(invokeParser("_ZGVsMxv_sin"));
EXPECT_EQ(VF, (unsigned)0);
EXPECT_TRUE(IsMasked());
EXPECT_TRUE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::SVE);
EXPECT_EQ(ScalarName, "sin");
EXPECT_EQ(VectorName, "_ZGVsMxv_sin");
}
TEST_F(VFABIParserTest, ParseFixedWidthSVE) {
EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::SVE);
EXPECT_EQ(ScalarName, "sin");
EXPECT_EQ(VectorName, "_ZGVsM2v_sin");
}
TEST_F(VFABIParserTest, NotAVectorFunctionABIName) {
// Vector names should start with `_ZGV`.
EXPECT_FALSE(invokeParser("ZGVnN2v_sin"));
}
TEST_F(VFABIParserTest, LinearWithRuntimeStep) {
EXPECT_FALSE(invokeParser("_ZGVnN2ls_sin"))
<< "A number should be present after \"ls\".";
EXPECT_TRUE(invokeParser("_ZGVnN2ls2_sin"));
EXPECT_FALSE(invokeParser("_ZGVnN2Rs_sin"))
<< "A number should be present after \"Rs\".";
EXPECT_TRUE(invokeParser("_ZGVnN2Rs4_sin"));
EXPECT_FALSE(invokeParser("_ZGVnN2Ls_sin"))
<< "A number should be present after \"Ls\".";
EXPECT_TRUE(invokeParser("_ZGVnN2Ls6_sin"));
EXPECT_FALSE(invokeParser("_ZGVnN2Us_sin"))
<< "A number should be present after \"Us\".";
EXPECT_TRUE(invokeParser("_ZGVnN2Us8_sin"));
}
TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin"));
EXPECT_EQ(Parameters.size(), (unsigned)8);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearRef, 1}));
EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUVal, 1}));
EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, -1}));
EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_LinearVal, -1}));
EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearRef, -1}));
EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, -1}));
}
TEST_F(VFABIParserTest, ISA) {
EXPECT_TRUE(invokeParser("_ZGVqN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::Unknown);
EXPECT_TRUE(invokeParser("_ZGVnN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
EXPECT_TRUE(invokeParser("_ZGVsN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::SVE);
EXPECT_TRUE(invokeParser("_ZGVbN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::SSE);
EXPECT_TRUE(invokeParser("_ZGVcN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::AVX);
EXPECT_TRUE(invokeParser("_ZGVdN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::AVX2);
EXPECT_TRUE(invokeParser("_ZGVeN2v_sin"));
EXPECT_EQ(ISA, VFISAKind::AVX512);
}
TEST_F(VFABIParserTest, InvalidMask) {
EXPECT_FALSE(invokeParser("_ZGVsK2v_sin"));
}
TEST_F(VFABIParserTest, InvalidParameter) {
EXPECT_FALSE(invokeParser("_ZGVsM2vX_sin"));
}
TEST_F(VFABIParserTest, Align) {
EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin"));
EXPECT_EQ(Parameters.size(), (unsigned)1);
EXPECT_EQ(Parameters[0].Alignment, Align(2));
// Missing alignement value.
EXPECT_FALSE(invokeParser("_ZGVsM2l2a_sin"));
// Invalid alignment token "x".
EXPECT_FALSE(invokeParser("_ZGVsM2l2ax_sin"));
// Alignment MUST be associated to a paramater.
EXPECT_FALSE(invokeParser("_ZGVsM2a2_sin"));
// Alignment must be a power of 2.
EXPECT_FALSE(invokeParser("_ZGVsN2l2a0_sin"));
EXPECT_TRUE(invokeParser("_ZGVsN2l2a1_sin"));
EXPECT_FALSE(invokeParser("_ZGVsN2l2a3_sin"));
EXPECT_FALSE(invokeParser("_ZGVsN2l2a6_sin"));
}
TEST_F(VFABIParserTest, ParseUniform) {
EXPECT_TRUE(invokeParser("_ZGVnN2u0_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_FALSE(IsMasked());
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
EXPECT_FALSE(IsScalable);
EXPECT_EQ(Parameters.size(), (unsigned)1);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0}));
EXPECT_EQ(ScalarName, "sin");
EXPECT_EQ(VectorName, "_ZGVnN2u0_sin");
EXPECT_FALSE(invokeParser("_ZGVnN2u_sin"));
EXPECT_FALSE(invokeParser("_ZGVnN2ul_sin"));
}
TEST_F(VFABIParserTest, ISAIndependentMangling) {
// This test makes sure that the mangling of the parameters in
// independent on the <isa> token.
const SmallVector<VFParameter, 8> ExpectedParams = {
VFParameter({0, VFParamKind::Vector, 0}),
VFParameter({1, VFParamKind::OMP_LinearPos, 2}),
VFParameter({2, VFParamKind::OMP_LinearValPos, 27}),
VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}),
VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}),
VFParameter({5, VFParamKind::OMP_Linear, 1}),
VFParameter({6, VFParamKind::OMP_LinearVal, 10}),
VFParameter({7, VFParamKind::OMP_LinearUVal, 100}),
VFParameter({8, VFParamKind::OMP_LinearRef, 1000}),
VFParameter({9, VFParamKind::OMP_Uniform, 2}),
};
#define __COMMON_CHECKS \
do { \
EXPECT_EQ(VF, (unsigned)2); \
EXPECT_FALSE(IsMasked()); \
EXPECT_FALSE(IsScalable); \
EXPECT_EQ(Parameters.size(), (unsigned)10); \
EXPECT_EQ(Parameters, ExpectedParams); \
EXPECT_EQ(ScalarName, "sin"); \
} while (0)
// Advanced SIMD: <isa> = "n"
EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
// SVE: <isa> = "s"
EXPECT_TRUE(invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::SVE);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
// SSE: <isa> = "b"
EXPECT_TRUE(invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::SSE);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
// AVX: <isa> = "c"
EXPECT_TRUE(invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::AVX);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
// AVX2: <isa> = "d"
EXPECT_TRUE(invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::AVX2);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
// AVX512: <isa> = "e"
EXPECT_TRUE(invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::AVX512);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
// Unknown ISA (randomly using "q"). This test will need update if
// some targets decide to use "q" as their ISA token.
EXPECT_TRUE(invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
EXPECT_EQ(ISA, VFISAKind::Unknown);
__COMMON_CHECKS;
EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
#undef __COMMON_CHECKS
}
TEST_F(VFABIParserTest, MissingScalarName) {
EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
}
TEST_F(VFABIParserTest, MissingVectorName) {
EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()"));
}
TEST_F(VFABIParserTest, MissingVectorNameTermination) {
EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar"));
}
TEST_F(VFABIParserTest, ParseMaskingNEON) {
EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
EXPECT_EQ(Parameters.size(), (unsigned)2);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
EXPECT_EQ(ScalarName, "sin");
}
TEST_F(VFABIParserTest, ParseMaskingSVE) {
EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::SVE);
EXPECT_EQ(Parameters.size(), (unsigned)2);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
EXPECT_EQ(ScalarName, "sin");
}
TEST_F(VFABIParserTest, ParseMaskingSSE) {
EXPECT_TRUE(invokeParser("_ZGVbM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::SSE);
EXPECT_EQ(Parameters.size(), (unsigned)2);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
EXPECT_EQ(ScalarName, "sin");
}
TEST_F(VFABIParserTest, ParseMaskingAVX) {
EXPECT_TRUE(invokeParser("_ZGVcM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::AVX);
EXPECT_EQ(Parameters.size(), (unsigned)2);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
EXPECT_EQ(ScalarName, "sin");
}
TEST_F(VFABIParserTest, ParseMaskingAVX2) {
EXPECT_TRUE(invokeParser("_ZGVdM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::AVX2);
EXPECT_EQ(Parameters.size(), (unsigned)2);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
EXPECT_EQ(ScalarName, "sin");
}
TEST_F(VFABIParserTest, ParseMaskingAVX512) {
EXPECT_TRUE(invokeParser("_ZGVeM2v_sin"));
EXPECT_EQ(VF, (unsigned)2);
EXPECT_TRUE(IsMasked());
EXPECT_FALSE(IsScalable);
EXPECT_EQ(ISA, VFISAKind::AVX512);
EXPECT_EQ(Parameters.size(), (unsigned)2);
EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
EXPECT_EQ(ScalarName, "sin");
}