1 // Copyright (c) 2020 Google LLC
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 "source/fuzz/fuzzer_pass_construct_composites.h"
16
17 #include "gtest/gtest.h"
18 #include "source/fuzz/fuzzer_util.h"
19 #include "source/fuzz/pseudo_random_generator.h"
20 #include "test/fuzz/fuzz_test_util.h"
21
22 namespace spvtools {
23 namespace fuzz {
24 namespace {
25
TEST(FuzzerPassConstructCompositesTest,IsomorphicStructs)26 TEST(FuzzerPassConstructCompositesTest, IsomorphicStructs) {
27 // This test declares various isomorphic structs, and a struct that is made up
28 // of these isomorphic structs. The pass to construct composites is then
29 // applied several times to check that no issues arise related to using a
30 // value of one struct type when a value of an isomorphic struct type is
31 // required.
32
33 std::string shader = R"(
34 OpCapability Shader
35 %1 = OpExtInstImport "GLSL.std.450"
36 OpMemoryModel Logical GLSL450
37 OpEntryPoint Fragment %4 "main"
38 OpExecutionMode %4 OriginUpperLeft
39 OpSource ESSL 310
40 %2 = OpTypeVoid
41 %3 = OpTypeFunction %2
42 %6 = OpTypeFloat 32
43 %7 = OpConstant %6 0
44 %8 = OpTypeStruct %6 %6 %6
45 %9 = OpTypeStruct %6 %6 %6
46 %10 = OpTypeStruct %6 %6 %6
47 %11 = OpTypeStruct %6 %6 %6
48 %12 = OpTypeStruct %6 %6 %6
49 %13 = OpTypeStruct %8 %9 %10 %11 %12
50 %14 = OpConstantComposite %8 %7 %7 %7
51 %15 = OpConstantComposite %9 %7 %7 %7
52 %16 = OpConstantComposite %10 %7 %7 %7
53 %17 = OpConstantComposite %11 %7 %7 %7
54 %18 = OpConstantComposite %12 %7 %7 %7
55 %4 = OpFunction %2 None %3
56 %5 = OpLabel
57 OpNop
58 OpNop
59 OpNop
60 OpNop
61 OpNop
62 OpNop
63 OpNop
64 OpNop
65 OpNop
66 OpNop
67 OpNop
68 OpNop
69 OpNop
70 OpNop
71 OpNop
72 OpNop
73 OpReturn
74 OpFunctionEnd
75 )";
76
77 const auto env = SPV_ENV_UNIVERSAL_1_3;
78 const auto consumer = nullptr;
79
80 auto prng = MakeUnique<PseudoRandomGenerator>(0);
81
82 for (uint32_t i = 0; i < 10; i++) {
83 const auto context =
84 BuildModule(env, consumer, shader, kFuzzAssembleOption);
85 spvtools::ValidatorOptions validator_options;
86 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
87 context.get(), validator_options, kConsoleMessageConsumer));
88 TransformationContext transformation_context(
89 MakeUnique<FactManager>(context.get()), validator_options);
90 FuzzerContext fuzzer_context(prng.get(), 100);
91 protobufs::TransformationSequence transformation_sequence;
92
93 FuzzerPassConstructComposites fuzzer_pass(
94 context.get(), &transformation_context, &fuzzer_context,
95 &transformation_sequence);
96
97 fuzzer_pass.Apply();
98
99 // We just check that the result is valid.
100 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
101 context.get(), validator_options, kConsoleMessageConsumer));
102 }
103 }
104
TEST(FuzzerPassConstructCompositesTest,IsomorphicArrays)105 TEST(FuzzerPassConstructCompositesTest, IsomorphicArrays) {
106 // This test declares various isomorphic arrays, and a struct that is made up
107 // of these isomorphic arrays. The pass to construct composites is then
108 // applied several times to check that no issues arise related to using a
109 // value of one array type when a value of an isomorphic array type is
110 // required.
111
112 std::string shader = R"(
113 OpCapability Shader
114 %1 = OpExtInstImport "GLSL.std.450"
115 OpMemoryModel Logical GLSL450
116 OpEntryPoint Fragment %4 "main"
117 OpExecutionMode %4 OriginUpperLeft
118 OpSource ESSL 310
119 %2 = OpTypeVoid
120 %3 = OpTypeFunction %2
121 %6 = OpTypeFloat 32
122 %50 = OpTypeInt 32 0
123 %51 = OpConstant %50 3
124 %7 = OpConstant %6 0
125 %8 = OpTypeArray %6 %51
126 %9 = OpTypeArray %6 %51
127 %10 = OpTypeArray %6 %51
128 %11 = OpTypeArray %6 %51
129 %12 = OpTypeArray %6 %51
130 %13 = OpTypeStruct %8 %9 %10 %11 %12
131 %14 = OpConstantComposite %8 %7 %7 %7
132 %15 = OpConstantComposite %9 %7 %7 %7
133 %16 = OpConstantComposite %10 %7 %7 %7
134 %17 = OpConstantComposite %11 %7 %7 %7
135 %18 = OpConstantComposite %12 %7 %7 %7
136 %4 = OpFunction %2 None %3
137 %5 = OpLabel
138 OpNop
139 OpNop
140 OpNop
141 OpNop
142 OpNop
143 OpNop
144 OpNop
145 OpNop
146 OpNop
147 OpNop
148 OpNop
149 OpNop
150 OpNop
151 OpNop
152 OpNop
153 OpNop
154 OpReturn
155 OpFunctionEnd
156 )";
157
158 const auto env = SPV_ENV_UNIVERSAL_1_3;
159 const auto consumer = nullptr;
160
161 auto prng = MakeUnique<PseudoRandomGenerator>(0);
162
163 for (uint32_t i = 0; i < 10; i++) {
164 const auto context =
165 BuildModule(env, consumer, shader, kFuzzAssembleOption);
166 spvtools::ValidatorOptions validator_options;
167 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
168 context.get(), validator_options, kConsoleMessageConsumer));
169 TransformationContext transformation_context(
170 MakeUnique<FactManager>(context.get()), validator_options);
171 FuzzerContext fuzzer_context(prng.get(), 100);
172 protobufs::TransformationSequence transformation_sequence;
173
174 FuzzerPassConstructComposites fuzzer_pass(
175 context.get(), &transformation_context, &fuzzer_context,
176 &transformation_sequence);
177
178 fuzzer_pass.Apply();
179
180 // We just check that the result is valid.
181 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
182 context.get(), validator_options, kConsoleMessageConsumer));
183 }
184 }
185
186 } // namespace
187 } // namespace fuzz
188 } // namespace spvtools
189