• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 Google 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 // Tests for unique type declaration rules validator.
16 
17 #include <functional>
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 #include "gmock/gmock.h"
23 #include "source/comp/markv.h"
24 #include "test/test_fixture.h"
25 #include "test/unit_spirv.h"
26 #include "tools/comp/markv_model_factory.h"
27 
28 namespace spvtools {
29 namespace comp {
30 namespace {
31 
32 using spvtest::ScopedContext;
33 using MarkvTest = ::testing::TestWithParam<MarkvModelType>;
34 
DiagnosticsMessageHandler(spv_message_level_t level,const char *,const spv_position_t & position,const char * message)35 void DiagnosticsMessageHandler(spv_message_level_t level, const char*,
36                                const spv_position_t& position,
37                                const char* message) {
38   switch (level) {
39     case SPV_MSG_FATAL:
40     case SPV_MSG_INTERNAL_ERROR:
41     case SPV_MSG_ERROR:
42       std::cerr << "error: " << position.index << ": " << message << std::endl;
43       break;
44     case SPV_MSG_WARNING:
45       std::cout << "warning: " << position.index << ": " << message
46                 << std::endl;
47       break;
48     case SPV_MSG_INFO:
49       std::cout << "info: " << position.index << ": " << message << std::endl;
50       break;
51     default:
52       break;
53   }
54 }
55 
56 // Compiles |code| to SPIR-V |words|.
Compile(const std::string & code,std::vector<uint32_t> * words,uint32_t options=SPV_TEXT_TO_BINARY_OPTION_NONE,spv_target_env env=SPV_ENV_UNIVERSAL_1_2)57 void Compile(const std::string& code, std::vector<uint32_t>* words,
58              uint32_t options = SPV_TEXT_TO_BINARY_OPTION_NONE,
59              spv_target_env env = SPV_ENV_UNIVERSAL_1_2) {
60   spvtools::Context ctx(env);
61   ctx.SetMessageConsumer(DiagnosticsMessageHandler);
62 
63   spv_binary spirv_binary;
64   ASSERT_EQ(SPV_SUCCESS, spvTextToBinaryWithOptions(
65                              ctx.CContext(), code.c_str(), code.size(), options,
66                              &spirv_binary, nullptr));
67 
68   *words = std::vector<uint32_t>(spirv_binary->code,
69                                  spirv_binary->code + spirv_binary->wordCount);
70 
71   spvBinaryDestroy(spirv_binary);
72 }
73 
74 // Disassembles SPIR-V |words| to |out_text|.
Disassemble(const std::vector<uint32_t> & words,std::string * out_text,spv_target_env env=SPV_ENV_UNIVERSAL_1_2)75 void Disassemble(const std::vector<uint32_t>& words, std::string* out_text,
76                  spv_target_env env = SPV_ENV_UNIVERSAL_1_2) {
77   spvtools::Context ctx(env);
78   ctx.SetMessageConsumer(DiagnosticsMessageHandler);
79 
80   spv_text text = nullptr;
81   ASSERT_EQ(SPV_SUCCESS, spvBinaryToText(ctx.CContext(), words.data(),
82                                          words.size(), 0, &text, nullptr));
83   assert(text);
84 
85   *out_text = std::string(text->str, text->length);
86   spvTextDestroy(text);
87 }
88 
89 // Encodes/decodes |original|, assembles/dissasembles |original|, then compares
90 // the results of the two operations.
TestEncodeDecode(MarkvModelType model_type,const std::string & original_text)91 void TestEncodeDecode(MarkvModelType model_type,
92                       const std::string& original_text) {
93   spvtools::Context ctx(SPV_ENV_UNIVERSAL_1_2);
94   std::unique_ptr<MarkvModel> model = CreateMarkvModel(model_type);
95   MarkvCodecOptions options;
96 
97   std::vector<uint32_t> expected_binary;
98   Compile(original_text, &expected_binary);
99   ASSERT_FALSE(expected_binary.empty());
100 
101   std::string expected_text;
102   Disassemble(expected_binary, &expected_text);
103   ASSERT_FALSE(expected_text.empty());
104 
105   std::vector<uint32_t> binary_to_encode;
106   Compile(original_text, &binary_to_encode,
107           SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
108   ASSERT_FALSE(binary_to_encode.empty());
109 
110   std::stringstream encoder_comments;
111   const auto output_to_string_stream =
112       [&encoder_comments](const std::string& str) { encoder_comments << str; };
113 
114   std::vector<uint8_t> markv;
115   ASSERT_EQ(SPV_SUCCESS,
116             SpirvToMarkv(ctx.CContext(), binary_to_encode, options, *model,
117                          DiagnosticsMessageHandler, output_to_string_stream,
118                          MarkvDebugConsumer(), &markv));
119   ASSERT_FALSE(markv.empty());
120 
121   std::vector<uint32_t> decoded_binary;
122   ASSERT_EQ(SPV_SUCCESS,
123             MarkvToSpirv(ctx.CContext(), markv, options, *model,
124                          DiagnosticsMessageHandler, MarkvLogConsumer(),
125                          MarkvDebugConsumer(), &decoded_binary));
126   ASSERT_FALSE(decoded_binary.empty());
127 
128   EXPECT_EQ(expected_binary, decoded_binary) << encoder_comments.str();
129 
130   std::string decoded_text;
131   Disassemble(decoded_binary, &decoded_text);
132   ASSERT_FALSE(decoded_text.empty());
133 
134   EXPECT_EQ(expected_text, decoded_text) << encoder_comments.str();
135 }
136 
TestEncodeDecodeShaderMainBody(MarkvModelType model_type,const std::string & body)137 void TestEncodeDecodeShaderMainBody(MarkvModelType model_type,
138                                     const std::string& body) {
139   const std::string prefix =
140       R"(
141 OpCapability Shader
142 OpCapability Int64
143 OpCapability Float64
144 %ext_inst = OpExtInstImport "GLSL.std.450"
145 OpMemoryModel Logical GLSL450
146 OpEntryPoint Fragment %main "main"
147 %void = OpTypeVoid
148 %func = OpTypeFunction %void
149 %bool = OpTypeBool
150 %f32 = OpTypeFloat 32
151 %u32 = OpTypeInt 32 0
152 %s32 = OpTypeInt 32 1
153 %f64 = OpTypeFloat 64
154 %u64 = OpTypeInt 64 0
155 %s64 = OpTypeInt 64 1
156 %boolvec2 = OpTypeVector %bool 2
157 %s32vec2 = OpTypeVector %s32 2
158 %u32vec2 = OpTypeVector %u32 2
159 %f32vec2 = OpTypeVector %f32 2
160 %f64vec2 = OpTypeVector %f64 2
161 %boolvec3 = OpTypeVector %bool 3
162 %u32vec3 = OpTypeVector %u32 3
163 %s32vec3 = OpTypeVector %s32 3
164 %f32vec3 = OpTypeVector %f32 3
165 %f64vec3 = OpTypeVector %f64 3
166 %boolvec4 = OpTypeVector %bool 4
167 %u32vec4 = OpTypeVector %u32 4
168 %s32vec4 = OpTypeVector %s32 4
169 %f32vec4 = OpTypeVector %f32 4
170 %f64vec4 = OpTypeVector %f64 4
171 
172 %f32_0 = OpConstant %f32 0
173 %f32_1 = OpConstant %f32 1
174 %f32_2 = OpConstant %f32 2
175 %f32_3 = OpConstant %f32 3
176 %f32_4 = OpConstant %f32 4
177 %f32_pi = OpConstant %f32 3.14159
178 
179 %s32_0 = OpConstant %s32 0
180 %s32_1 = OpConstant %s32 1
181 %s32_2 = OpConstant %s32 2
182 %s32_3 = OpConstant %s32 3
183 %s32_4 = OpConstant %s32 4
184 %s32_m1 = OpConstant %s32 -1
185 
186 %u32_0 = OpConstant %u32 0
187 %u32_1 = OpConstant %u32 1
188 %u32_2 = OpConstant %u32 2
189 %u32_3 = OpConstant %u32 3
190 %u32_4 = OpConstant %u32 4
191 
192 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
193 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
194 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
195 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
196 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
197 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
198 
199 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
200 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
201 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
202 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
203 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
204 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
205 
206 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
207 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
208 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
209 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
210 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
211 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
212 
213 %main = OpFunction %void None %func
214 %main_entry = OpLabel)";
215 
216   const std::string suffix =
217       R"(
218 OpReturn
219 OpFunctionEnd)";
220 
221   TestEncodeDecode(model_type, prefix + body + suffix);
222 }
223 
TEST_P(MarkvTest,U32Literal)224 TEST_P(MarkvTest, U32Literal) {
225   TestEncodeDecode(GetParam(), R"(
226 OpCapability Shader
227 OpCapability Linkage
228 OpMemoryModel Logical GLSL450
229 %u32 = OpTypeInt 32 0
230 %100 = OpConstant %u32 0
231 %200 = OpConstant %u32 1
232 %300 = OpConstant %u32 4294967295
233 )");
234 }
235 
TEST_P(MarkvTest,S32Literal)236 TEST_P(MarkvTest, S32Literal) {
237   TestEncodeDecode(GetParam(), R"(
238 OpCapability Shader
239 OpCapability Linkage
240 OpMemoryModel Logical GLSL450
241 %s32 = OpTypeInt 32 1
242 %100 = OpConstant %s32 0
243 %200 = OpConstant %s32 1
244 %300 = OpConstant %s32 -1
245 %400 = OpConstant %s32 2147483647
246 %500 = OpConstant %s32 -2147483648
247 )");
248 }
249 
TEST_P(MarkvTest,U64Literal)250 TEST_P(MarkvTest, U64Literal) {
251   TestEncodeDecode(GetParam(), R"(
252 OpCapability Shader
253 OpCapability Linkage
254 OpCapability Int64
255 OpMemoryModel Logical GLSL450
256 %u64 = OpTypeInt 64 0
257 %100 = OpConstant %u64 0
258 %200 = OpConstant %u64 1
259 %300 = OpConstant %u64 18446744073709551615
260 )");
261 }
262 
TEST_P(MarkvTest,S64Literal)263 TEST_P(MarkvTest, S64Literal) {
264   TestEncodeDecode(GetParam(), R"(
265 OpCapability Shader
266 OpCapability Linkage
267 OpCapability Int64
268 OpMemoryModel Logical GLSL450
269 %s64 = OpTypeInt 64 1
270 %100 = OpConstant %s64 0
271 %200 = OpConstant %s64 1
272 %300 = OpConstant %s64 -1
273 %400 = OpConstant %s64 9223372036854775807
274 %500 = OpConstant %s64 -9223372036854775808
275 )");
276 }
277 
TEST_P(MarkvTest,U16Literal)278 TEST_P(MarkvTest, U16Literal) {
279   TestEncodeDecode(GetParam(), R"(
280 OpCapability Shader
281 OpCapability Linkage
282 OpCapability Int16
283 OpMemoryModel Logical GLSL450
284 %u16 = OpTypeInt 16 0
285 %100 = OpConstant %u16 0
286 %200 = OpConstant %u16 1
287 %300 = OpConstant %u16 65535
288 )");
289 }
290 
TEST_P(MarkvTest,S16Literal)291 TEST_P(MarkvTest, S16Literal) {
292   TestEncodeDecode(GetParam(), R"(
293 OpCapability Shader
294 OpCapability Linkage
295 OpCapability Int16
296 OpMemoryModel Logical GLSL450
297 %s16 = OpTypeInt 16 1
298 %100 = OpConstant %s16 0
299 %200 = OpConstant %s16 1
300 %300 = OpConstant %s16 -1
301 %400 = OpConstant %s16 32767
302 %500 = OpConstant %s16 -32768
303 )");
304 }
305 
TEST_P(MarkvTest,F32Literal)306 TEST_P(MarkvTest, F32Literal) {
307   TestEncodeDecode(GetParam(), R"(
308 OpCapability Shader
309 OpCapability Linkage
310 OpMemoryModel Logical GLSL450
311 %f32 = OpTypeFloat 32
312 %100 = OpConstant %f32 0
313 %200 = OpConstant %f32 1
314 %300 = OpConstant %f32 0.1
315 %400 = OpConstant %f32 -0.1
316 )");
317 }
318 
TEST_P(MarkvTest,F64Literal)319 TEST_P(MarkvTest, F64Literal) {
320   TestEncodeDecode(GetParam(), R"(
321 OpCapability Shader
322 OpCapability Linkage
323 OpCapability Float64
324 OpMemoryModel Logical GLSL450
325 %f64 = OpTypeFloat 64
326 %100 = OpConstant %f64 0
327 %200 = OpConstant %f64 1
328 %300 = OpConstant %f64 0.1
329 %400 = OpConstant %f64 -0.1
330 )");
331 }
332 
TEST_P(MarkvTest,F16Literal)333 TEST_P(MarkvTest, F16Literal) {
334   TestEncodeDecode(GetParam(), R"(
335 OpCapability Shader
336 OpCapability Linkage
337 OpCapability Float16
338 OpMemoryModel Logical GLSL450
339 %f16 = OpTypeFloat 16
340 %100 = OpConstant %f16 0
341 %200 = OpConstant %f16 1
342 %300 = OpConstant %f16 0.1
343 %400 = OpConstant %f16 -0.1
344 )");
345 }
346 
TEST_P(MarkvTest,StringLiteral)347 TEST_P(MarkvTest, StringLiteral) {
348   TestEncodeDecode(GetParam(), R"(
349 OpCapability Shader
350 OpCapability Linkage
351 OpExtension "SPV_KHR_16bit_storage"
352 OpExtension "xxx"
353 OpExtension "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
354 OpExtension ""
355 OpMemoryModel Logical GLSL450
356 )");
357 }
358 
TEST_P(MarkvTest,WithFunction)359 TEST_P(MarkvTest, WithFunction) {
360   TestEncodeDecode(GetParam(), R"(
361 OpCapability Addresses
362 OpCapability Kernel
363 OpCapability GenericPointer
364 OpCapability Linkage
365 OpExtension "SPV_KHR_16bit_storage"
366 OpMemoryModel Physical32 OpenCL
367 %f32 = OpTypeFloat 32
368 %u32 = OpTypeInt 32 0
369 %void = OpTypeVoid
370 %void_func = OpTypeFunction %void
371 %100 = OpConstant %u32 1
372 %200 = OpConstant %u32 2
373 %main = OpFunction %void None %void_func
374 %entry_main = OpLabel
375 %300 = OpIAdd %u32 %100 %200
376 OpReturn
377 OpFunctionEnd
378 )");
379 }
380 
TEST_P(MarkvTest,WithMultipleFunctions)381 TEST_P(MarkvTest, WithMultipleFunctions) {
382   TestEncodeDecode(GetParam(), R"(
383 OpCapability Addresses
384 OpCapability Kernel
385 OpCapability GenericPointer
386 OpCapability Linkage
387 OpMemoryModel Physical32 OpenCL
388 %f32 = OpTypeFloat 32
389 %one = OpConstant %f32 1
390 %void = OpTypeVoid
391 %void_func = OpTypeFunction %void
392 %f32_func = OpTypeFunction %f32 %f32
393 %sqr_plus_one = OpFunction %f32 None %f32_func
394 %x = OpFunctionParameter %f32
395 %100 = OpLabel
396 %x2 = OpFMul %f32 %x %x
397 %x2p1 = OpFunctionCall %f32 %plus_one %x2
398 OpReturnValue %x2p1
399 OpFunctionEnd
400 %plus_one = OpFunction %f32 None %f32_func
401 %y = OpFunctionParameter %f32
402 %200 = OpLabel
403 %yp1 = OpFAdd %f32 %y %one
404 OpReturnValue %yp1
405 OpFunctionEnd
406 %main = OpFunction %void None %void_func
407 %entry_main = OpLabel
408 %1p1 = OpFunctionCall %f32 %sqr_plus_one %one
409 OpReturn
410 OpFunctionEnd
411 )");
412 }
413 
TEST_P(MarkvTest,ForwardDeclaredId)414 TEST_P(MarkvTest, ForwardDeclaredId) {
415   TestEncodeDecode(GetParam(), R"(
416 OpCapability Addresses
417 OpCapability Kernel
418 OpCapability GenericPointer
419 OpCapability Linkage
420 OpMemoryModel Physical32 OpenCL
421 OpEntryPoint Kernel %1 "simple_kernel"
422 %2 = OpTypeInt 32 0
423 %3 = OpTypeVector %2 2
424 %4 = OpConstant %2 2
425 %5 = OpTypeArray %2 %4
426 %6 = OpTypeVoid
427 %7 = OpTypeFunction %6
428 %1 = OpFunction %6 None %7
429 %8 = OpLabel
430 OpReturn
431 OpFunctionEnd
432 )");
433 }
434 
TEST_P(MarkvTest,WithSwitch)435 TEST_P(MarkvTest, WithSwitch) {
436   TestEncodeDecode(GetParam(), R"(
437 OpCapability Addresses
438 OpCapability Kernel
439 OpCapability GenericPointer
440 OpCapability Linkage
441 OpCapability Int64
442 OpMemoryModel Physical32 OpenCL
443 %u64 = OpTypeInt 64 0
444 %void = OpTypeVoid
445 %void_func = OpTypeFunction %void
446 %val = OpConstant %u64 1
447 %main = OpFunction %void None %void_func
448 %entry_main = OpLabel
449 OpSwitch %val %default 1 %case1 1000000000000 %case2
450 %case1 = OpLabel
451 OpNop
452 OpBranch %after_switch
453 %case2 = OpLabel
454 OpNop
455 OpBranch %after_switch
456 %default = OpLabel
457 OpNop
458 OpBranch %after_switch
459 %after_switch = OpLabel
460 OpReturn
461 OpFunctionEnd
462 )");
463 }
464 
TEST_P(MarkvTest,WithLoop)465 TEST_P(MarkvTest, WithLoop) {
466   TestEncodeDecode(GetParam(), R"(
467 OpCapability Addresses
468 OpCapability Kernel
469 OpCapability GenericPointer
470 OpCapability Linkage
471 OpMemoryModel Physical32 OpenCL
472 %void = OpTypeVoid
473 %void_func = OpTypeFunction %void
474 %main = OpFunction %void None %void_func
475 %entry_main = OpLabel
476 OpLoopMerge %merge %continue DontUnroll|DependencyLength 10
477 OpBranch %begin_loop
478 %begin_loop = OpLabel
479 OpNop
480 OpBranch %continue
481 %continue = OpLabel
482 OpNop
483 OpBranch %begin_loop
484 %merge = OpLabel
485 OpReturn
486 OpFunctionEnd
487 )");
488 }
489 
TEST_P(MarkvTest,WithDecorate)490 TEST_P(MarkvTest, WithDecorate) {
491   TestEncodeDecode(GetParam(), R"(
492 OpCapability Shader
493 OpCapability Linkage
494 OpMemoryModel Logical GLSL450
495 OpDecorate %1 ArrayStride 4
496 OpDecorate %1 Uniform
497 %2 = OpTypeFloat 32
498 %1 = OpTypeRuntimeArray %2
499 )");
500 }
501 
TEST_P(MarkvTest,WithExtInst)502 TEST_P(MarkvTest, WithExtInst) {
503   TestEncodeDecode(GetParam(), R"(
504 OpCapability Addresses
505 OpCapability Kernel
506 OpCapability GenericPointer
507 OpCapability Linkage
508 %opencl = OpExtInstImport "OpenCL.std"
509 OpMemoryModel Physical32 OpenCL
510 %f32 = OpTypeFloat 32
511 %void = OpTypeVoid
512 %void_func = OpTypeFunction %void
513 %100 = OpConstant %f32 1.1
514 %main = OpFunction %void None %void_func
515 %entry_main = OpLabel
516 %200 = OpExtInst %f32 %opencl cos %100
517 OpReturn
518 OpFunctionEnd
519 )");
520 }
521 
TEST_P(MarkvTest,F32Mul)522 TEST_P(MarkvTest, F32Mul) {
523   TestEncodeDecodeShaderMainBody(GetParam(), R"(
524 %val1 = OpFMul %f32 %f32_0 %f32_1
525 %val2 = OpFMul %f32 %f32_2 %f32_0
526 %val3 = OpFMul %f32 %f32_pi %f32_2
527 %val4 = OpFMul %f32 %f32_1 %f32_1
528 )");
529 }
530 
TEST_P(MarkvTest,U32Mul)531 TEST_P(MarkvTest, U32Mul) {
532   TestEncodeDecodeShaderMainBody(GetParam(), R"(
533 %val1 = OpIMul %u32 %u32_0 %u32_1
534 %val2 = OpIMul %u32 %u32_2 %u32_0
535 %val3 = OpIMul %u32 %u32_3 %u32_2
536 %val4 = OpIMul %u32 %u32_1 %u32_1
537 )");
538 }
539 
TEST_P(MarkvTest,S32Mul)540 TEST_P(MarkvTest, S32Mul) {
541   TestEncodeDecodeShaderMainBody(GetParam(), R"(
542 %val1 = OpIMul %s32 %s32_0 %s32_1
543 %val2 = OpIMul %s32 %s32_2 %s32_0
544 %val3 = OpIMul %s32 %s32_m1 %s32_2
545 %val4 = OpIMul %s32 %s32_1 %s32_1
546 )");
547 }
548 
TEST_P(MarkvTest,F32Add)549 TEST_P(MarkvTest, F32Add) {
550   TestEncodeDecodeShaderMainBody(GetParam(), R"(
551 %val1 = OpFAdd %f32 %f32_0 %f32_1
552 %val2 = OpFAdd %f32 %f32_2 %f32_0
553 %val3 = OpFAdd %f32 %f32_pi %f32_2
554 %val4 = OpFAdd %f32 %f32_1 %f32_1
555 )");
556 }
557 
TEST_P(MarkvTest,U32Add)558 TEST_P(MarkvTest, U32Add) {
559   TestEncodeDecodeShaderMainBody(GetParam(), R"(
560 %val1 = OpIAdd %u32 %u32_0 %u32_1
561 %val2 = OpIAdd %u32 %u32_2 %u32_0
562 %val3 = OpIAdd %u32 %u32_3 %u32_2
563 %val4 = OpIAdd %u32 %u32_1 %u32_1
564 )");
565 }
566 
TEST_P(MarkvTest,S32Add)567 TEST_P(MarkvTest, S32Add) {
568   TestEncodeDecodeShaderMainBody(GetParam(), R"(
569 %val1 = OpIAdd %s32 %s32_0 %s32_1
570 %val2 = OpIAdd %s32 %s32_2 %s32_0
571 %val3 = OpIAdd %s32 %s32_m1 %s32_2
572 %val4 = OpIAdd %s32 %s32_1 %s32_1
573 )");
574 }
575 
TEST_P(MarkvTest,F32Dot)576 TEST_P(MarkvTest, F32Dot) {
577   TestEncodeDecodeShaderMainBody(GetParam(), R"(
578 %dot2_1 = OpDot %f32 %f32vec2_01 %f32vec2_12
579 %dot2_2 = OpDot %f32 %f32vec2_01 %f32vec2_01
580 %dot2_3 = OpDot %f32 %f32vec2_12 %f32vec2_12
581 %dot3_1 = OpDot %f32 %f32vec3_012 %f32vec3_123
582 %dot3_2 = OpDot %f32 %f32vec3_012 %f32vec3_012
583 %dot3_3 = OpDot %f32 %f32vec3_123 %f32vec3_123
584 %dot4_1 = OpDot %f32 %f32vec4_0123 %f32vec4_1234
585 %dot4_2 = OpDot %f32 %f32vec4_0123 %f32vec4_0123
586 %dot4_3 = OpDot %f32 %f32vec4_1234 %f32vec4_1234
587 )");
588 }
589 
TEST_P(MarkvTest,F32VectorCompositeConstruct)590 TEST_P(MarkvTest, F32VectorCompositeConstruct) {
591   TestEncodeDecodeShaderMainBody(GetParam(), R"(
592 %cc1 = OpCompositeConstruct %f32vec4 %f32vec2_01 %f32vec2_12
593 %cc2 = OpCompositeConstruct %f32vec3 %f32vec2_01 %f32_2
594 %cc3 = OpCompositeConstruct %f32vec2 %f32_1 %f32_2
595 %cc4 = OpCompositeConstruct %f32vec4 %f32_1 %f32_2 %cc3
596 )");
597 }
598 
TEST_P(MarkvTest,U32VectorCompositeConstruct)599 TEST_P(MarkvTest, U32VectorCompositeConstruct) {
600   TestEncodeDecodeShaderMainBody(GetParam(), R"(
601 %cc1 = OpCompositeConstruct %u32vec4 %u32vec2_01 %u32vec2_12
602 %cc2 = OpCompositeConstruct %u32vec3 %u32vec2_01 %u32_2
603 %cc3 = OpCompositeConstruct %u32vec2 %u32_1 %u32_2
604 %cc4 = OpCompositeConstruct %u32vec4 %u32_1 %u32_2 %cc3
605 )");
606 }
607 
TEST_P(MarkvTest,S32VectorCompositeConstruct)608 TEST_P(MarkvTest, S32VectorCompositeConstruct) {
609   TestEncodeDecodeShaderMainBody(GetParam(), R"(
610 %cc1 = OpCompositeConstruct %u32vec4 %u32vec2_01 %u32vec2_12
611 %cc2 = OpCompositeConstruct %u32vec3 %u32vec2_01 %u32_2
612 %cc3 = OpCompositeConstruct %u32vec2 %u32_1 %u32_2
613 %cc4 = OpCompositeConstruct %u32vec4 %u32_1 %u32_2 %cc3
614 )");
615 }
616 
TEST_P(MarkvTest,F32VectorCompositeExtract)617 TEST_P(MarkvTest, F32VectorCompositeExtract) {
618   TestEncodeDecodeShaderMainBody(GetParam(), R"(
619 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
620 %f32vec3_013 = OpCompositeExtract %f32vec3 %f32vec4_0123 0 1 3
621 )");
622 }
623 
TEST_P(MarkvTest,F32VectorComparison)624 TEST_P(MarkvTest, F32VectorComparison) {
625   TestEncodeDecodeShaderMainBody(GetParam(), R"(
626 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
627 %c1 = OpFOrdEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
628 %c2 = OpFUnordEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
629 %c3 = OpFOrdNotEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
630 %c4 = OpFUnordNotEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
631 %c5 = OpFOrdLessThan %boolvec4 %f32vec4_0123 %f32vec4_3210
632 %c6 = OpFUnordLessThan %boolvec4 %f32vec4_0123 %f32vec4_3210
633 %c7 = OpFOrdGreaterThan %boolvec4 %f32vec4_0123 %f32vec4_3210
634 %c8 = OpFUnordGreaterThan %boolvec4 %f32vec4_0123 %f32vec4_3210
635 %c9 = OpFOrdLessThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
636 %c10 = OpFUnordLessThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
637 %c11 = OpFOrdGreaterThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
638 %c12 = OpFUnordGreaterThanEqual %boolvec4 %f32vec4_0123 %f32vec4_3210
639 )");
640 }
641 
TEST_P(MarkvTest,VectorShuffle)642 TEST_P(MarkvTest, VectorShuffle) {
643   TestEncodeDecodeShaderMainBody(GetParam(), R"(
644 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
645 %sh1 = OpVectorShuffle %f32vec2 %f32vec4_0123 %f32vec4_3210 3 6
646 %sh2 = OpVectorShuffle %f32vec3 %f32vec2_01 %f32vec4_3210 0 3 4
647 )");
648 }
649 
TEST_P(MarkvTest,VectorTimesScalar)650 TEST_P(MarkvTest, VectorTimesScalar) {
651   TestEncodeDecodeShaderMainBody(GetParam(), R"(
652 %f32vec4_3210 = OpCompositeConstruct %f32vec4 %f32_3 %f32_2 %f32_1 %f32_0
653 %res1 = OpVectorTimesScalar %f32vec4 %f32vec4_0123 %f32_2
654 %res2 = OpVectorTimesScalar %f32vec4 %f32vec4_3210 %f32_2
655 )");
656 }
657 
TEST_P(MarkvTest,SpirvSpecSample)658 TEST_P(MarkvTest, SpirvSpecSample) {
659   TestEncodeDecode(GetParam(), R"(
660                OpCapability Shader
661           %1 = OpExtInstImport "GLSL.std.450"
662                OpMemoryModel Logical GLSL450
663                OpEntryPoint Fragment %4 "main" %31 %33 %42 %57
664                OpExecutionMode %4 OriginLowerLeft
665 
666 ; Debug information
667                OpSource GLSL 450
668                OpName %4 "main"
669                OpName %9 "scale"
670                OpName %17 "S"
671                OpMemberName %17 0 "b"
672                OpMemberName %17 1 "v"
673                OpMemberName %17 2 "i"
674                OpName %18 "blockName"
675                OpMemberName %18 0 "s"
676                OpMemberName %18 1 "cond"
677                OpName %20 ""
678                OpName %31 "color"
679                OpName %33 "color1"
680                OpName %42 "color2"
681                OpName %48 "i"
682                OpName %57 "multiplier"
683 
684 ; Annotations (non-debug)
685                OpDecorate %15 ArrayStride 16
686                OpMemberDecorate %17 0 Offset 0
687                OpMemberDecorate %17 1 Offset 16
688                OpMemberDecorate %17 2 Offset 96
689                OpMemberDecorate %18 0 Offset 0
690                OpMemberDecorate %18 1 Offset 112
691                OpDecorate %18 Block
692                OpDecorate %20 DescriptorSet 0
693                OpDecorate %42 NoPerspective
694 
695 ; All types, variables, and constants
696           %2 = OpTypeVoid
697           %3 = OpTypeFunction %2                      ; void ()
698           %6 = OpTypeFloat 32                         ; 32-bit float
699           %7 = OpTypeVector %6 4                      ; vec4
700           %8 = OpTypePointer Function %7              ; function-local vec4*
701          %10 = OpConstant %6 1
702          %11 = OpConstant %6 2
703          %12 = OpConstantComposite %7 %10 %10 %11 %10 ; vec4(1.0, 1.0, 2.0, 1.0)
704          %13 = OpTypeInt 32 0                         ; 32-bit int, sign-less
705          %14 = OpConstant %13 5
706          %15 = OpTypeArray %7 %14
707          %16 = OpTypeInt 32 1
708          %17 = OpTypeStruct %13 %15 %16
709          %18 = OpTypeStruct %17 %13
710          %19 = OpTypePointer Uniform %18
711          %20 = OpVariable %19 Uniform
712          %21 = OpConstant %16 1
713          %22 = OpTypePointer Uniform %13
714          %25 = OpTypeBool
715          %26 = OpConstant %13 0
716          %30 = OpTypePointer Output %7
717          %31 = OpVariable %30 Output
718          %32 = OpTypePointer Input %7
719          %33 = OpVariable %32 Input
720          %35 = OpConstant %16 0
721          %36 = OpConstant %16 2
722          %37 = OpTypePointer Uniform %7
723          %42 = OpVariable %32 Input
724          %47 = OpTypePointer Function %16
725          %55 = OpConstant %16 4
726          %57 = OpVariable %32 Input
727 
728 ; All functions
729           %4 = OpFunction %2 None %3                  ; main()
730           %5 = OpLabel
731           %9 = OpVariable %8 Function
732          %48 = OpVariable %47 Function
733                OpStore %9 %12
734          %23 = OpAccessChain %22 %20 %21              ; location of cond
735          %24 = OpLoad %13 %23                         ; load 32-bit int from cond
736          %27 = OpINotEqual %25 %24 %26                ; convert to bool
737                OpSelectionMerge %29 None              ; structured if
738                OpBranchConditional %27 %28 %41        ; if cond
739          %28 = OpLabel                                ; then
740          %34 = OpLoad %7 %33
741          %38 = OpAccessChain %37 %20 %35 %21 %36      ; s.v[2]
742          %39 = OpLoad %7 %38
743          %40 = OpFAdd %7 %34 %39
744                OpStore %31 %40
745                OpBranch %29
746          %41 = OpLabel                                ; else
747          %43 = OpLoad %7 %42
748          %44 = OpExtInst %7 %1 Sqrt %43               ; extended instruction sqrt
749          %45 = OpLoad %7 %9
750          %46 = OpFMul %7 %44 %45
751                OpStore %31 %46
752                OpBranch %29
753          %29 = OpLabel                                ; endif
754                OpStore %48 %35
755                OpBranch %49
756          %49 = OpLabel
757                OpLoopMerge %51 %52 None               ; structured loop
758                OpBranch %53
759          %53 = OpLabel
760          %54 = OpLoad %16 %48
761          %56 = OpSLessThan %25 %54 %55                ; i < 4 ?
762                OpBranchConditional %56 %50 %51        ; body or break
763          %50 = OpLabel                                ; body
764          %58 = OpLoad %7 %57
765          %59 = OpLoad %7 %31
766          %60 = OpFMul %7 %59 %58
767                OpStore %31 %60
768                OpBranch %52
769          %52 = OpLabel                                ; continue target
770          %61 = OpLoad %16 %48
771          %62 = OpIAdd %16 %61 %21                     ; ++i
772                OpStore %48 %62
773                OpBranch %49                           ; loop back
774          %51 = OpLabel                                ; loop merge point
775                OpReturn
776                OpFunctionEnd
777 )");
778 }
779 
TEST_P(MarkvTest,SampleFromDeadBranchEliminationTest)780 TEST_P(MarkvTest, SampleFromDeadBranchEliminationTest) {
781   TestEncodeDecode(GetParam(), R"(
782 OpCapability Shader
783 %1 = OpExtInstImport "GLSL.std.450"
784 OpMemoryModel Logical GLSL450
785 OpEntryPoint Fragment %main "main" %gl_FragColor
786 OpExecutionMode %main OriginUpperLeft
787 OpSource GLSL 140
788 OpName %main "main"
789 OpName %gl_FragColor "gl_FragColor"
790 %void = OpTypeVoid
791 %5 = OpTypeFunction %void
792 %bool = OpTypeBool
793 %true = OpConstantTrue %bool
794 %float = OpTypeFloat 32
795 %v4float = OpTypeVector %float 4
796 %_ptr_Function_v4float = OpTypePointer Function %v4float
797 %float_0 = OpConstant %float 0
798 %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
799 %float_1 = OpConstant %float 1
800 %14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
801 %_ptr_Output_v4float = OpTypePointer Output %v4float
802 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
803 %_ptr_Input_v4float = OpTypePointer Input %v4float
804 %main = OpFunction %void None %5
805 %17 = OpLabel
806 OpSelectionMerge %18 None
807 OpBranchConditional %true %19 %20
808 %19 = OpLabel
809 OpBranch %18
810 %20 = OpLabel
811 OpBranch %18
812 %18 = OpLabel
813 %21 = OpPhi %v4float %12 %19 %14 %20
814 OpStore %gl_FragColor %21
815 OpReturn
816 OpFunctionEnd
817 )");
818 }
819 
820 INSTANTIATE_TEST_CASE_P(AllMarkvModels, MarkvTest,
821                         ::testing::ValuesIn(std::vector<MarkvModelType>{
822                             kMarkvModelShaderLite,
823                             kMarkvModelShaderMid,
824                             kMarkvModelShaderMax,
825                         }), );
826 
827 }  // namespace
828 }  // namespace comp
829 }  // namespace spvtools
830