#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "source/latest_version_opencl_std_header.h"
#include "source/util/string_utils.h"
#include "test/test_fixture.h"
#include "test/unit_spirv.h"
namespace spvtools {
namespace {
using spvtest::Concatenate;
using spvtest::MakeInstruction;
using utils::MakeVector;
using spvtest::TextToBinaryTest;
using testing::Eq;
struct InstructionCase {
uint32_t opcode;
std::string name;
std::string operands;
std::vector<uint32_t> expected_operands;
};
using ExtInstOpenCLStdRoundTripTest =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<InstructionCase>>;
TEST_P(ExtInstOpenCLStdRoundTripTest, ParameterizedExtInst) {
const std::string input =
"%1 = OpExtInstImport \"OpenCL.std\"\n"
"%3 = OpExtInst %2 %1 " +
GetParam().name + " " + GetParam().operands + "\n";
EXPECT_THAT(CompiledInstructions(input),
Eq(Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1},
MakeVector("OpenCL.std")),
MakeInstruction(spv::Op::OpExtInst,
{2, 3, 1, GetParam().opcode},
GetParam().expected_operands)})))
<< input;
EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input;
}
#define CASE1(Enum, Name) \
{ \
uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4", { 4 } \
}
#define CASE2(Enum, Name) \
{ \
uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5", { 4, 5 } \
}
#define CASE3(Enum, Name) \
{ \
uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6", { 4, 5, 6 } \
}
#define CASE4(Enum, Name) \
{ \
uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6 %7", { \
4, 5, 6, 7 \
} \
}
#define CASE2Lit(Enum, Name, LiteralNumber) \
{ \
uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 " #LiteralNumber, { \
4, 5, LiteralNumber \
} \
}
#define CASE3Round(Enum, Name, Mode) \
{ \
uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6 " #Mode, { \
4, 5, 6, uint32_t(spv::FPRoundingMode::Mode) \
} \
}
INSTANTIATE_TEST_SUITE_P(
OpenCLMath, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE1(Acos, acos), CASE1(Acosh, acosh),
CASE1(Acospi, acospi),
CASE1(Asin, asin),
CASE1(Asinh, asinh),
CASE1(Asinh, asinh),
CASE1(Asinpi, asinpi),
CASE1(Atan, atan),
CASE2(Atan2, atan2),
CASE1(Atanh, atanh),
CASE1(Atanpi, atanpi),
CASE2(Atan2pi, atan2pi),
CASE1(Cbrt, cbrt),
CASE1(Ceil, ceil),
CASE1(Ceil, ceil),
CASE2(Copysign, copysign),
CASE1(Cos, cos),
CASE1(Cosh, cosh),
CASE1(Cospi, cospi),
CASE1(Erfc, erfc),
CASE1(Erf, erf),
CASE1(Exp, exp),
CASE1(Exp2, exp2),
CASE1(Exp10, exp10),
CASE1(Expm1, expm1),
CASE1(Fabs, fabs),
CASE2(Fdim, fdim),
CASE1(Floor, floor),
CASE3(Fma, fma),
CASE2(Fmax, fmax),
CASE2(Fmin, fmin),
CASE2(Fmod, fmod),
CASE2(Fract, fract),
CASE2(Frexp, frexp),
CASE2(Hypot, hypot),
CASE1(Ilogb, ilogb),
CASE2(Ldexp, ldexp),
CASE1(Lgamma, lgamma),
CASE2(Lgamma_r, lgamma_r),
CASE1(Log, log),
CASE1(Log2, log2),
CASE1(Log10, log10),
CASE1(Log1p, log1p),
CASE3(Mad, mad),
CASE2(Maxmag, maxmag),
CASE2(Minmag, minmag),
CASE2(Modf, modf),
CASE1(Nan, nan),
CASE2(Nextafter, nextafter),
CASE2(Pow, pow),
CASE2(Pown, pown),
CASE2(Powr, powr),
CASE2(Remainder, remainder),
CASE3(Remquo, remquo),
CASE1(Rint, rint),
CASE2(Rootn, rootn),
CASE1(Round, round),
CASE1(Rsqrt, rsqrt),
CASE1(Sin, sin),
CASE2(Sincos, sincos),
CASE1(Sinh, sinh),
CASE1(Sinpi, sinpi),
CASE1(Sqrt, sqrt),
CASE1(Tan, tan),
CASE1(Tanh, tanh),
CASE1(Tanpi, tanpi),
CASE1(Tgamma, tgamma),
CASE1(Trunc, trunc),
CASE1(Half_cos, half_cos),
CASE2(Half_divide, half_divide),
CASE1(Half_exp, half_exp),
CASE1(Half_exp2, half_exp2),
CASE1(Half_exp10, half_exp10),
CASE1(Half_log, half_log),
CASE1(Half_log2, half_log2),
CASE1(Half_log10, half_log10),
CASE2(Half_powr, half_powr),
CASE1(Half_recip, half_recip),
CASE1(Half_rsqrt, half_rsqrt),
CASE1(Half_sin, half_sin),
CASE1(Half_sqrt, half_sqrt),
CASE1(Half_tan, half_tan),
CASE1(Native_cos, native_cos),
CASE2(Native_divide, native_divide),
CASE1(Native_exp, native_exp),
CASE1(Native_exp2, native_exp2),
CASE1(Native_exp10, native_exp10),
CASE1(Native_log, native_log),
CASE1(Native_log10, native_log10),
CASE2(Native_powr, native_powr),
CASE1(Native_recip, native_recip),
CASE1(Native_rsqrt, native_rsqrt),
CASE1(Native_sin, native_sin),
CASE1(Native_sqrt, native_sqrt),
CASE1(Native_tan, native_tan), })));
INSTANTIATE_TEST_SUITE_P(
OpenCLInteger, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE1(SAbs, s_abs), CASE2(SAbs_diff, s_abs_diff),
CASE2(SAdd_sat, s_add_sat),
CASE2(UAdd_sat, u_add_sat),
CASE2(SHadd, s_hadd),
CASE2(UHadd, u_hadd),
CASE2(SRhadd, s_rhadd),
CASE2(SRhadd, s_rhadd),
CASE3(SClamp, s_clamp),
CASE3(UClamp, u_clamp),
CASE1(Clz, clz),
CASE1(Ctz, ctz),
CASE3(SMad_hi, s_mad_hi),
CASE3(UMad_sat, u_mad_sat),
CASE3(SMad_sat, s_mad_sat),
CASE2(SMax, s_max),
CASE2(UMax, u_max),
CASE2(SMin, s_min),
CASE2(UMin, u_min),
CASE2(SMul_hi, s_mul_hi),
CASE2(Rotate, rotate),
CASE2(SSub_sat, s_sub_sat),
CASE2(USub_sat, u_sub_sat),
CASE2(U_Upsample, u_upsample),
CASE2(S_Upsample, s_upsample),
CASE1(Popcount, popcount),
CASE3(SMad24, s_mad24),
CASE3(UMad24, u_mad24),
CASE2(SMul24, s_mul24),
CASE2(UMul24, u_mul24), CASE1(UAbs, u_abs), CASE2(UAbs_diff, u_abs_diff),
CASE2(UMul_hi, u_mul_hi),
CASE3(UMad_hi, u_mad_hi), })));
INSTANTIATE_TEST_SUITE_P(
OpenCLCommon, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE3(FClamp, fclamp), CASE1(Degrees, degrees),
CASE2(FMax_common, fmax_common),
CASE2(FMin_common, fmin_common),
CASE3(Mix, mix),
CASE1(Radians, radians),
CASE2(Step, step),
CASE3(Smoothstep, smoothstep),
CASE1(Sign, sign), })));
INSTANTIATE_TEST_SUITE_P(
OpenCLGeometric, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE2(Cross, cross), CASE2(Distance, distance),
CASE1(Length, length),
CASE1(Normalize, normalize),
CASE2(Fast_distance, fast_distance),
CASE1(Fast_length, fast_length),
CASE1(Fast_normalize, fast_normalize), })));
INSTANTIATE_TEST_SUITE_P(
OpenCLRelational, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE3(Bitselect, bitselect), CASE3(Select, select), })));
INSTANTIATE_TEST_SUITE_P(
OpenCLVectorLoadStore, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE2Lit(Vloadn, vloadn, 2),
CASE2Lit(Vloadn, vloadn, 3),
CASE2Lit(Vloadn, vloadn, 4),
CASE2Lit(Vloadn, vloadn, 8),
CASE2Lit(Vloadn, vloadn, 16),
CASE3(Vstoren, vstoren),
CASE2(Vload_half, vload_half),
CASE2Lit(Vload_halfn, vload_halfn, 2),
CASE2Lit(Vload_halfn, vload_halfn, 3),
CASE2Lit(Vload_halfn, vload_halfn, 4),
CASE2Lit(Vload_halfn, vload_halfn, 8),
CASE2Lit(Vload_halfn, vload_halfn, 16),
CASE3(Vstore_half, vstore_half),
CASE3Round(Vstore_half_r, vstore_half_r, RTE),
CASE3Round(Vstore_half_r, vstore_half_r, RTZ),
CASE3Round(Vstore_half_r, vstore_half_r, RTP),
CASE3Round(Vstore_half_r, vstore_half_r, RTN),
CASE3(Vstore_halfn, vstore_halfn),
CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTE),
CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTZ),
CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTP),
CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTN),
CASE2Lit(Vloada_halfn, vloada_halfn, 2),
CASE2Lit(Vloada_halfn, vloada_halfn, 3),
CASE2Lit(Vloada_halfn, vloada_halfn, 4),
CASE2Lit(Vloada_halfn, vloada_halfn, 8),
CASE2Lit(Vloada_halfn, vloada_halfn, 16),
CASE3(Vstorea_halfn, vstorea_halfn),
CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTE),
CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTZ),
CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTP),
CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTN),
})));
INSTANTIATE_TEST_SUITE_P(
OpenCLMiscellaneousVector, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE2(Shuffle, shuffle),
CASE3(Shuffle2, shuffle2),
})));
#define PREFIX uint32_t(OpenCLLIB::Entrypoints::Printf), "printf"
INSTANTIATE_TEST_SUITE_P(
OpenCLMiscPrintf, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
{PREFIX, "%4", {4}},
{PREFIX, "%4 %5", {4, 5}},
{PREFIX, "%4 %5 %6", {4, 5, 6}},
{PREFIX, "%4 %5 %6 %7", {4, 5, 6, 7}},
{PREFIX, "%4 %5 %6 %7 %8", {4, 5, 6, 7, 8}},
{PREFIX, "%4 %5 %6 %7 %8 %9", {4, 5, 6, 7, 8, 9}},
{PREFIX, "%4 %5 %6 %7 %8 %9 %10", {4, 5, 6, 7, 8, 9, 10}},
{PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11", {4, 5, 6, 7, 8, 9, 10, 11}},
{PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11 %12",
{4, 5, 6, 7, 8, 9, 10, 11, 12}},
{PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11 %12 %13",
{4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
{PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14",
{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}},
})));
#undef PREFIX
INSTANTIATE_TEST_SUITE_P(
OpenCLMiscPrefetch, ExtInstOpenCLStdRoundTripTest,
::testing::ValuesIn(std::vector<InstructionCase>({
CASE2(Prefetch, prefetch),
})));
#undef CASE1
#undef CASE2
#undef CASE3
#undef CASE4
#undef CASE2Lit
#undef CASE3Round
} }