• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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