1 // Copyright (c) 2021 Shiyu Liu
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 "gtest/gtest.h"
16 #include "source/fuzz/fuzzer_util.h"
17 #include "test/fuzz/fuzz_test_util.h"
18
19 namespace spvtools {
20 namespace fuzz {
21 namespace {
22
TEST(FuzzerUtilMaybeFindBlockTest,BasicTest)23 TEST(FuzzerUtilMaybeFindBlockTest, BasicTest) {
24 std::string shader = R"(
25 OpCapability Shader
26 %1 = OpExtInstImport "GLSL.std.450"
27 OpMemoryModel Logical GLSL450
28 OpEntryPoint Fragment %4 "main"
29 OpExecutionMode %4 OriginUpperLeft
30 OpSource ESSL 310
31 OpDecorate %8 RelaxedPrecision
32 %2 = OpTypeVoid
33 %3 = OpTypeFunction %2
34 %6 = OpTypeInt 32 1
35 %7 = OpTypePointer Function %6
36 %9 = OpConstant %6 1
37 %10 = OpConstant %6 2
38 %4 = OpFunction %2 None %3
39 %5 = OpLabel
40 %8 = OpVariable %7 Function
41 OpBranch %11
42 %11 = OpLabel
43 OpStore %8 %9
44 OpBranch %12
45 %12 = OpLabel
46 OpStore %8 %10
47 OpReturn
48 OpFunctionEnd
49 )";
50
51 const auto env = SPV_ENV_UNIVERSAL_1_4;
52 const auto consumer = nullptr;
53 const std::unique_ptr<opt::IRContext> context =
54 BuildModule(env, consumer, shader, kFuzzAssembleOption);
55 spvtools::ValidatorOptions validator_options;
56 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
57 kConsoleMessageConsumer));
58
59 // Only blocks with id 11 and 12 can be found.
60 // Should return nullptr when id is not a label or id was not found.
61 uint32_t block_id1 = 11;
62 uint32_t block_id2 = 12;
63 uint32_t block_id3 = 13;
64 uint32_t block_id4 = 8;
65
66 opt::IRContext* ir_context = context.get();
67 // Block with id 11 should be found.
68 ASSERT_TRUE(fuzzerutil::MaybeFindBlock(ir_context, block_id1) != nullptr);
69 // Block with id 12 should be found.
70 ASSERT_TRUE(fuzzerutil::MaybeFindBlock(ir_context, block_id2) != nullptr);
71 // Block with id 13 cannot be found.
72 ASSERT_FALSE(fuzzerutil::MaybeFindBlock(ir_context, block_id3) != nullptr);
73 // Block with id 8 exists but don't not of type OpLabel.
74 ASSERT_FALSE(fuzzerutil::MaybeFindBlock(ir_context, block_id4) != nullptr);
75 }
76
TEST(FuzzerutilTest,FuzzerUtilMaybeGetBoolConstantTest)77 TEST(FuzzerutilTest, FuzzerUtilMaybeGetBoolConstantTest) {
78 std::string shader = R"(
79 OpCapability Shader
80 %1 = OpExtInstImport "GLSL.std.450"
81 OpMemoryModel Logical GLSL450
82 OpEntryPoint Fragment %4 "main" %36
83 OpExecutionMode %4 OriginUpperLeft
84 OpSource ESSL 310
85 OpName %4 "main"
86 OpName %8 "b1"
87 OpName %10 "b2"
88 OpName %12 "b3"
89 OpName %13 "b4"
90 OpName %16 "f1"
91 OpName %18 "f2"
92 OpName %20 "cf1"
93 OpName %22 "cf2"
94 OpName %26 "i1"
95 OpName %28 "i2"
96 OpName %30 "ci1"
97 OpName %32 "ci2"
98 OpName %36 "value"
99 OpDecorate %26 RelaxedPrecision
100 OpDecorate %28 RelaxedPrecision
101 OpDecorate %30 RelaxedPrecision
102 OpDecorate %32 RelaxedPrecision
103 OpDecorate %36 Location 0
104 %2 = OpTypeVoid
105 %3 = OpTypeFunction %2
106 %6 = OpTypeBool
107 %7 = OpTypePointer Function %6
108 %9 = OpConstantTrue %6
109 %11 = OpConstantFalse %6
110 %14 = OpTypeFloat 32
111 %15 = OpTypePointer Function %14
112 %17 = OpConstant %14 1.23000002
113 %19 = OpConstant %14 1.11000001
114 %21 = OpConstant %14 2
115 %23 = OpConstant %14 3.29999995
116 %24 = OpTypeInt 32 1
117 %25 = OpTypePointer Function %24
118 %27 = OpConstant %24 1
119 %29 = OpConstant %24 100
120 %31 = OpConstant %24 123
121 %33 = OpConstant %24 1111
122 %35 = OpTypePointer Input %14
123 %36 = OpVariable %35 Input
124 %4 = OpFunction %2 None %3
125 %5 = OpLabel
126 %8 = OpVariable %7 Function
127 %10 = OpVariable %7 Function
128 %12 = OpVariable %7 Function
129 %13 = OpVariable %7 Function
130 %16 = OpVariable %15 Function
131 %18 = OpVariable %15 Function
132 %20 = OpVariable %15 Function
133 %22 = OpVariable %15 Function
134 %26 = OpVariable %25 Function
135 %28 = OpVariable %25 Function
136 %30 = OpVariable %25 Function
137 %32 = OpVariable %25 Function
138 OpStore %8 %9
139 OpStore %10 %11
140 OpStore %12 %9
141 OpStore %13 %11
142 OpStore %16 %17
143 OpStore %18 %19
144 OpStore %20 %21
145 OpStore %22 %23
146 OpStore %26 %27
147 OpStore %28 %29
148 OpStore %30 %31
149 OpStore %32 %33
150 OpReturn
151 OpFunctionEnd
152 )";
153
154 const auto env = SPV_ENV_UNIVERSAL_1_4;
155 const auto consumer = nullptr;
156 const std::unique_ptr<opt::IRContext> context =
157 BuildModule(env, consumer, shader, kFuzzAssembleOption);
158 spvtools::ValidatorOptions validator_options;
159 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
160 kConsoleMessageConsumer));
161 TransformationContext transformation_context(
162 MakeUnique<FactManager>(context.get()), validator_options);
163
164 opt::IRContext* ir_context = context.get();
165 // A bool constant with value false exists and the id is 11.
166 ASSERT_EQ(11, fuzzerutil::MaybeGetBoolConstant(
167 ir_context, transformation_context, false, false));
168 // A bool constant with value true exists and the id is 9.
169 ASSERT_EQ(9, fuzzerutil::MaybeGetBoolConstant(
170 ir_context, transformation_context, true, false));
171 }
172
TEST(FuzzerutilTest,FuzzerUtilMaybeGetBoolTypeTest)173 TEST(FuzzerutilTest, FuzzerUtilMaybeGetBoolTypeTest) {
174 std::string shader = R"(
175 OpCapability Shader
176 %1 = OpExtInstImport "GLSL.std.450"
177 OpMemoryModel Logical GLSL450
178 OpEntryPoint Fragment %4 "main" %92 %52 %53
179 OpExecutionMode %4 OriginUpperLeft
180 OpSource ESSL 310
181 OpDecorate %92 BuiltIn FragCoord
182 %2 = OpTypeVoid
183 %3 = OpTypeFunction %2
184 %6 = OpTypeInt 32 1
185 %7 = OpTypeFloat 32
186 %8 = OpTypeStruct %6 %7
187 %9 = OpTypePointer Function %8
188 %10 = OpTypeFunction %6 %9
189 %14 = OpConstant %6 0
190 %15 = OpTypePointer Function %6
191 %51 = OpTypePointer Private %6
192 %21 = OpConstant %6 2
193 %23 = OpConstant %6 1
194 %24 = OpConstant %7 1
195 %25 = OpTypePointer Function %7
196 %50 = OpTypePointer Private %7
197 %34 = OpTypeBool
198 %35 = OpConstantFalse %34
199 %52 = OpVariable %50 Private
200 %53 = OpVariable %51 Private
201 %80 = OpConstantComposite %8 %21 %24
202 %90 = OpTypeVector %7 4
203 %91 = OpTypePointer Input %90
204 %92 = OpVariable %91 Input
205 %93 = OpConstantComposite %90 %24 %24 %24 %24
206 %4 = OpFunction %2 None %3
207 %5 = OpLabel
208 %20 = OpVariable %9 Function
209 %27 = OpVariable %9 Function
210 %22 = OpAccessChain %15 %20 %14
211 %44 = OpCopyObject %9 %20
212 %26 = OpAccessChain %25 %20 %23
213 %29 = OpFunctionCall %6 %12 %27
214 %30 = OpAccessChain %15 %20 %14
215 %45 = OpCopyObject %15 %30
216 %81 = OpCopyObject %9 %27
217 %33 = OpAccessChain %15 %20 %14
218 OpSelectionMerge %37 None
219 OpBranchConditional %35 %36 %37
220 %36 = OpLabel
221 %38 = OpAccessChain %15 %20 %14
222 %40 = OpAccessChain %15 %20 %14
223 %43 = OpAccessChain %15 %20 %14
224 %82 = OpCopyObject %9 %27
225 OpBranch %37
226 %37 = OpLabel
227 OpReturn
228 OpFunctionEnd
229 %12 = OpFunction %6 None %10
230 %11 = OpFunctionParameter %9
231 %13 = OpLabel
232 %46 = OpCopyObject %9 %11
233 %16 = OpAccessChain %15 %11 %14
234 %95 = OpCopyObject %8 %80
235 OpReturnValue %21
236 %100 = OpLabel
237 OpUnreachable
238 OpFunctionEnd
239 )";
240
241 const auto env = SPV_ENV_UNIVERSAL_1_4;
242 const auto consumer = nullptr;
243 const std::unique_ptr<opt::IRContext> context =
244 BuildModule(env, consumer, shader, kFuzzAssembleOption);
245 spvtools::ValidatorOptions validator_options;
246 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
247 kConsoleMessageConsumer));
248
249 opt::IRContext* ir_context = context.get();
250 // A bool type with result id of 34 exists.
251 ASSERT_TRUE(fuzzerutil::MaybeGetBoolType(ir_context));
252 }
253
TEST(FuzzerutilTest,FuzzerUtilMaybeGetCompositeConstantTest)254 TEST(FuzzerutilTest, FuzzerUtilMaybeGetCompositeConstantTest) {
255 std::string shader = R"(
256 OpCapability Shader
257 %1 = OpExtInstImport "GLSL.std.450"
258 OpMemoryModel Logical GLSL450
259 OpEntryPoint Fragment %4 "main" %54
260 OpExecutionMode %4 OriginUpperLeft
261 OpSource ESSL 310
262 OpName %4 "main"
263 OpName %8 "b1"
264 OpName %10 "b2"
265 OpName %12 "b3"
266 OpName %13 "b4"
267 OpName %16 "f1"
268 OpName %18 "f2"
269 OpName %22 "zc"
270 OpName %24 "i1"
271 OpName %28 "i2"
272 OpName %30 "i3"
273 OpName %32 "i4"
274 OpName %37 "f_arr"
275 OpName %47 "i_arr"
276 OpName %54 "value"
277 OpDecorate %22 RelaxedPrecision
278 OpDecorate %24 RelaxedPrecision
279 OpDecorate %28 RelaxedPrecision
280 OpDecorate %30 RelaxedPrecision
281 OpDecorate %32 RelaxedPrecision
282 OpDecorate %47 RelaxedPrecision
283 OpDecorate %54 Location 0
284 %2 = OpTypeVoid
285 %3 = OpTypeFunction %2
286 %6 = OpTypeBool
287 %7 = OpTypePointer Function %6
288 %9 = OpConstantTrue %6
289 %11 = OpConstantFalse %6
290 %14 = OpTypeFloat 32
291 %15 = OpTypePointer Function %14
292 %17 = OpConstant %14 1.23000002
293 %19 = OpConstant %14 1.11000001
294 %20 = OpTypeInt 32 1
295 %21 = OpTypePointer Function %20
296 %23 = OpConstant %20 0
297 %25 = OpConstant %20 1
298 %26 = OpTypeInt 32 0
299 %27 = OpTypePointer Function %26
300 %29 = OpConstant %26 100
301 %31 = OpConstant %20 -1
302 %33 = OpConstant %20 -99
303 %34 = OpConstant %26 5
304 %35 = OpTypeArray %14 %34
305 %36 = OpTypePointer Function %35
306 %38 = OpConstant %14 5.5
307 %39 = OpConstant %14 4.4000001
308 %40 = OpConstant %14 3.29999995
309 %41 = OpConstant %14 2.20000005
310 %42 = OpConstant %14 1.10000002
311 %43 = OpConstantComposite %35 %38 %39 %40 %41 %42
312 %44 = OpConstant %26 3
313 %45 = OpTypeArray %20 %44
314 %46 = OpTypePointer Function %45
315 %48 = OpConstant %20 3
316 %49 = OpConstant %20 7
317 %50 = OpConstant %20 9
318 %51 = OpConstantComposite %45 %48 %49 %50
319 %53 = OpTypePointer Input %14
320 %54 = OpVariable %53 Input
321 %4 = OpFunction %2 None %3
322 %5 = OpLabel
323 %8 = OpVariable %7 Function
324 %10 = OpVariable %7 Function
325 %12 = OpVariable %7 Function
326 %13 = OpVariable %7 Function
327 %16 = OpVariable %15 Function
328 %18 = OpVariable %15 Function
329 %22 = OpVariable %21 Function
330 %24 = OpVariable %21 Function
331 %28 = OpVariable %27 Function
332 %30 = OpVariable %21 Function
333 %32 = OpVariable %21 Function
334 %37 = OpVariable %36 Function
335 %47 = OpVariable %46 Function
336 OpStore %8 %9
337 OpStore %10 %11
338 OpStore %12 %9
339 OpStore %13 %11
340 OpStore %16 %17
341 OpStore %18 %19
342 OpStore %22 %23
343 OpStore %24 %25
344 OpStore %28 %29
345 OpStore %30 %31
346 OpStore %32 %33
347 OpStore %37 %43
348 OpStore %47 %51
349 OpReturn
350 OpFunctionEnd
351 )";
352
353 const auto env = SPV_ENV_UNIVERSAL_1_4;
354 const auto consumer = nullptr;
355 const std::unique_ptr<opt::IRContext> context =
356 BuildModule(env, consumer, shader, kFuzzAssembleOption);
357 spvtools::ValidatorOptions validator_options;
358 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
359 kConsoleMessageConsumer));
360 TransformationContext transformation_context(
361 MakeUnique<FactManager>(context.get()), validator_options);
362
363 opt::IRContext* ir_context = context.get();
364
365 // %43 = OpConstantComposite %35 %38 %39 %40 %41 %42
366 // %51 = OpConstantComposite %45 %48 %49 %50
367 // This should pass as a float array with 5 elements exist and its id is 43.
368 ASSERT_EQ(43, fuzzerutil::MaybeGetCompositeConstant(
369 ir_context, transformation_context, {38, 39, 40, 41, 42},
370 35, false));
371 // This should pass as an int array with 3 elements exist and its id is 51.
372 ASSERT_EQ(51,
373 fuzzerutil::MaybeGetCompositeConstant(
374 ir_context, transformation_context, {48, 49, 50}, 45, false));
375 // An int array with 2 elements does not exist.
376 ASSERT_EQ(0, fuzzerutil::MaybeGetCompositeConstant(
377 ir_context, transformation_context, {48, 49}, 45, false));
378 }
379
TEST(FuzzerutilTest,FuzzerUtilMaybeGetFloatConstantTest)380 TEST(FuzzerutilTest, FuzzerUtilMaybeGetFloatConstantTest) {
381 std::string shader = R"(
382 OpCapability Shader
383 %1 = OpExtInstImport "GLSL.std.450"
384 OpMemoryModel Logical GLSL450
385 OpEntryPoint Fragment %4 "main" %36
386 OpExecutionMode %4 OriginUpperLeft
387 OpSource ESSL 310
388 OpName %4 "main"
389 OpName %8 "b1"
390 OpName %10 "b2"
391 OpName %12 "b3"
392 OpName %13 "b4"
393 OpName %16 "f1"
394 OpName %18 "f2"
395 OpName %20 "cf1"
396 OpName %22 "cf2"
397 OpName %26 "i1"
398 OpName %28 "i2"
399 OpName %30 "ci1"
400 OpName %32 "ci2"
401 OpName %36 "value"
402 OpDecorate %26 RelaxedPrecision
403 OpDecorate %28 RelaxedPrecision
404 OpDecorate %30 RelaxedPrecision
405 OpDecorate %32 RelaxedPrecision
406 OpDecorate %36 Location 0
407 %2 = OpTypeVoid
408 %3 = OpTypeFunction %2
409 %6 = OpTypeBool
410 %7 = OpTypePointer Function %6
411 %9 = OpConstantTrue %6
412 %11 = OpConstantFalse %6
413 %14 = OpTypeFloat 32
414 %15 = OpTypePointer Function %14
415 %17 = OpConstant %14 1.23000002
416 %19 = OpConstant %14 1.11000001
417 %21 = OpConstant %14 2
418 %23 = OpConstant %14 3.29999995
419 %24 = OpTypeInt 32 1
420 %25 = OpTypePointer Function %24
421 %27 = OpConstant %24 1
422 %29 = OpConstant %24 100
423 %31 = OpConstant %24 123
424 %33 = OpConstant %24 1111
425 %35 = OpTypePointer Input %14
426 %36 = OpVariable %35 Input
427 %4 = OpFunction %2 None %3
428 %5 = OpLabel
429 %8 = OpVariable %7 Function
430 %10 = OpVariable %7 Function
431 %12 = OpVariable %7 Function
432 %13 = OpVariable %7 Function
433 %16 = OpVariable %15 Function
434 %18 = OpVariable %15 Function
435 %20 = OpVariable %15 Function
436 %22 = OpVariable %15 Function
437 %26 = OpVariable %25 Function
438 %28 = OpVariable %25 Function
439 %30 = OpVariable %25 Function
440 %32 = OpVariable %25 Function
441 OpStore %8 %9
442 OpStore %10 %11
443 OpStore %12 %9
444 OpStore %13 %11
445 OpStore %16 %17
446 OpStore %18 %19
447 OpStore %20 %21
448 OpStore %22 %23
449 OpStore %26 %27
450 OpStore %28 %29
451 OpStore %30 %31
452 OpStore %32 %33
453 OpReturn
454 OpFunctionEnd
455 )";
456
457 const auto env = SPV_ENV_UNIVERSAL_1_4;
458 const auto consumer = nullptr;
459 const std::unique_ptr<opt::IRContext> context =
460 BuildModule(env, consumer, shader, kFuzzAssembleOption);
461 spvtools::ValidatorOptions validator_options;
462 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
463 kConsoleMessageConsumer));
464 TransformationContext transformation_context(
465 MakeUnique<FactManager>(context.get()), validator_options);
466
467 opt::IRContext* ir_context = context.get();
468
469 uint32_t word1 = fuzzerutil::FloatToWord(2);
470 uint32_t word2 = fuzzerutil::FloatToWord(1.23f);
471
472 // A 32 bit float constant of value 2 exists and its id is 21.
473 ASSERT_EQ(21, fuzzerutil::MaybeGetFloatConstant(
474 ir_context, transformation_context,
475 std::vector<uint32_t>{word1}, 32, false));
476 // A 32 bit float constant of value 1.23 exists and its id is 17.
477 ASSERT_EQ(17, fuzzerutil::MaybeGetFloatConstant(
478 ir_context, transformation_context,
479 std::vector<uint32_t>{word2}, 32, false));
480 }
481
TEST(FuzzerutilTest,FuzzerUtilMaybeGetFloatTypeTest)482 TEST(FuzzerutilTest, FuzzerUtilMaybeGetFloatTypeTest) {
483 std::string shader = R"(
484 OpCapability Shader
485 %1 = OpExtInstImport "GLSL.std.450"
486 OpMemoryModel Logical GLSL450
487 OpEntryPoint Fragment %4 "main" %92 %52 %53
488 OpExecutionMode %4 OriginUpperLeft
489 OpSource ESSL 310
490 OpDecorate %92 BuiltIn FragCoord
491 %2 = OpTypeVoid
492 %3 = OpTypeFunction %2
493 %6 = OpTypeInt 32 1
494 %7 = OpTypeFloat 32
495 %8 = OpTypeStruct %6 %7
496 %9 = OpTypePointer Function %8
497 %10 = OpTypeFunction %6 %9
498 %14 = OpConstant %6 0
499 %15 = OpTypePointer Function %6
500 %51 = OpTypePointer Private %6
501 %21 = OpConstant %6 2
502 %23 = OpConstant %6 1
503 %24 = OpConstant %7 1
504 %25 = OpTypePointer Function %7
505 %50 = OpTypePointer Private %7
506 %34 = OpTypeBool
507 %35 = OpConstantFalse %34
508 %52 = OpVariable %50 Private
509 %53 = OpVariable %51 Private
510 %80 = OpConstantComposite %8 %21 %24
511 %90 = OpTypeVector %7 4
512 %91 = OpTypePointer Input %90
513 %92 = OpVariable %91 Input
514 %93 = OpConstantComposite %90 %24 %24 %24 %24
515 %4 = OpFunction %2 None %3
516 %5 = OpLabel
517 %20 = OpVariable %9 Function
518 %27 = OpVariable %9 Function
519 %22 = OpAccessChain %15 %20 %14
520 %44 = OpCopyObject %9 %20
521 %26 = OpAccessChain %25 %20 %23
522 %29 = OpFunctionCall %6 %12 %27
523 %30 = OpAccessChain %15 %20 %14
524 %45 = OpCopyObject %15 %30
525 %81 = OpCopyObject %9 %27
526 %33 = OpAccessChain %15 %20 %14
527 OpSelectionMerge %37 None
528 OpBranchConditional %35 %36 %37
529 %36 = OpLabel
530 %38 = OpAccessChain %15 %20 %14
531 %40 = OpAccessChain %15 %20 %14
532 %43 = OpAccessChain %15 %20 %14
533 %82 = OpCopyObject %9 %27
534 OpBranch %37
535 %37 = OpLabel
536 OpReturn
537 OpFunctionEnd
538 %12 = OpFunction %6 None %10
539 %11 = OpFunctionParameter %9
540 %13 = OpLabel
541 %46 = OpCopyObject %9 %11
542 %16 = OpAccessChain %15 %11 %14
543 %95 = OpCopyObject %8 %80
544 OpReturnValue %21
545 %100 = OpLabel
546 OpUnreachable
547 OpFunctionEnd
548 )";
549
550 const auto env = SPV_ENV_UNIVERSAL_1_4;
551 const auto consumer = nullptr;
552 const std::unique_ptr<opt::IRContext> context =
553 BuildModule(env, consumer, shader, kFuzzAssembleOption);
554 spvtools::ValidatorOptions validator_options;
555 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
556 kConsoleMessageConsumer));
557
558 opt::IRContext* ir_context = context.get();
559 // A float type with width = 32 and result id of 7 exists.
560 ASSERT_EQ(7, fuzzerutil::MaybeGetFloatType(ir_context, 32));
561
562 // A float int type with width = 32 exists, but the id should be 7.
563 ASSERT_NE(5, fuzzerutil::MaybeGetFloatType(ir_context, 32));
564
565 // A float type with width 30 does not exist.
566 ASSERT_EQ(0, fuzzerutil::MaybeGetFloatType(ir_context, 30));
567 }
568
TEST(FuzzerutilTest,FuzzerUtilMaybeGetIntegerConstantFromValueAndTypeTest)569 TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerConstantFromValueAndTypeTest) {
570 std::string shader = R"(
571 OpCapability Shader
572 %1 = OpExtInstImport "GLSL.std.450"
573 OpMemoryModel Logical GLSL450
574 OpEntryPoint Fragment %4 "main" %36
575 OpExecutionMode %4 OriginUpperLeft
576 OpSource ESSL 310
577 OpName %4 "main"
578 OpName %8 "b1"
579 OpName %10 "b2"
580 OpName %12 "b3"
581 OpName %13 "b4"
582 OpName %16 "f1"
583 OpName %18 "f2"
584 OpName %22 "zc"
585 OpName %24 "i1"
586 OpName %28 "i2"
587 OpName %30 "i3"
588 OpName %32 "i4"
589 OpName %36 "value"
590 OpDecorate %22 RelaxedPrecision
591 OpDecorate %24 RelaxedPrecision
592 OpDecorate %28 RelaxedPrecision
593 OpDecorate %30 RelaxedPrecision
594 OpDecorate %32 RelaxedPrecision
595 OpDecorate %36 Location 0
596 %2 = OpTypeVoid
597 %3 = OpTypeFunction %2
598 %6 = OpTypeBool
599 %7 = OpTypePointer Function %6
600 %9 = OpConstantTrue %6
601 %11 = OpConstantFalse %6
602 %14 = OpTypeFloat 32
603 %15 = OpTypePointer Function %14
604 %17 = OpConstant %14 1.23000002
605 %19 = OpConstant %14 1.11000001
606 %20 = OpTypeInt 32 1
607 %21 = OpTypePointer Function %20
608 %23 = OpConstant %20 0
609 %25 = OpConstant %20 1
610 %26 = OpTypeInt 32 0
611 %27 = OpTypePointer Function %26
612 %29 = OpConstant %26 100
613 %31 = OpConstant %20 -1
614 %33 = OpConstant %20 -99
615 %35 = OpTypePointer Input %14
616 %36 = OpVariable %35 Input
617 %4 = OpFunction %2 None %3
618 %5 = OpLabel
619 %8 = OpVariable %7 Function
620 %10 = OpVariable %7 Function
621 %12 = OpVariable %7 Function
622 %13 = OpVariable %7 Function
623 %16 = OpVariable %15 Function
624 %18 = OpVariable %15 Function
625 %22 = OpVariable %21 Function
626 %24 = OpVariable %21 Function
627 %28 = OpVariable %27 Function
628 %30 = OpVariable %21 Function
629 %32 = OpVariable %21 Function
630 OpStore %8 %9
631 OpStore %10 %11
632 OpStore %12 %9
633 OpStore %13 %11
634 OpStore %16 %17
635 OpStore %18 %19
636 OpStore %22 %23
637 OpStore %24 %25
638 OpStore %28 %29
639 OpStore %30 %31
640 OpStore %32 %33
641 OpReturn
642 OpFunctionEnd
643 )";
644
645 const auto env = SPV_ENV_UNIVERSAL_1_4;
646 const auto consumer = nullptr;
647 const std::unique_ptr<opt::IRContext> context =
648 BuildModule(env, consumer, shader, kFuzzAssembleOption);
649 spvtools::ValidatorOptions validator_options;
650 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
651 kConsoleMessageConsumer));
652
653 opt::IRContext* ir_context = context.get();
654
655 // A 32 bit signed int constant (with int type id 20) with value 1 exists and
656 // the id is 25.
657 ASSERT_EQ(25, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context,
658 1, 20));
659 // A 32 bit unsigned int constant (with int type id 0) with value 100 exists
660 // and the id is 29.
661 ASSERT_EQ(29, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context,
662 100, 26));
663 // A 32 bit unsigned int constant with value 50 does not exist.
664 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context,
665 50, 26));
666 }
667
TEST(FuzzerutilTest,FuzzerUtilMaybeGetIntegerConstantTest)668 TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerConstantTest) {
669 std::string shader = R"(
670 OpCapability Shader
671 OpCapability Shader
672 %1 = OpExtInstImport "GLSL.std.450"
673 OpMemoryModel Logical GLSL450
674 OpEntryPoint Fragment %4 "main" %36
675 OpExecutionMode %4 OriginUpperLeft
676 OpSource ESSL 310
677 OpName %4 "main"
678 OpName %8 "b1"
679 OpName %10 "b2"
680 OpName %12 "b3"
681 OpName %13 "b4"
682 OpName %16 "f1"
683 OpName %18 "f2"
684 OpName %22 "zc"
685 OpName %24 "i1"
686 OpName %28 "i2"
687 OpName %30 "i3"
688 OpName %32 "i4"
689 OpName %36 "value"
690 OpDecorate %22 RelaxedPrecision
691 OpDecorate %24 RelaxedPrecision
692 OpDecorate %28 RelaxedPrecision
693 OpDecorate %30 RelaxedPrecision
694 OpDecorate %32 RelaxedPrecision
695 OpDecorate %36 Location 0
696 %2 = OpTypeVoid
697 %3 = OpTypeFunction %2
698 %6 = OpTypeBool
699 %7 = OpTypePointer Function %6
700 %9 = OpConstantTrue %6
701 %11 = OpConstantFalse %6
702 %14 = OpTypeFloat 32
703 %15 = OpTypePointer Function %14
704 %17 = OpConstant %14 1.23000002
705 %19 = OpConstant %14 1.11000001
706 %20 = OpTypeInt 32 1
707 %21 = OpTypePointer Function %20
708 %23 = OpConstant %20 0
709 %25 = OpConstant %20 1
710 %26 = OpTypeInt 32 0
711 %27 = OpTypePointer Function %26
712 %29 = OpConstant %26 100
713 %31 = OpConstant %20 -1
714 %33 = OpConstant %20 -99
715 %35 = OpTypePointer Input %14
716 %36 = OpVariable %35 Input
717 %4 = OpFunction %2 None %3
718 %5 = OpLabel
719 %8 = OpVariable %7 Function
720 %10 = OpVariable %7 Function
721 %12 = OpVariable %7 Function
722 %13 = OpVariable %7 Function
723 %16 = OpVariable %15 Function
724 %18 = OpVariable %15 Function
725 %22 = OpVariable %21 Function
726 %24 = OpVariable %21 Function
727 %28 = OpVariable %27 Function
728 %30 = OpVariable %21 Function
729 %32 = OpVariable %21 Function
730 OpStore %8 %9
731 OpStore %10 %11
732 OpStore %12 %9
733 OpStore %13 %11
734 OpStore %16 %17
735 OpStore %18 %19
736 OpStore %22 %23
737 OpStore %24 %25
738 OpStore %28 %29
739 OpStore %30 %31
740 OpStore %32 %33
741 OpReturn
742 OpFunctionEnd
743 )";
744
745 const auto env = SPV_ENV_UNIVERSAL_1_4;
746 const auto consumer = nullptr;
747 const std::unique_ptr<opt::IRContext> context =
748 BuildModule(env, consumer, shader, kFuzzAssembleOption);
749 spvtools::ValidatorOptions validator_options;
750 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
751 kConsoleMessageConsumer));
752 TransformationContext transformation_context(
753 MakeUnique<FactManager>(context.get()), validator_options);
754
755 opt::IRContext* ir_context = context.get();
756
757 // A 32 bit unsigned int constant with value 1 exists and the id is 25.
758 ASSERT_EQ(25, fuzzerutil::MaybeGetIntegerConstant(
759 ir_context, transformation_context,
760 std::vector<uint32_t>{1}, 32, true, false));
761 // A 32 bit unsigned int constant with value 100 exists and the id is 29.
762 ASSERT_EQ(29, fuzzerutil::MaybeGetIntegerConstant(
763 ir_context, transformation_context,
764 std::vector<uint32_t>{100}, 32, false, false));
765 // A 32 bit signed int constant with value 99 doesn't not exist and should
766 // return 0.
767 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerConstant(
768 ir_context, transformation_context,
769 std::vector<uint32_t>{99}, 32, true, false));
770 }
771
TEST(FuzzerutilTest,FuzzerUtilMaybeGetIntegerTypeTest)772 TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerTypeTest) {
773 std::string shader = R"(
774 OpCapability Shader
775 %1 = OpExtInstImport "GLSL.std.450"
776 OpMemoryModel Logical GLSL450
777 OpEntryPoint Fragment %4 "main" %92 %52 %53
778 OpExecutionMode %4 OriginUpperLeft
779 OpSource ESSL 310
780 OpDecorate %92 BuiltIn FragCoord
781 %2 = OpTypeVoid
782 %3 = OpTypeFunction %2
783 %6 = OpTypeInt 32 1
784 %7 = OpTypeFloat 32
785 %8 = OpTypeStruct %6 %7
786 %9 = OpTypePointer Function %8
787 %10 = OpTypeFunction %6 %9
788 %14 = OpConstant %6 0
789 %15 = OpTypePointer Function %6
790 %51 = OpTypePointer Private %6
791 %21 = OpConstant %6 2
792 %23 = OpConstant %6 1
793 %24 = OpConstant %7 1
794 %25 = OpTypePointer Function %7
795 %50 = OpTypePointer Private %7
796 %34 = OpTypeBool
797 %35 = OpConstantFalse %34
798 %52 = OpVariable %50 Private
799 %53 = OpVariable %51 Private
800 %80 = OpConstantComposite %8 %21 %24
801 %90 = OpTypeVector %7 4
802 %91 = OpTypePointer Input %90
803 %92 = OpVariable %91 Input
804 %93 = OpConstantComposite %90 %24 %24 %24 %24
805 %4 = OpFunction %2 None %3
806 %5 = OpLabel
807 %20 = OpVariable %9 Function
808 %27 = OpVariable %9 Function
809 %22 = OpAccessChain %15 %20 %14
810 %44 = OpCopyObject %9 %20
811 %26 = OpAccessChain %25 %20 %23
812 %29 = OpFunctionCall %6 %12 %27
813 %30 = OpAccessChain %15 %20 %14
814 %45 = OpCopyObject %15 %30
815 %81 = OpCopyObject %9 %27
816 %33 = OpAccessChain %15 %20 %14
817 OpSelectionMerge %37 None
818 OpBranchConditional %35 %36 %37
819 %36 = OpLabel
820 %38 = OpAccessChain %15 %20 %14
821 %40 = OpAccessChain %15 %20 %14
822 %43 = OpAccessChain %15 %20 %14
823 %82 = OpCopyObject %9 %27
824 OpBranch %37
825 %37 = OpLabel
826 OpReturn
827 OpFunctionEnd
828 %12 = OpFunction %6 None %10
829 %11 = OpFunctionParameter %9
830 %13 = OpLabel
831 %46 = OpCopyObject %9 %11
832 %16 = OpAccessChain %15 %11 %14
833 %95 = OpCopyObject %8 %80
834 OpReturnValue %21
835 %100 = OpLabel
836 OpUnreachable
837 OpFunctionEnd
838 )";
839
840 const auto env = SPV_ENV_UNIVERSAL_1_4;
841 const auto consumer = nullptr;
842 const std::unique_ptr<opt::IRContext> context =
843 BuildModule(env, consumer, shader, kFuzzAssembleOption);
844 spvtools::ValidatorOptions validator_options;
845 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
846 kConsoleMessageConsumer));
847
848 opt::IRContext* ir_context = context.get();
849
850 // A signed int type with width = 32 and result id of 6 exists.
851 ASSERT_EQ(6, fuzzerutil::MaybeGetIntegerType(ir_context, 32, true));
852
853 // A signed int type with width = 32 exists, but the id should be 6.
854 ASSERT_FALSE(fuzzerutil::MaybeGetIntegerType(ir_context, 32, true) == 5);
855
856 // A int type with width = 32 and result id of 6 exists, but it should be a
857 // signed int.
858 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 32, false));
859 // A signed int type with width 30 does not exist.
860 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 30, true));
861 // An unsigned int type with width 22 does not exist.
862 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 22, false));
863 }
864
TEST(FuzzerutilTest,FuzzerUtilMaybeGetPointerTypeTest)865 TEST(FuzzerutilTest, FuzzerUtilMaybeGetPointerTypeTest) {
866 std::string shader = R"(
867 OpCapability Shader
868 %1 = OpExtInstImport "GLSL.std.450"
869 OpMemoryModel Logical GLSL450
870 OpEntryPoint Fragment %4 "main" %92 %52 %53
871 OpExecutionMode %4 OriginUpperLeft
872 OpSource ESSL 310
873 OpDecorate %92 BuiltIn FragCoord
874 %2 = OpTypeVoid
875 %3 = OpTypeFunction %2
876 %6 = OpTypeInt 32 1
877 %7 = OpTypeFloat 32
878 %8 = OpTypeStruct %6 %7
879 %9 = OpTypePointer Function %8
880 %10 = OpTypeFunction %6 %9
881 %14 = OpConstant %6 0
882 %15 = OpTypePointer Function %6
883 %51 = OpTypePointer Private %6
884 %21 = OpConstant %6 2
885 %23 = OpConstant %6 1
886 %24 = OpConstant %7 1
887 %25 = OpTypePointer Function %7
888 %50 = OpTypePointer Private %7
889 %34 = OpTypeBool
890 %35 = OpConstantFalse %34
891 %52 = OpVariable %50 Private
892 %53 = OpVariable %51 Private
893 %80 = OpConstantComposite %8 %21 %24
894 %90 = OpTypeVector %7 4
895 %91 = OpTypePointer Input %90
896 %92 = OpVariable %91 Input
897 %93 = OpConstantComposite %90 %24 %24 %24 %24
898 %4 = OpFunction %2 None %3
899 %5 = OpLabel
900 %20 = OpVariable %9 Function
901 %27 = OpVariable %9 Function
902 %22 = OpAccessChain %15 %20 %14
903 %44 = OpCopyObject %9 %20
904 %26 = OpAccessChain %25 %20 %23
905 %29 = OpFunctionCall %6 %12 %27
906 %30 = OpAccessChain %15 %20 %14
907 %45 = OpCopyObject %15 %30
908 %81 = OpCopyObject %9 %27
909 %33 = OpAccessChain %15 %20 %14
910 OpSelectionMerge %37 None
911 OpBranchConditional %35 %36 %37
912 %36 = OpLabel
913 %38 = OpAccessChain %15 %20 %14
914 %40 = OpAccessChain %15 %20 %14
915 %43 = OpAccessChain %15 %20 %14
916 %82 = OpCopyObject %9 %27
917 OpBranch %37
918 %37 = OpLabel
919 OpReturn
920 OpFunctionEnd
921 %12 = OpFunction %6 None %10
922 %11 = OpFunctionParameter %9
923 %13 = OpLabel
924 %46 = OpCopyObject %9 %11
925 %16 = OpAccessChain %15 %11 %14
926 %95 = OpCopyObject %8 %80
927 OpReturnValue %21
928 %100 = OpLabel
929 OpUnreachable
930 OpFunctionEnd
931 )";
932
933 const auto env = SPV_ENV_UNIVERSAL_1_4;
934 const auto consumer = nullptr;
935 const std::unique_ptr<opt::IRContext> context =
936 BuildModule(env, consumer, shader, kFuzzAssembleOption);
937 spvtools::ValidatorOptions validator_options;
938 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
939 kConsoleMessageConsumer));
940
941 opt::IRContext* ir_context = context.get();
942 auto private_storage_class = spv::StorageClass::Private;
943 auto function_storage_class = spv::StorageClass::Function;
944 auto input_storage_class = spv::StorageClass::Input;
945
946 // A valid pointer must have the correct |pointee_type_id| and |storageClass|.
947 // A function type pointer with id = 9 and pointee type id 8 should be found.
948 ASSERT_EQ(9, fuzzerutil::MaybeGetPointerType(ir_context, 8,
949 function_storage_class));
950 // A function type pointer with id = 15 and pointee type id 6 should be found.
951 ASSERT_EQ(15, fuzzerutil::MaybeGetPointerType(ir_context, 6,
952 function_storage_class));
953 // A function type pointer with id = 25 and pointee type id 7 should be found.
954 ASSERT_EQ(25, fuzzerutil::MaybeGetPointerType(ir_context, 7,
955 function_storage_class));
956
957 // A private type pointer with id=51 and pointee type id 6 should be found.
958 ASSERT_EQ(51, fuzzerutil::MaybeGetPointerType(ir_context, 6,
959 private_storage_class));
960 // A function pointer with id=50 and pointee type id 7 should be found.
961 ASSERT_EQ(50, fuzzerutil::MaybeGetPointerType(ir_context, 7,
962 private_storage_class));
963
964 // A input type pointer with id=91 and pointee type id 90 should be found.
965 ASSERT_EQ(
966 91, fuzzerutil::MaybeGetPointerType(ir_context, 90, input_storage_class));
967
968 // A pointer with id=91 and pointee type 90 exists, but the type should be
969 // input.
970 ASSERT_EQ(0, fuzzerutil::MaybeGetPointerType(ir_context, 90,
971 function_storage_class));
972 // A input type pointer with id=91 exists but the pointee id should be 90.
973 ASSERT_EQ(
974 0, fuzzerutil::MaybeGetPointerType(ir_context, 89, input_storage_class));
975 // A input type pointer with pointee id 90 exists but result id of the pointer
976 // should be 91.
977 ASSERT_NE(
978 58, fuzzerutil::MaybeGetPointerType(ir_context, 90, input_storage_class));
979 }
980
TEST(FuzzerutilTest,FuzzerUtilMaybeGetScalarConstantTest)981 TEST(FuzzerutilTest, FuzzerUtilMaybeGetScalarConstantTest) {
982 std::string shader = R"(
983 OpCapability Shader
984 %1 = OpExtInstImport "GLSL.std.450"
985 OpMemoryModel Logical GLSL450
986 OpEntryPoint Fragment %4 "main" %56
987 OpExecutionMode %4 OriginUpperLeft
988 OpSource ESSL 310
989 OpName %4 "main"
990 OpName %8 "b1"
991 OpName %10 "b2"
992 OpName %12 "b3"
993 OpName %13 "b4"
994 OpName %16 "f1"
995 OpName %18 "f2"
996 OpName %22 "zc"
997 OpName %24 "i1"
998 OpName %28 "i2"
999 OpName %30 "i"
1000 OpName %32 "i3"
1001 OpName %34 "i4"
1002 OpName %39 "f_arr"
1003 OpName %49 "i_arr"
1004 OpName %56 "value"
1005 OpDecorate %22 RelaxedPrecision
1006 OpDecorate %24 RelaxedPrecision
1007 OpDecorate %28 RelaxedPrecision
1008 OpDecorate %30 RelaxedPrecision
1009 OpDecorate %32 RelaxedPrecision
1010 OpDecorate %34 RelaxedPrecision
1011 OpDecorate %49 RelaxedPrecision
1012 OpDecorate %56 Location 0
1013 %2 = OpTypeVoid
1014 %3 = OpTypeFunction %2
1015 %6 = OpTypeBool
1016 %7 = OpTypePointer Function %6
1017 %9 = OpConstantTrue %6
1018 %11 = OpConstantFalse %6
1019 %14 = OpTypeFloat 32
1020 %15 = OpTypePointer Function %14
1021 %17 = OpConstant %14 1.23000002
1022 %19 = OpConstant %14 1.11000001
1023 %20 = OpTypeInt 32 1
1024 %21 = OpTypePointer Function %20
1025 %23 = OpConstant %20 0
1026 %25 = OpConstant %20 1
1027 %26 = OpTypeInt 32 0
1028 %27 = OpTypePointer Function %26
1029 %29 = OpConstant %26 100
1030 %31 = OpConstant %26 0
1031 %33 = OpConstant %20 -1
1032 %35 = OpConstant %20 -99
1033 %36 = OpConstant %26 5
1034 %37 = OpTypeArray %14 %36
1035 %38 = OpTypePointer Function %37
1036 %40 = OpConstant %14 5.5
1037 %41 = OpConstant %14 4.4000001
1038 %42 = OpConstant %14 3.29999995
1039 %43 = OpConstant %14 2.20000005
1040 %44 = OpConstant %14 1.10000002
1041 %45 = OpConstantComposite %37 %40 %41 %42 %43 %44
1042 %46 = OpConstant %26 3
1043 %47 = OpTypeArray %20 %46
1044 %48 = OpTypePointer Function %47
1045 %50 = OpConstant %20 3
1046 %51 = OpConstant %20 7
1047 %52 = OpConstant %20 9
1048 %53 = OpConstantComposite %47 %50 %51 %52
1049 %55 = OpTypePointer Input %14
1050 %56 = OpVariable %55 Input
1051 %4 = OpFunction %2 None %3
1052 %5 = OpLabel
1053 %8 = OpVariable %7 Function
1054 %10 = OpVariable %7 Function
1055 %12 = OpVariable %7 Function
1056 %13 = OpVariable %7 Function
1057 %16 = OpVariable %15 Function
1058 %18 = OpVariable %15 Function
1059 %22 = OpVariable %21 Function
1060 %24 = OpVariable %21 Function
1061 %28 = OpVariable %27 Function
1062 %30 = OpVariable %27 Function
1063 %32 = OpVariable %21 Function
1064 %34 = OpVariable %21 Function
1065 %39 = OpVariable %38 Function
1066 %49 = OpVariable %48 Function
1067 OpStore %8 %9
1068 OpStore %10 %11
1069 OpStore %12 %9
1070 OpStore %13 %11
1071 OpStore %16 %17
1072 OpStore %18 %19
1073 OpStore %22 %23
1074 OpStore %24 %25
1075 OpStore %28 %29
1076 OpStore %30 %31
1077 OpStore %32 %33
1078 OpStore %34 %35
1079 OpStore %39 %45
1080 OpStore %49 %53
1081 OpReturn
1082 OpFunctionEnd
1083 )";
1084
1085 const auto env = SPV_ENV_UNIVERSAL_1_4;
1086 const auto consumer = nullptr;
1087 const std::unique_ptr<opt::IRContext> context =
1088 BuildModule(env, consumer, shader, kFuzzAssembleOption);
1089 spvtools::ValidatorOptions validator_options;
1090 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1091 kConsoleMessageConsumer));
1092 TransformationContext transformation_context(
1093 MakeUnique<FactManager>(context.get()), validator_options);
1094
1095 opt::IRContext* ir_context = context.get();
1096
1097 std::vector<uint32_t> uint_words1 = fuzzerutil::IntToWords(100, 32, false);
1098 std::vector<uint32_t> uint_words2 = fuzzerutil::IntToWords(0, 32, false);
1099 std::vector<uint32_t> int_words1 = fuzzerutil::IntToWords(-99, 32, true);
1100 std::vector<uint32_t> int_words2 = fuzzerutil::IntToWords(1, 32, true);
1101 uint32_t float_word1 = fuzzerutil::FloatToWord(1.11f);
1102 uint32_t float_word2 = fuzzerutil::FloatToWord(4.4f);
1103
1104 // A unsigned int of value 100 that has a scalar type id of 26 exists and its
1105 // id is 29.
1106 ASSERT_EQ(
1107 29, fuzzerutil::MaybeGetScalarConstant(ir_context, transformation_context,
1108 uint_words1, 26, false));
1109 // A unsigned int of value 0 that has a scalar type id of 26 exists and its id
1110 // is 29.
1111 ASSERT_EQ(
1112 31, fuzzerutil::MaybeGetScalarConstant(ir_context, transformation_context,
1113 uint_words2, 26, false));
1114 // A signed int of value -99 that has a scalar type id of 20 exists and its id
1115 // is 35.
1116 ASSERT_EQ(35, fuzzerutil::MaybeGetScalarConstant(
1117 ir_context, transformation_context, int_words1, 20, false));
1118 // A signed int of value 1 that has a scalar type id of 20 exists and its id
1119 // is 25.
1120 ASSERT_EQ(25, fuzzerutil::MaybeGetScalarConstant(
1121 ir_context, transformation_context, int_words2, 20, false));
1122 // A float of value 1.11 that has a scalar type id of 14 exists and its id
1123 // is 19.
1124 ASSERT_EQ(19, fuzzerutil::MaybeGetScalarConstant(
1125 ir_context, transformation_context,
1126 std::vector<uint32_t>{float_word1}, 14, false));
1127 // A signed int of value 1 that has a scalar type id of 20 exists and its id
1128 // is 25.
1129 ASSERT_EQ(41, fuzzerutil::MaybeGetScalarConstant(
1130 ir_context, transformation_context,
1131 std::vector<uint32_t>{float_word2}, 14, false));
1132 }
1133
TEST(FuzzerutilTest,FuzzerUtilMaybeGetStructTypeTest)1134 TEST(FuzzerutilTest, FuzzerUtilMaybeGetStructTypeTest) {
1135 std::string shader = R"(
1136 OpCapability Shader
1137 %1 = OpExtInstImport "GLSL.std.450"
1138 OpMemoryModel Logical GLSL450
1139 OpEntryPoint Fragment %4 "main" %92 %52 %53
1140 OpExecutionMode %4 OriginUpperLeft
1141 OpSource ESSL 310
1142 OpDecorate %92 BuiltIn FragCoord
1143 %2 = OpTypeVoid
1144 %3 = OpTypeFunction %2
1145 %6 = OpTypeInt 32 1
1146 %7 = OpTypeFloat 32
1147 %8 = OpTypeStruct %6 %7
1148 %9 = OpTypePointer Function %8
1149 %10 = OpTypeFunction %6 %9
1150 %14 = OpConstant %6 0
1151 %15 = OpTypePointer Function %6
1152 %51 = OpTypePointer Private %6
1153 %21 = OpConstant %6 2
1154 %23 = OpConstant %6 1
1155 %24 = OpConstant %7 1
1156 %25 = OpTypePointer Function %7
1157 %50 = OpTypePointer Private %7
1158 %34 = OpTypeBool
1159 %35 = OpConstantFalse %34
1160 %52 = OpVariable %50 Private
1161 %53 = OpVariable %51 Private
1162 %80 = OpConstantComposite %8 %21 %24
1163 %90 = OpTypeVector %7 4
1164 %91 = OpTypePointer Input %90
1165 %92 = OpVariable %91 Input
1166 %93 = OpConstantComposite %90 %24 %24 %24 %24
1167 %4 = OpFunction %2 None %3
1168 %5 = OpLabel
1169 %20 = OpVariable %9 Function
1170 %27 = OpVariable %9 Function
1171 %22 = OpAccessChain %15 %20 %14
1172 %44 = OpCopyObject %9 %20
1173 %26 = OpAccessChain %25 %20 %23
1174 %29 = OpFunctionCall %6 %12 %27
1175 %30 = OpAccessChain %15 %20 %14
1176 %45 = OpCopyObject %15 %30
1177 %81 = OpCopyObject %9 %27
1178 %33 = OpAccessChain %15 %20 %14
1179 OpSelectionMerge %37 None
1180 OpBranchConditional %35 %36 %37
1181 %36 = OpLabel
1182 %38 = OpAccessChain %15 %20 %14
1183 %40 = OpAccessChain %15 %20 %14
1184 %43 = OpAccessChain %15 %20 %14
1185 %82 = OpCopyObject %9 %27
1186 OpBranch %37
1187 %37 = OpLabel
1188 OpReturn
1189 OpFunctionEnd
1190 %12 = OpFunction %6 None %10
1191 %11 = OpFunctionParameter %9
1192 %13 = OpLabel
1193 %46 = OpCopyObject %9 %11
1194 %16 = OpAccessChain %15 %11 %14
1195 %95 = OpCopyObject %8 %80
1196 OpReturnValue %21
1197 %100 = OpLabel
1198 OpUnreachable
1199 OpFunctionEnd
1200 )";
1201
1202 const auto env = SPV_ENV_UNIVERSAL_1_4;
1203 const auto consumer = nullptr;
1204 const std::unique_ptr<opt::IRContext> context =
1205 BuildModule(env, consumer, shader, kFuzzAssembleOption);
1206 spvtools::ValidatorOptions validator_options;
1207 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1208 kConsoleMessageConsumer));
1209
1210 opt::IRContext* ir_context = context.get();
1211
1212 // 6 and 7 are all valid ids from OpTypeInt and OpTypeFloat
1213 // so the result id of 8 should be found.
1214 ASSERT_EQ(8, fuzzerutil::MaybeGetStructType(ir_context,
1215 std::vector<uint32_t>{6, 7}));
1216
1217 // |component_type_id| of 16 does not exist in the module, so such a struct
1218 // type cannot be found.
1219 ASSERT_EQ(0, fuzzerutil::MaybeGetStructType(ir_context,
1220 std::vector<uint32_t>(6, 16)));
1221
1222 // |component_type_id| of 10 is of OpTypeFunction type and thus the struct
1223 // cannot be found.
1224 ASSERT_EQ(0, fuzzerutil::MaybeGetStructType(ir_context,
1225 std::vector<uint32_t>(6, 10)));
1226 }
1227
TEST(FuzzerutilTest,FuzzerUtilMaybeGetVectorTypeTest)1228 TEST(FuzzerutilTest, FuzzerUtilMaybeGetVectorTypeTest) {
1229 std::string shader = R"(
1230 OpCapability Shader
1231 %1 = OpExtInstImport "GLSL.std.450"
1232 OpMemoryModel Logical GLSL450
1233 OpEntryPoint Fragment %4 "main" %92 %52 %53
1234 OpExecutionMode %4 OriginUpperLeft
1235 OpSource ESSL 310
1236 OpDecorate %92 BuiltIn FragCoord
1237 %2 = OpTypeVoid
1238 %3 = OpTypeFunction %2
1239 %6 = OpTypeInt 32 1
1240 %7 = OpTypeFloat 32
1241 %8 = OpTypeStruct %6 %7
1242 %9 = OpTypePointer Function %8
1243 %10 = OpTypeFunction %6 %9
1244 %14 = OpConstant %6 0
1245 %15 = OpTypePointer Function %6
1246 %51 = OpTypePointer Private %6
1247 %21 = OpConstant %6 2
1248 %23 = OpConstant %6 1
1249 %24 = OpConstant %7 1
1250 %25 = OpTypePointer Function %7
1251 %50 = OpTypePointer Private %7
1252 %34 = OpTypeBool
1253 %35 = OpConstantFalse %34
1254 %52 = OpVariable %50 Private
1255 %53 = OpVariable %51 Private
1256 %80 = OpConstantComposite %8 %21 %24
1257 %90 = OpTypeVector %7 4
1258 %91 = OpTypePointer Input %90
1259 %92 = OpVariable %91 Input
1260 %93 = OpConstantComposite %90 %24 %24 %24 %24
1261 %4 = OpFunction %2 None %3
1262 %5 = OpLabel
1263 %20 = OpVariable %9 Function
1264 %27 = OpVariable %9 Function
1265 %22 = OpAccessChain %15 %20 %14
1266 %44 = OpCopyObject %9 %20
1267 %26 = OpAccessChain %25 %20 %23
1268 %29 = OpFunctionCall %6 %12 %27
1269 %30 = OpAccessChain %15 %20 %14
1270 %45 = OpCopyObject %15 %30
1271 %81 = OpCopyObject %9 %27
1272 %33 = OpAccessChain %15 %20 %14
1273 OpSelectionMerge %37 None
1274 OpBranchConditional %35 %36 %37
1275 %36 = OpLabel
1276 %38 = OpAccessChain %15 %20 %14
1277 %40 = OpAccessChain %15 %20 %14
1278 %43 = OpAccessChain %15 %20 %14
1279 %82 = OpCopyObject %9 %27
1280 OpBranch %37
1281 %37 = OpLabel
1282 OpReturn
1283 OpFunctionEnd
1284 %12 = OpFunction %6 None %10
1285 %11 = OpFunctionParameter %9
1286 %13 = OpLabel
1287 %46 = OpCopyObject %9 %11
1288 %16 = OpAccessChain %15 %11 %14
1289 %95 = OpCopyObject %8 %80
1290 OpReturnValue %21
1291 %100 = OpLabel
1292 OpUnreachable
1293 OpFunctionEnd
1294 )";
1295
1296 const auto env = SPV_ENV_UNIVERSAL_1_4;
1297 const auto consumer = nullptr;
1298 const std::unique_ptr<opt::IRContext> context =
1299 BuildModule(env, consumer, shader, kFuzzAssembleOption);
1300 spvtools::ValidatorOptions validator_options;
1301 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1302 kConsoleMessageConsumer));
1303
1304 opt::IRContext* ir_context = context.get();
1305 // The vector type with |element_count| 4 and |component_type_id| 7
1306 // is present and has a result id of 90.
1307 ASSERT_EQ(90, fuzzerutil::MaybeGetVectorType(ir_context, 7, 4));
1308
1309 // The vector type with |element_count| 3 and |component_type_id| 7
1310 // is not present in the module.
1311 ASSERT_EQ(0, fuzzerutil::MaybeGetVectorType(ir_context, 7, 3));
1312
1313 #ifndef NDEBUG
1314 // It should abort with |component_type_id| of 100
1315 // |component_type_id| must be a valid result id of an OpTypeInt,
1316 // OpTypeFloat or OpTypeBool instruction in the module.
1317 ASSERT_DEATH(fuzzerutil::MaybeGetVectorType(ir_context, 100, 4),
1318 "\\|component_type_id\\| is invalid");
1319
1320 // It should abort with |element_count| of 5.
1321 // |element_count| must be in the range [2,4].
1322 ASSERT_DEATH(fuzzerutil::MaybeGetVectorType(ir_context, 7, 5),
1323 "Precondition: component count must be in range \\[2, 4\\].");
1324 #endif
1325 }
1326
TEST(FuzzerutilTest,FuzzerUtilMaybeGetVoidTypeTest)1327 TEST(FuzzerutilTest, FuzzerUtilMaybeGetVoidTypeTest) {
1328 std::string shader = R"(
1329 OpCapability Shader
1330 %1 = OpExtInstImport "GLSL.std.450"
1331 OpMemoryModel Logical GLSL450
1332 OpEntryPoint Fragment %4 "main" %92 %52 %53
1333 OpExecutionMode %4 OriginUpperLeft
1334 OpSource ESSL 310
1335 OpDecorate %92 BuiltIn FragCoord
1336 %2 = OpTypeVoid
1337 %3 = OpTypeFunction %2
1338 %6 = OpTypeInt 32 1
1339 %7 = OpTypeFloat 32
1340 %8 = OpTypeStruct %6 %7
1341 %9 = OpTypePointer Function %8
1342 %10 = OpTypeFunction %6 %9
1343 %14 = OpConstant %6 0
1344 %15 = OpTypePointer Function %6
1345 %51 = OpTypePointer Private %6
1346 %21 = OpConstant %6 2
1347 %23 = OpConstant %6 1
1348 %24 = OpConstant %7 1
1349 %25 = OpTypePointer Function %7
1350 %50 = OpTypePointer Private %7
1351 %34 = OpTypeBool
1352 %35 = OpConstantFalse %34
1353 %52 = OpVariable %50 Private
1354 %53 = OpVariable %51 Private
1355 %80 = OpConstantComposite %8 %21 %24
1356 %90 = OpTypeVector %7 4
1357 %91 = OpTypePointer Input %90
1358 %92 = OpVariable %91 Input
1359 %93 = OpConstantComposite %90 %24 %24 %24 %24
1360 %4 = OpFunction %2 None %3
1361 %5 = OpLabel
1362 %20 = OpVariable %9 Function
1363 %27 = OpVariable %9 Function
1364 %22 = OpAccessChain %15 %20 %14
1365 %44 = OpCopyObject %9 %20
1366 %26 = OpAccessChain %25 %20 %23
1367 %29 = OpFunctionCall %6 %12 %27
1368 %30 = OpAccessChain %15 %20 %14
1369 %45 = OpCopyObject %15 %30
1370 %81 = OpCopyObject %9 %27
1371 %33 = OpAccessChain %15 %20 %14
1372 OpSelectionMerge %37 None
1373 OpBranchConditional %35 %36 %37
1374 %36 = OpLabel
1375 %38 = OpAccessChain %15 %20 %14
1376 %40 = OpAccessChain %15 %20 %14
1377 %43 = OpAccessChain %15 %20 %14
1378 %82 = OpCopyObject %9 %27
1379 OpBranch %37
1380 %37 = OpLabel
1381 OpReturn
1382 OpFunctionEnd
1383 %12 = OpFunction %6 None %10
1384 %11 = OpFunctionParameter %9
1385 %13 = OpLabel
1386 %46 = OpCopyObject %9 %11
1387 %16 = OpAccessChain %15 %11 %14
1388 %95 = OpCopyObject %8 %80
1389 OpReturnValue %21
1390 %100 = OpLabel
1391 OpUnreachable
1392 OpFunctionEnd
1393 )";
1394
1395 const auto env = SPV_ENV_UNIVERSAL_1_4;
1396 const auto consumer = nullptr;
1397 const std::unique_ptr<opt::IRContext> context =
1398 BuildModule(env, consumer, shader, kFuzzAssembleOption);
1399 spvtools::ValidatorOptions validator_options;
1400 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1401 kConsoleMessageConsumer));
1402
1403 opt::IRContext* ir_context = context.get();
1404 // A void type with a result id of 2 can be found.
1405 ASSERT_EQ(2, fuzzerutil::MaybeGetVoidType(ir_context));
1406 }
1407
TEST(FuzzerutilTest,FuzzerUtilMaybeGetZeroConstantTest)1408 TEST(FuzzerutilTest, FuzzerUtilMaybeGetZeroConstantTest) {
1409 std::string shader = R"(
1410 OpCapability Shader
1411 %1 = OpExtInstImport "GLSL.std.450"
1412 OpMemoryModel Logical GLSL450
1413 OpEntryPoint Fragment %4 "main" %56
1414 OpExecutionMode %4 OriginUpperLeft
1415 OpSource ESSL 310
1416 OpName %4 "main"
1417 OpName %8 "b1"
1418 OpName %10 "b2"
1419 OpName %12 "b3"
1420 OpName %13 "b4"
1421 OpName %16 "f1"
1422 OpName %18 "f2"
1423 OpName %22 "zc"
1424 OpName %24 "i1"
1425 OpName %28 "i2"
1426 OpName %30 "i"
1427 OpName %32 "i3"
1428 OpName %34 "i4"
1429 OpName %39 "f_arr"
1430 OpName %49 "i_arr"
1431 OpName %56 "value"
1432 OpDecorate %22 RelaxedPrecision
1433 OpDecorate %24 RelaxedPrecision
1434 OpDecorate %28 RelaxedPrecision
1435 OpDecorate %30 RelaxedPrecision
1436 OpDecorate %32 RelaxedPrecision
1437 OpDecorate %34 RelaxedPrecision
1438 OpDecorate %49 RelaxedPrecision
1439 OpDecorate %56 Location 0
1440 %2 = OpTypeVoid
1441 %3 = OpTypeFunction %2
1442 %6 = OpTypeBool
1443 %7 = OpTypePointer Function %6
1444 %9 = OpConstantTrue %6
1445 %11 = OpConstantFalse %6
1446 %14 = OpTypeFloat 32
1447 %15 = OpTypePointer Function %14
1448 %17 = OpConstant %14 1.23000002
1449 %19 = OpConstant %14 1.11000001
1450 %20 = OpTypeInt 32 1
1451 %21 = OpTypePointer Function %20
1452 %23 = OpConstant %20 0
1453 %25 = OpConstant %20 1
1454 %26 = OpTypeInt 32 0
1455 %27 = OpTypePointer Function %26
1456 %29 = OpConstant %26 100
1457 %31 = OpConstant %26 0
1458 %33 = OpConstant %20 -1
1459 %35 = OpConstant %20 -99
1460 %36 = OpConstant %26 5
1461 %37 = OpTypeArray %14 %36
1462 %38 = OpTypePointer Function %37
1463 %40 = OpConstant %14 5.5
1464 %41 = OpConstant %14 4.4000001
1465 %42 = OpConstant %14 3.29999995
1466 %43 = OpConstant %14 2.20000005
1467 %44 = OpConstant %14 1.10000002
1468 %45 = OpConstantComposite %37 %40 %41 %42 %43 %44
1469 %46 = OpConstant %26 3
1470 %47 = OpTypeArray %20 %46
1471 %48 = OpTypePointer Function %47
1472 %50 = OpConstant %20 3
1473 %51 = OpConstant %20 7
1474 %52 = OpConstant %20 9
1475 %53 = OpConstantComposite %47 %50 %51 %52
1476 %55 = OpTypePointer Input %14
1477 %56 = OpVariable %55 Input
1478 %4 = OpFunction %2 None %3
1479 %5 = OpLabel
1480 %8 = OpVariable %7 Function
1481 %10 = OpVariable %7 Function
1482 %12 = OpVariable %7 Function
1483 %13 = OpVariable %7 Function
1484 %16 = OpVariable %15 Function
1485 %18 = OpVariable %15 Function
1486 %22 = OpVariable %21 Function
1487 %24 = OpVariable %21 Function
1488 %28 = OpVariable %27 Function
1489 %30 = OpVariable %27 Function
1490 %32 = OpVariable %21 Function
1491 %34 = OpVariable %21 Function
1492 %39 = OpVariable %38 Function
1493 %49 = OpVariable %48 Function
1494 OpStore %8 %9
1495 OpStore %10 %11
1496 OpStore %12 %9
1497 OpStore %13 %11
1498 OpStore %16 %17
1499 OpStore %18 %19
1500 OpStore %22 %23
1501 OpStore %24 %25
1502 OpStore %28 %29
1503 OpStore %30 %31
1504 OpStore %32 %33
1505 OpStore %34 %35
1506 OpStore %39 %45
1507 OpStore %49 %53
1508 OpReturn
1509 OpFunctionEnd
1510 )";
1511
1512 const auto env = SPV_ENV_UNIVERSAL_1_4;
1513 const auto consumer = nullptr;
1514 const std::unique_ptr<opt::IRContext> context =
1515 BuildModule(env, consumer, shader, kFuzzAssembleOption);
1516 spvtools::ValidatorOptions validator_options;
1517 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1518 kConsoleMessageConsumer));
1519 TransformationContext transformation_context(
1520 MakeUnique<FactManager>(context.get()), validator_options);
1521
1522 opt::IRContext* ir_context = context.get();
1523
1524 // The id of a boolean constant will be returned give boolean type id 6.
1525 uint32_t maybe_bool_id = fuzzerutil::MaybeGetZeroConstant(
1526 ir_context, transformation_context, 6, false);
1527 // The id of a 32 bit float constant will be returned given the float type
1528 // id 14.
1529 uint32_t maybe_float_id = fuzzerutil::MaybeGetZeroConstant(
1530 ir_context, transformation_context, 14, false);
1531 uint32_t maybe_signed_int_id = fuzzerutil::MaybeGetZeroConstant(
1532 ir_context, transformation_context, 20, false);
1533 uint32_t maybe_unsigned_int_id = fuzzerutil::MaybeGetZeroConstant(
1534 ir_context, transformation_context, 26, false);
1535
1536 // Lists of possible ids for float, signed int, unsigned int and array.
1537 std::vector<uint32_t> float_ids{17, 19};
1538 std::vector<uint32_t> signed_int_ids{23, 25, 31, 33};
1539
1540 ASSERT_TRUE(maybe_bool_id == 9 || maybe_bool_id == 11);
1541 ASSERT_TRUE(std::find(signed_int_ids.begin(), signed_int_ids.end(),
1542 maybe_signed_int_id) != signed_int_ids.end());
1543
1544 // There is a unsigned int typed zero constant and its id is 31.
1545 ASSERT_EQ(31, maybe_unsigned_int_id);
1546
1547 // There is no zero float constant.
1548 ASSERT_TRUE(std::find(float_ids.begin(), float_ids.end(), maybe_float_id) ==
1549 float_ids.end());
1550 }
1551
TEST(FuzzerutilTest,TypesAreCompatible)1552 TEST(FuzzerutilTest, TypesAreCompatible) {
1553 const std::string shader = R"(
1554 OpCapability Shader
1555 %1 = OpExtInstImport "GLSL.std.450"
1556 OpMemoryModel Logical GLSL450
1557 OpEntryPoint Fragment %4 "main"
1558 OpExecutionMode %4 OriginUpperLeft
1559 OpSource ESSL 320
1560 %2 = OpTypeVoid
1561 %3 = OpTypeFunction %2
1562 %6 = OpTypeInt 32 1
1563 %9 = OpTypeInt 32 0
1564 %8 = OpTypeStruct %6
1565 %10 = OpTypePointer StorageBuffer %8
1566 %11 = OpVariable %10 StorageBuffer
1567 %86 = OpTypeStruct %9
1568 %87 = OpTypePointer Workgroup %86
1569 %88 = OpVariable %87 Workgroup
1570 %89 = OpTypePointer Workgroup %9
1571 %19 = OpConstant %9 0
1572 %18 = OpConstant %9 1
1573 %12 = OpConstant %6 0
1574 %13 = OpTypePointer StorageBuffer %6
1575 %15 = OpConstant %6 2
1576 %16 = OpConstant %6 7
1577 %20 = OpConstant %9 64
1578 %4 = OpFunction %2 None %3
1579 %5 = OpLabel
1580 %14 = OpAccessChain %13 %11 %12
1581 %90 = OpAccessChain %89 %88 %19
1582 %21 = OpAtomicLoad %6 %14 %15 %20
1583 %22 = OpAtomicExchange %6 %14 %15 %20 %16
1584 %23 = OpAtomicCompareExchange %6 %14 %15 %20 %12 %16 %15
1585 %24 = OpAtomicIIncrement %6 %14 %15 %20
1586 %25 = OpAtomicIDecrement %6 %14 %15 %20
1587 %26 = OpAtomicIAdd %6 %14 %15 %20 %16
1588 %27 = OpAtomicISub %6 %14 %15 %20 %16
1589 %28 = OpAtomicSMin %6 %14 %15 %20 %16
1590 %29 = OpAtomicUMin %9 %90 %15 %20 %18
1591 %30 = OpAtomicSMax %6 %14 %15 %20 %15
1592 %31 = OpAtomicUMax %9 %90 %15 %20 %18
1593 %32 = OpAtomicAnd %6 %14 %15 %20 %16
1594 %33 = OpAtomicOr %6 %14 %15 %20 %16
1595 %34 = OpAtomicXor %6 %14 %15 %20 %16
1596 OpAtomicStore %14 %15 %20 %16
1597 OpReturn
1598 OpFunctionEnd
1599 )";
1600
1601 const auto env = SPV_ENV_UNIVERSAL_1_3;
1602 const auto consumer = nullptr;
1603 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
1604 spvtools::ValidatorOptions validator_options;
1605 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1606 kConsoleMessageConsumer));
1607
1608 const uint32_t int_type = 6; // The id of OpTypeInt 32 1
1609 const uint32_t uint_type = 9; // The id of OpTypeInt 32 0
1610
1611 // OpAtomicLoad
1612 #ifndef NDEBUG
1613 ASSERT_DEATH(
1614 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicLoad, 0,
1615 int_type, uint_type),
1616 "Signedness check should not occur on a pointer operand.");
1617 #endif
1618 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1619 context.get(), spv::Op::OpAtomicLoad, 1, int_type, uint_type));
1620 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1621 context.get(), spv::Op::OpAtomicLoad, 2, int_type, uint_type));
1622
1623 // OpAtomicExchange
1624 #ifndef NDEBUG
1625 ASSERT_DEATH(
1626 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicExchange,
1627 0, int_type, uint_type),
1628 "Signedness check should not occur on a pointer operand.");
1629 #endif
1630 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1631 context.get(), spv::Op::OpAtomicExchange, 1, int_type, uint_type));
1632 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1633 context.get(), spv::Op::OpAtomicExchange, 2, int_type, uint_type));
1634 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1635 context.get(), spv::Op::OpAtomicExchange, 3, int_type, uint_type));
1636
1637 // OpAtomicStore
1638 #ifndef NDEBUG
1639 ASSERT_DEATH(
1640 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0,
1641 int_type, uint_type),
1642 "Signedness check should not occur on a pointer operand.");
1643 #endif
1644 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1645 context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type));
1646 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1647 context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type));
1648 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1649 context.get(), spv::Op::OpAtomicStore, 3, int_type, uint_type));
1650
1651 // OpAtomicCompareExchange
1652 #ifndef NDEBUG
1653 ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(),
1654 spv::Op::OpAtomicCompareExchange,
1655 0, int_type, uint_type),
1656 "Signedness check should not occur on a pointer operand.");
1657 #endif
1658 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1659 context.get(), spv::Op::OpAtomicCompareExchange, 1, int_type, uint_type));
1660 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1661 context.get(), spv::Op::OpAtomicCompareExchange, 2, int_type, uint_type));
1662 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1663 context.get(), spv::Op::OpAtomicCompareExchange, 3, int_type, uint_type));
1664 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1665 context.get(), spv::Op::OpAtomicCompareExchange, 4, int_type, uint_type));
1666
1667 // OpAtomicIIncrement
1668 #ifndef NDEBUG
1669 ASSERT_DEATH(
1670 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIIncrement,
1671 0, int_type, uint_type),
1672 "Signedness check should not occur on a pointer operand.");
1673 #endif
1674 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1675 context.get(), spv::Op::OpAtomicIIncrement, 1, int_type, uint_type));
1676 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1677 context.get(), spv::Op::OpAtomicIIncrement, 2, int_type, uint_type));
1678
1679 // OpAtomicIDecrement
1680 #ifndef NDEBUG
1681 ASSERT_DEATH(
1682 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0,
1683 int_type, uint_type),
1684 "Signedness check should not occur on a pointer operand.");
1685 #endif
1686 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1687 context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type));
1688 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1689 context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type));
1690
1691 // OpAtomicIAdd
1692 #ifndef NDEBUG
1693 ASSERT_DEATH(
1694 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIAdd, 0,
1695 int_type, uint_type),
1696 "Signedness check should not occur on a pointer operand.");
1697 #endif
1698 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1699 context.get(), spv::Op::OpAtomicIAdd, 1, int_type, uint_type));
1700 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1701 context.get(), spv::Op::OpAtomicIAdd, 2, int_type, uint_type));
1702 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1703 context.get(), spv::Op::OpAtomicIAdd, 3, int_type, uint_type));
1704
1705 // OpAtomicISub
1706 #ifndef NDEBUG
1707 ASSERT_DEATH(
1708 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicISub, 0,
1709 int_type, uint_type),
1710 "Signedness check should not occur on a pointer operand.");
1711 #endif
1712 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1713 context.get(), spv::Op::OpAtomicISub, 1, int_type, uint_type));
1714 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1715 context.get(), spv::Op::OpAtomicISub, 2, int_type, uint_type));
1716 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1717 context.get(), spv::Op::OpAtomicISub, 3, int_type, uint_type));
1718
1719 // OpAtomicSMin
1720 #ifndef NDEBUG
1721 ASSERT_DEATH(
1722 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMin, 0,
1723 int_type, uint_type),
1724 "Signedness check should not occur on a pointer operand.");
1725 #endif
1726 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1727 context.get(), spv::Op::OpAtomicSMin, 1, int_type, uint_type));
1728 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1729 context.get(), spv::Op::OpAtomicSMin, 2, int_type, uint_type));
1730 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1731 context.get(), spv::Op::OpAtomicSMin, 3, int_type, uint_type));
1732
1733 // OpAtomicUMin
1734 #ifndef NDEBUG
1735 ASSERT_DEATH(
1736 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMin, 0,
1737 int_type, uint_type),
1738 "Signedness check should not occur on a pointer operand.");
1739 #endif
1740 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1741 context.get(), spv::Op::OpAtomicUMin, 1, int_type, uint_type));
1742 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1743 context.get(), spv::Op::OpAtomicUMin, 2, int_type, uint_type));
1744 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1745 context.get(), spv::Op::OpAtomicUMin, 3, int_type, uint_type));
1746
1747 // OpAtomicSMax
1748 #ifndef NDEBUG
1749 ASSERT_DEATH(
1750 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMax, 0,
1751 int_type, uint_type),
1752 "Signedness check should not occur on a pointer operand.");
1753 #endif
1754 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1755 context.get(), spv::Op::OpAtomicSMax, 1, int_type, uint_type));
1756 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1757 context.get(), spv::Op::OpAtomicSMax, 2, int_type, uint_type));
1758 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1759 context.get(), spv::Op::OpAtomicSMax, 3, int_type, uint_type));
1760
1761 // OpAtomicUMax
1762 #ifndef NDEBUG
1763 ASSERT_DEATH(
1764 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMax, 0,
1765 int_type, uint_type),
1766 "Signedness check should not occur on a pointer operand.");
1767 #endif
1768 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1769 context.get(), spv::Op::OpAtomicUMax, 1, int_type, uint_type));
1770 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1771 context.get(), spv::Op::OpAtomicUMax, 2, int_type, uint_type));
1772 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1773 context.get(), spv::Op::OpAtomicUMax, 3, int_type, uint_type));
1774
1775 // OpAtomicAnd
1776 #ifndef NDEBUG
1777 ASSERT_DEATH(fuzzerutil::TypesAreCompatible(
1778 context.get(), spv::Op::OpAtomicAnd, 0, int_type, uint_type),
1779 "Signedness check should not occur on a pointer operand.");
1780 #endif
1781 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1782 context.get(), spv::Op::OpAtomicAnd, 1, int_type, uint_type));
1783 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1784 context.get(), spv::Op::OpAtomicAnd, 2, int_type, uint_type));
1785 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1786 context.get(), spv::Op::OpAtomicAnd, 3, int_type, uint_type));
1787
1788 // OpAtomicOr
1789 #ifndef NDEBUG
1790 ASSERT_DEATH(fuzzerutil::TypesAreCompatible(
1791 context.get(), spv::Op::OpAtomicOr, 0, int_type, uint_type),
1792 "Signedness check should not occur on a pointer operand.");
1793 #endif
1794 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr,
1795 1, int_type, uint_type));
1796 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr,
1797 2, int_type, uint_type));
1798 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1799 context.get(), spv::Op::OpAtomicOr, 3, int_type, uint_type));
1800
1801 // OpAtomicXor
1802 #ifndef NDEBUG
1803 ASSERT_DEATH(fuzzerutil::TypesAreCompatible(
1804 context.get(), spv::Op::OpAtomicXor, 0, int_type, uint_type),
1805 "Signedness check should not occur on a pointer operand.");
1806 #endif
1807 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1808 context.get(), spv::Op::OpAtomicXor, 1, int_type, uint_type));
1809 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
1810 context.get(), spv::Op::OpAtomicXor, 2, int_type, uint_type));
1811 ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
1812 context.get(), spv::Op::OpAtomicXor, 3, int_type, uint_type));
1813 }
1814
1815 } // namespace
1816 } // namespace fuzz
1817 } // namespace spvtools
1818