Setup dependent external sources
[platform/upstream/VK-GL-CTS.git] / external / spirv-tools / src / test / ext_inst.opencl_test.cpp
1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "unit_spirv.h"
16
17 #include <gmock/gmock.h>
18 #include "test_fixture.h"
19 #include "spirv/1.0/OpenCL.std.h"
20
21 namespace {
22
23 using spvtest::Concatenate;
24 using spvtest::MakeInstruction;
25 using spvtest::MakeVector;
26 using spvtest::TextToBinaryTest;
27 using testing::Eq;
28
29 struct InstructionCase {
30   uint32_t opcode;
31   std::string name;
32   std::string operands;
33   std::vector<uint32_t> expected_operands;
34 };
35
36 using ExtInstOpenCLStdRoundTripTest =
37     spvtest::TextToBinaryTestBase<::testing::TestWithParam<InstructionCase>>;
38
39 TEST_P(ExtInstOpenCLStdRoundTripTest, ParameterizedExtInst) {
40   // This example should not validate.
41   const std::string input =
42       "%1 = OpExtInstImport \"OpenCL.std\"\n"
43       "%3 = OpExtInst %2 %1 " +
44       GetParam().name + " " + GetParam().operands + "\n";
45   // First make sure it assembles correctly.
46   EXPECT_THAT(
47       CompiledInstructions(input),
48       Eq(Concatenate(
49           {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("OpenCL.std")),
50            MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode},
51                            GetParam().expected_operands)})))
52       << input;
53   // Now check the round trip through the disassembler.
54   EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input;
55 }
56
57 #define CASE1(Enum, Name)                                      \
58   {                                                            \
59     uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4", { 4 } \
60   }
61 #define CASE2(Enum, Name)                                            \
62   {                                                                  \
63     uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5", { 4, 5 } \
64   }
65 #define CASE3(Enum, Name)                                                  \
66   {                                                                        \
67     uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6", { 4, 5, 6 } \
68   }
69 #define CASE4(Enum, Name)                                           \
70   {                                                                 \
71     uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6 %7", { \
72       4, 5, 6, 7                                                    \
73     }                                                               \
74   }
75 #define CASE2Lit(Enum, Name, LiteralNumber)                                   \
76   {                                                                           \
77     uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 " #LiteralNumber, { \
78       4, 5, LiteralNumber                                                     \
79     }                                                                         \
80   }
81 #define CASE3Round(Enum, Name, Mode)                                    \
82   {                                                                     \
83     uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6 " #Mode, { \
84       4, 5, 6, uint32_t(SpvFPRoundingMode##Mode)                        \
85     }                                                                   \
86   }
87
88 // clang-format off
89 // OpenCL.std: 2.1 Math extended instructions
90 INSTANTIATE_TEST_CASE_P(
91     OpenCLMath, ExtInstOpenCLStdRoundTripTest,
92     ::testing::ValuesIn(std::vector<InstructionCase>({
93         // We are only testing the correctness of encoding and decoding here.
94         // Semantic correctness should be the responsibility of validator.
95         CASE1(Acos, acos), // enum value 0
96         CASE1(Acosh, acosh),
97         CASE1(Acospi, acospi),
98         CASE1(Asin, asin),
99         CASE1(Asinh, asinh),
100         CASE1(Asinh, asinh),
101         CASE1(Asinpi, asinpi),
102         CASE1(Atan, atan),
103         CASE2(Atan2, atan2),
104         CASE1(Atanh, atanh),
105         CASE1(Atanpi, atanpi),
106         CASE2(Atan2pi, atan2pi),
107         CASE1(Cbrt, cbrt),
108         CASE1(Ceil, ceil),
109         CASE1(Ceil, ceil),
110         CASE2(Copysign, copysign),
111         CASE1(Cos, cos),
112         CASE1(Cosh, cosh),
113         CASE1(Cospi, cospi),
114         CASE1(Erfc, erfc),
115         CASE1(Erf, erf),
116         CASE1(Exp, exp),
117         CASE1(Exp2, exp2),
118         CASE1(Exp10, exp10),
119         CASE1(Expm1, expm1),
120         CASE1(Fabs, fabs),
121         CASE2(Fdim, fdim),
122         CASE1(Floor, floor),
123         CASE3(Fma, fma),
124         CASE2(Fmax, fmax),
125         CASE2(Fmin, fmin),
126         CASE2(Fmod, fmod),
127         CASE2(Fract, fract),
128         CASE2(Frexp, frexp),
129         CASE2(Hypot, hypot),
130         CASE1(Ilogb, ilogb),
131         CASE2(Ldexp, ldexp),
132         CASE1(Lgamma, lgamma),
133         CASE2(Lgamma_r, lgamma_r),
134         CASE1(Log, log),
135         CASE1(Log2, log2),
136         CASE1(Log10, log10),
137         CASE1(Log1p, log1p),
138         CASE3(Mad, mad),
139         CASE2(Maxmag, maxmag),
140         CASE2(Minmag, minmag),
141         CASE2(Modf, modf),
142         CASE1(Nan, nan),
143         CASE2(Nextafter, nextafter),
144         CASE2(Pow, pow),
145         CASE2(Pown, pown),
146         CASE2(Powr, powr),
147         CASE2(Remainder, remainder),
148         CASE3(Remquo, remquo),
149         CASE1(Rint, rint),
150         CASE2(Rootn, rootn),
151         CASE1(Round, round),
152         CASE1(Rsqrt, rsqrt),
153         CASE1(Sin, sin),
154         CASE2(Sincos, sincos),
155         CASE1(Sinh, sinh),
156         CASE1(Sinpi, sinpi),
157         CASE1(Sqrt, sqrt),
158         CASE1(Tan, tan),
159         CASE1(Tanh, tanh),
160         CASE1(Tanpi, tanpi),
161         CASE1(Tgamma, tgamma),
162         CASE1(Trunc, trunc),
163         CASE1(Half_cos, half_cos),
164         CASE2(Half_divide, half_divide),
165         CASE1(Half_exp, half_exp),
166         CASE1(Half_exp2, half_exp2),
167         CASE1(Half_exp10, half_exp10),
168         CASE1(Half_log, half_log),
169         CASE1(Half_log2, half_log2),
170         CASE1(Half_log10, half_log10),
171         CASE2(Half_powr, half_powr),
172         CASE1(Half_recip, half_recip),
173         CASE1(Half_rsqrt, half_rsqrt),
174         CASE1(Half_sin, half_sin),
175         CASE1(Half_sqrt, half_sqrt),
176         CASE1(Half_tan, half_tan),
177         CASE1(Native_cos, native_cos),
178         CASE2(Native_divide, native_divide),
179         CASE1(Native_exp, native_exp),
180         CASE1(Native_exp2, native_exp2),
181         CASE1(Native_exp10, native_exp10),
182         CASE1(Native_log, native_log),
183         CASE1(Native_log10, native_log10),
184         CASE2(Native_powr, native_powr),
185         CASE1(Native_recip, native_recip),
186         CASE1(Native_rsqrt, native_rsqrt),
187         CASE1(Native_sin, native_sin),
188         CASE1(Native_sqrt, native_sqrt),
189         CASE1(Native_tan, native_tan), // enum value 94
190     })),);
191
192 // OpenCL.std: 2.1 Integer instructions
193 INSTANTIATE_TEST_CASE_P(
194     OpenCLInteger, ExtInstOpenCLStdRoundTripTest,
195     ::testing::ValuesIn(std::vector<InstructionCase>({
196         CASE1(SAbs, s_abs), // enum value 141
197         CASE2(SAbs_diff, s_abs_diff),
198         CASE2(SAdd_sat, s_add_sat),
199         CASE2(UAdd_sat, u_add_sat),
200         CASE2(SHadd, s_hadd),
201         CASE2(UHadd, u_hadd),
202         CASE2(SRhadd, s_rhadd),
203         CASE2(SRhadd, s_rhadd),
204         CASE3(SClamp, s_clamp),
205         CASE3(UClamp, u_clamp),
206         CASE1(Clz, clz),
207         CASE1(Ctz, ctz),
208         CASE3(SMad_hi, s_mad_hi),
209         CASE3(UMad_sat, u_mad_sat),
210         CASE3(SMad_sat, s_mad_sat),
211         CASE2(SMax, s_max),
212         CASE2(UMax, u_max),
213         CASE2(SMin, s_min),
214         CASE2(UMin, u_min),
215         CASE2(SMul_hi, s_mul_hi),
216         CASE2(Rotate, rotate),
217         CASE2(SSub_sat, s_sub_sat),
218         CASE2(USub_sat, u_sub_sat),
219         CASE2(U_Upsample, u_upsample),
220         CASE2(S_Upsample, s_upsample),
221         CASE1(Popcount, popcount),
222         CASE3(SMad24, s_mad24),
223         CASE3(UMad24, u_mad24),
224         CASE2(SMul24, s_mul24),
225         CASE2(UMul24, u_mul24), // enum value 170
226         CASE1(UAbs, u_abs), // enum value 201
227         CASE2(UAbs_diff, u_abs_diff),
228         CASE2(UMul_hi, u_mul_hi),
229         CASE3(UMad_hi, u_mad_hi), // enum value 204
230     })),);
231
232 // OpenCL.std: 2.3 Common instrucitons
233 INSTANTIATE_TEST_CASE_P(
234     OpenCLCommon, ExtInstOpenCLStdRoundTripTest,
235     ::testing::ValuesIn(std::vector<InstructionCase>({
236         CASE3(FClamp, fclamp), // enum value 95
237         CASE1(Degrees, degrees),
238         CASE2(FMax_common, fmax_common),
239         CASE2(FMin_common, fmin_common),
240         CASE3(Mix, mix),
241         CASE1(Radians, radians),
242         CASE2(Step, step),
243         CASE3(Smoothstep, smoothstep),
244         CASE1(Sign, sign), // enum value 103
245     })),);
246
247 // OpenCL.std: 2.4 Geometric instructions
248 INSTANTIATE_TEST_CASE_P(
249     OpenCLGeometric, ExtInstOpenCLStdRoundTripTest,
250     ::testing::ValuesIn(std::vector<InstructionCase>({
251         CASE2(Cross, cross), // enum value 104
252         CASE2(Distance, distance),
253         CASE1(Length, length),
254         CASE1(Normalize, normalize),
255         CASE2(Fast_distance, fast_distance),
256         CASE1(Fast_length, fast_length),
257         CASE1(Fast_normalize, fast_normalize), // enum value 110
258     })),);
259
260 // OpenCL.std: 2.5 Relational instructions
261 INSTANTIATE_TEST_CASE_P(
262     OpenCLRelational, ExtInstOpenCLStdRoundTripTest,
263     ::testing::ValuesIn(std::vector<InstructionCase>({
264         CASE3(Bitselect, bitselect), // enum value 186
265         CASE3(Select, select), // enum value 187
266     })),);
267
268 // OpenCL.std: 2.6 Vector data load and store instructions
269 INSTANTIATE_TEST_CASE_P(
270     OpenCLVectorLoadStore, ExtInstOpenCLStdRoundTripTest,
271     ::testing::ValuesIn(std::vector<InstructionCase>({
272         // The last argument to Vloadn must be one of 2, 3, 4, 8, 16.
273         CASE2Lit(Vloadn, vloadn, 2),
274         CASE2Lit(Vloadn, vloadn, 3),
275         CASE2Lit(Vloadn, vloadn, 4),
276         CASE2Lit(Vloadn, vloadn, 8),
277         CASE2Lit(Vloadn, vloadn, 16),
278         CASE3(Vstoren, vstoren),
279         CASE2(Vload_half, vload_half),
280         CASE2Lit(Vload_halfn, vload_halfn, 2),
281         CASE2Lit(Vload_halfn, vload_halfn, 3),
282         CASE2Lit(Vload_halfn, vload_halfn, 4),
283         CASE2Lit(Vload_halfn, vload_halfn, 8),
284         CASE2Lit(Vload_halfn, vload_halfn, 16),
285         CASE3(Vstore_half, vstore_half),
286         // Try all the rounding modes.
287         CASE3Round(Vstore_half_r, vstore_half_r, RTE),
288         CASE3Round(Vstore_half_r, vstore_half_r, RTZ),
289         CASE3Round(Vstore_half_r, vstore_half_r, RTP),
290         CASE3Round(Vstore_half_r, vstore_half_r, RTN),
291         CASE3(Vstore_halfn, vstore_halfn),
292         CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTE),
293         CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTZ),
294         CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTP),
295         CASE3Round(Vstore_halfn_r, vstore_halfn_r, RTN),
296         CASE2Lit(Vloada_halfn, vloada_halfn, 2),
297         CASE2Lit(Vloada_halfn, vloada_halfn, 3),
298         CASE2Lit(Vloada_halfn, vloada_halfn, 4),
299         CASE2Lit(Vloada_halfn, vloada_halfn, 8),
300         CASE2Lit(Vloada_halfn, vloada_halfn, 16),
301         CASE3(Vstorea_halfn, vstorea_halfn),
302         CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTE),
303         CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTZ),
304         CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTP),
305         CASE3Round(Vstorea_halfn_r, vstorea_halfn_r, RTN),
306     })),);
307
308 // OpenCL.std: 2.7 Miscellaneous vector instructions
309 INSTANTIATE_TEST_CASE_P(
310     OpenCLMiscellaneousVector, ExtInstOpenCLStdRoundTripTest,
311     ::testing::ValuesIn(std::vector<InstructionCase>({
312         CASE2(Shuffle, shuffle),
313         CASE3(Shuffle2, shuffle2),
314     })),);
315
316 // OpenCL.std: 2.8 Miscellaneous instructions
317
318 #define PREFIX uint32_t(OpenCLLIB::Entrypoints::Printf), "printf"
319 INSTANTIATE_TEST_CASE_P(
320     OpenCLMiscPrintf, ExtInstOpenCLStdRoundTripTest,
321     ::testing::ValuesIn(std::vector<InstructionCase>({
322       // Printf is interesting because it takes a variable number of arguments.
323       // Start with zero optional arguments.
324       {PREFIX, "%4", {4}},
325       {PREFIX, "%4 %5", {4, 5}},
326       {PREFIX, "%4 %5 %6", {4, 5, 6}},
327       {PREFIX, "%4 %5 %6 %7", {4, 5, 6, 7}},
328       {PREFIX, "%4 %5 %6 %7 %8", {4, 5, 6, 7, 8}},
329       {PREFIX, "%4 %5 %6 %7 %8 %9", {4, 5, 6, 7, 8, 9}},
330       {PREFIX, "%4 %5 %6 %7 %8 %9 %10", {4, 5, 6, 7, 8, 9, 10}},
331       {PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11", {4, 5, 6, 7, 8, 9, 10, 11}},
332       {PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11 %12",
333         {4, 5, 6, 7, 8, 9, 10, 11, 12}},
334       {PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11 %12 %13",
335         {4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
336       {PREFIX, "%4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14",
337         {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}},
338     })),);
339 #undef PREFIX
340
341 INSTANTIATE_TEST_CASE_P(
342     OpenCLMiscPrefetch, ExtInstOpenCLStdRoundTripTest,
343     ::testing::ValuesIn(std::vector<InstructionCase>({
344         CASE2(Prefetch, prefetch),
345     })),);
346
347 // OpenCL.std: 2.9.1 Image encoding
348 // No new instructions defined in this section.
349
350 // OpenCL.std: 2.9.2 Sampler encoding
351 // No new instructions defined in this section.
352
353 // OpenCL.std: 2.9.3 Image read
354 // No new instructions defined in this section.
355 // Use core instruction OpImageSampleExplicitLod instead.
356
357 // OpenCL.std: 2.9.4 Image write
358 // No new instructions defined in this section.
359
360 // clang-format on
361
362 #undef CASE1
363 #undef CASE2
364 #undef CASE3
365 #undef CASE4
366 #undef CASE2Lit
367 #undef CASE3Round
368
369 }  // anonymous namespace