123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- // Copyright (c) 2015-2016 The Khronos Group Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include <string>
- #include <vector>
- #include "gmock/gmock.h"
- #include "source/latest_version_opencl_std_header.h"
- #include "test/test_fixture.h"
- #include "test/unit_spirv.h"
- namespace spvtools {
- namespace {
- using spvtest::Concatenate;
- using spvtest::MakeInstruction;
- using spvtest::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) {
- // This example should not validate.
- const std::string input =
- "%1 = OpExtInstImport \"OpenCL.std\"\n"
- "%3 = OpExtInst %2 %1 " +
- GetParam().name + " " + GetParam().operands + "\n";
- // First make sure it assembles correctly.
- EXPECT_THAT(
- CompiledInstructions(input),
- Eq(Concatenate(
- {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("OpenCL.std")),
- MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode},
- GetParam().expected_operands)})))
- << input;
- // Now check the round trip through the disassembler.
- 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(SpvFPRoundingMode##Mode) \
- } \
- }
- // clang-format off
- // OpenCL.std: 2.1 Math extended instructions
- INSTANTIATE_TEST_SUITE_P(
- OpenCLMath, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- // We are only testing the correctness of encoding and decoding here.
- // Semantic correctness should be the responsibility of validator.
- CASE1(Acos, acos), // enum value 0
- 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), // enum value 94
- })));
- // OpenCL.std: 2.1 Integer instructions
- INSTANTIATE_TEST_SUITE_P(
- OpenCLInteger, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- CASE1(SAbs, s_abs), // enum value 141
- 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), // enum value 170
- CASE1(UAbs, u_abs), // enum value 201
- CASE2(UAbs_diff, u_abs_diff),
- CASE2(UMul_hi, u_mul_hi),
- CASE3(UMad_hi, u_mad_hi), // enum value 204
- })));
- // OpenCL.std: 2.3 Common instrucitons
- INSTANTIATE_TEST_SUITE_P(
- OpenCLCommon, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- CASE3(FClamp, fclamp), // enum value 95
- 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), // enum value 103
- })));
- // OpenCL.std: 2.4 Geometric instructions
- INSTANTIATE_TEST_SUITE_P(
- OpenCLGeometric, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- CASE2(Cross, cross), // enum value 104
- CASE2(Distance, distance),
- CASE1(Length, length),
- CASE1(Normalize, normalize),
- CASE2(Fast_distance, fast_distance),
- CASE1(Fast_length, fast_length),
- CASE1(Fast_normalize, fast_normalize), // enum value 110
- })));
- // OpenCL.std: 2.5 Relational instructions
- INSTANTIATE_TEST_SUITE_P(
- OpenCLRelational, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- CASE3(Bitselect, bitselect), // enum value 186
- CASE3(Select, select), // enum value 187
- })));
- // OpenCL.std: 2.6 Vector data load and store instructions
- INSTANTIATE_TEST_SUITE_P(
- OpenCLVectorLoadStore, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- // The last argument to Vloadn must be one of 2, 3, 4, 8, 16.
- 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),
- // Try all the rounding modes.
- 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),
- })));
- // OpenCL.std: 2.7 Miscellaneous vector instructions
- INSTANTIATE_TEST_SUITE_P(
- OpenCLMiscellaneousVector, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- CASE2(Shuffle, shuffle),
- CASE3(Shuffle2, shuffle2),
- })));
- // OpenCL.std: 2.8 Miscellaneous instructions
- #define PREFIX uint32_t(OpenCLLIB::Entrypoints::Printf), "printf"
- INSTANTIATE_TEST_SUITE_P(
- OpenCLMiscPrintf, ExtInstOpenCLStdRoundTripTest,
- ::testing::ValuesIn(std::vector<InstructionCase>({
- // Printf is interesting because it takes a variable number of arguments.
- // Start with zero optional arguments.
- {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),
- })));
- // OpenCL.std: 2.9.1 Image encoding
- // No new instructions defined in this section.
- // OpenCL.std: 2.9.2 Sampler encoding
- // No new instructions defined in this section.
- // OpenCL.std: 2.9.3 Image read
- // No new instructions defined in this section.
- // Use core instruction OpImageSampleExplicitLod instead.
- // OpenCL.std: 2.9.4 Image write
- // No new instructions defined in this section.
- // clang-format on
- #undef CASE1
- #undef CASE2
- #undef CASE3
- #undef CASE4
- #undef CASE2Lit
- #undef CASE3Round
- } // namespace
- } // namespace spvtools
|