1 // Copyright (c) 2019 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/transformation_add_constant_composite.h"
16
17 #include "gtest/gtest.h"
18 #include "source/fuzz/fuzzer_util.h"
19 #include "test/fuzz/fuzz_test_util.h"
20
21 namespace spvtools {
22 namespace fuzz {
23 namespace {
24
TEST(TransformationAddConstantCompositeTest,BasicTest)25 TEST(TransformationAddConstantCompositeTest, BasicTest) {
26 std::string shader = R"(
27 OpCapability Shader
28 %1 = OpExtInstImport "GLSL.std.450"
29 OpMemoryModel Logical GLSL450
30 OpEntryPoint Fragment %4 "main"
31 OpExecutionMode %4 OriginUpperLeft
32 OpSource ESSL 310
33 %2 = OpTypeVoid
34 %3 = OpTypeFunction %2
35 %6 = OpTypeFloat 32
36 %7 = OpTypeVector %6 2
37 %8 = OpTypeMatrix %7 3
38 %11 = OpConstant %6 0
39 %12 = OpConstant %6 1
40 %14 = OpConstant %6 2
41 %15 = OpConstant %6 3
42 %17 = OpConstant %6 4
43 %18 = OpConstant %6 5
44 %21 = OpTypeInt 32 1
45 %22 = OpTypeInt 32 0
46 %23 = OpConstant %22 3
47 %24 = OpTypeArray %21 %23
48 %25 = OpTypeBool
49 %26 = OpTypeStruct %24 %25
50 %29 = OpConstant %21 1
51 %30 = OpConstant %21 2
52 %31 = OpConstant %21 3
53 %33 = OpConstantFalse %25
54 %35 = OpTypeVector %6 3
55 %38 = OpConstant %6 6
56 %39 = OpConstant %6 7
57 %40 = OpConstant %6 8
58 %4 = OpFunction %2 None %3
59 %5 = OpLabel
60 OpReturn
61 OpFunctionEnd
62 )";
63
64 const auto env = SPV_ENV_UNIVERSAL_1_4;
65 const auto consumer = nullptr;
66 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
67 spvtools::ValidatorOptions validator_options;
68 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
69 kConsoleMessageConsumer));
70 TransformationContext transformation_context(
71 MakeUnique<FactManager>(context.get()), validator_options);
72 // Too few ids
73 ASSERT_FALSE(TransformationAddConstantComposite(103, 8, {100, 101}, false)
74 .IsApplicable(context.get(), transformation_context));
75 // Too many ids
76 ASSERT_FALSE(TransformationAddConstantComposite(101, 7, {14, 15, 14}, false)
77 .IsApplicable(context.get(), transformation_context));
78 // Id already in use
79 ASSERT_FALSE(TransformationAddConstantComposite(40, 7, {11, 12}, false)
80 .IsApplicable(context.get(), transformation_context));
81 // %39 is not a type
82 ASSERT_FALSE(TransformationAddConstantComposite(100, 39, {11, 12}, false)
83 .IsApplicable(context.get(), transformation_context));
84
85 TransformationAddConstantComposite transformations[] = {
86 // %100 = OpConstantComposite %7 %11 %12
87 TransformationAddConstantComposite(100, 7, {11, 12}, false),
88
89 // %101 = OpConstantComposite %7 %14 %15
90 TransformationAddConstantComposite(101, 7, {14, 15}, false),
91
92 // %102 = OpConstantComposite %7 %17 %18
93 TransformationAddConstantComposite(102, 7, {17, 18}, false),
94
95 // %103 = OpConstantComposite %8 %100 %101 %102
96 TransformationAddConstantComposite(103, 8, {100, 101, 102}, false),
97
98 // %104 = OpConstantComposite %24 %29 %30 %31
99 TransformationAddConstantComposite(104, 24, {29, 30, 31}, false),
100
101 // %105 = OpConstantComposite %26 %104 %33
102 TransformationAddConstantComposite(105, 26, {104, 33}, false),
103
104 // %106 = OpConstantComposite %35 %38 %39 %40
105 TransformationAddConstantComposite(106, 35, {38, 39, 40}, false),
106
107 // Same constants but with an irrelevant fact applied.
108
109 // %107 = OpConstantComposite %7 %11 %12
110 TransformationAddConstantComposite(107, 7, {11, 12}, true),
111
112 // %108 = OpConstantComposite %7 %14 %15
113 TransformationAddConstantComposite(108, 7, {14, 15}, true),
114
115 // %109 = OpConstantComposite %7 %17 %18
116 TransformationAddConstantComposite(109, 7, {17, 18}, true),
117
118 // %110 = OpConstantComposite %8 %100 %101 %102
119 TransformationAddConstantComposite(110, 8, {100, 101, 102}, true),
120
121 // %111 = OpConstantComposite %24 %29 %30 %31
122 TransformationAddConstantComposite(111, 24, {29, 30, 31}, true),
123
124 // %112 = OpConstantComposite %26 %104 %33
125 TransformationAddConstantComposite(112, 26, {104, 33}, true),
126
127 // %113 = OpConstantComposite %35 %38 %39 %40
128 TransformationAddConstantComposite(113, 35, {38, 39, 40}, true)};
129
130 for (auto& transformation : transformations) {
131 ASSERT_TRUE(
132 transformation.IsApplicable(context.get(), transformation_context));
133 ApplyAndCheckFreshIds(transformation, context.get(),
134 &transformation_context);
135 }
136 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
137 kConsoleMessageConsumer));
138
139 for (uint32_t id = 100; id <= 106; ++id) {
140 ASSERT_FALSE(transformation_context.GetFactManager()->IdIsIrrelevant(id));
141 }
142
143 for (uint32_t id = 107; id <= 113; ++id) {
144 ASSERT_TRUE(transformation_context.GetFactManager()->IdIsIrrelevant(id));
145 }
146
147 std::string after_transformation = R"(
148 OpCapability Shader
149 %1 = OpExtInstImport "GLSL.std.450"
150 OpMemoryModel Logical GLSL450
151 OpEntryPoint Fragment %4 "main"
152 OpExecutionMode %4 OriginUpperLeft
153 OpSource ESSL 310
154 %2 = OpTypeVoid
155 %3 = OpTypeFunction %2
156 %6 = OpTypeFloat 32
157 %7 = OpTypeVector %6 2
158 %8 = OpTypeMatrix %7 3
159 %11 = OpConstant %6 0
160 %12 = OpConstant %6 1
161 %14 = OpConstant %6 2
162 %15 = OpConstant %6 3
163 %17 = OpConstant %6 4
164 %18 = OpConstant %6 5
165 %21 = OpTypeInt 32 1
166 %22 = OpTypeInt 32 0
167 %23 = OpConstant %22 3
168 %24 = OpTypeArray %21 %23
169 %25 = OpTypeBool
170 %26 = OpTypeStruct %24 %25
171 %29 = OpConstant %21 1
172 %30 = OpConstant %21 2
173 %31 = OpConstant %21 3
174 %33 = OpConstantFalse %25
175 %35 = OpTypeVector %6 3
176 %38 = OpConstant %6 6
177 %39 = OpConstant %6 7
178 %40 = OpConstant %6 8
179 %100 = OpConstantComposite %7 %11 %12
180 %101 = OpConstantComposite %7 %14 %15
181 %102 = OpConstantComposite %7 %17 %18
182 %103 = OpConstantComposite %8 %100 %101 %102
183 %104 = OpConstantComposite %24 %29 %30 %31
184 %105 = OpConstantComposite %26 %104 %33
185 %106 = OpConstantComposite %35 %38 %39 %40
186 %107 = OpConstantComposite %7 %11 %12
187 %108 = OpConstantComposite %7 %14 %15
188 %109 = OpConstantComposite %7 %17 %18
189 %110 = OpConstantComposite %8 %100 %101 %102
190 %111 = OpConstantComposite %24 %29 %30 %31
191 %112 = OpConstantComposite %26 %104 %33
192 %113 = OpConstantComposite %35 %38 %39 %40
193 %4 = OpFunction %2 None %3
194 %5 = OpLabel
195 OpReturn
196 OpFunctionEnd
197 )";
198 ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
199 }
200
TEST(TransformationAddConstantCompositeTest,DisallowBufferBlockDecoration)201 TEST(TransformationAddConstantCompositeTest, DisallowBufferBlockDecoration) {
202 std::string shader = R"(
203 OpCapability Shader
204 %1 = OpExtInstImport "GLSL.std.450"
205 OpMemoryModel Logical GLSL450
206 OpEntryPoint GLCompute %4 "main"
207 OpExecutionMode %4 LocalSize 1 1 1
208 OpSource ESSL 320
209 OpName %4 "main"
210 OpName %7 "buf"
211 OpMemberName %7 0 "a"
212 OpMemberName %7 1 "b"
213 OpName %9 ""
214 OpMemberDecorate %7 0 Offset 0
215 OpMemberDecorate %7 1 Offset 4
216 OpDecorate %7 BufferBlock
217 OpDecorate %9 DescriptorSet 0
218 OpDecorate %9 Binding 0
219 %2 = OpTypeVoid
220 %3 = OpTypeFunction %2
221 %6 = OpTypeInt 32 1
222 %10 = OpConstant %6 42
223 %7 = OpTypeStruct %6 %6
224 %8 = OpTypePointer Uniform %7
225 %9 = OpVariable %8 Uniform
226 %4 = OpFunction %2 None %3
227 %5 = OpLabel
228 OpReturn
229 OpFunctionEnd
230 )";
231
232 const auto env = SPV_ENV_UNIVERSAL_1_0;
233 const auto consumer = nullptr;
234 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
235 spvtools::ValidatorOptions validator_options;
236 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
237 kConsoleMessageConsumer));
238 TransformationContext transformation_context(
239 MakeUnique<FactManager>(context.get()), validator_options);
240 ASSERT_FALSE(TransformationAddConstantComposite(100, 7, {10, 10}, false)
241 .IsApplicable(context.get(), transformation_context));
242 }
243
TEST(TransformationAddConstantCompositeTest,DisallowBlockDecoration)244 TEST(TransformationAddConstantCompositeTest, DisallowBlockDecoration) {
245 std::string shader = R"(
246 OpCapability Shader
247 %1 = OpExtInstImport "GLSL.std.450"
248 OpMemoryModel Logical GLSL450
249 OpEntryPoint GLCompute %4 "main" %9
250 OpExecutionMode %4 LocalSize 1 1 1
251 OpSource ESSL 320
252 OpName %4 "main"
253 OpName %7 "buf"
254 OpMemberName %7 0 "a"
255 OpMemberName %7 1 "b"
256 OpName %9 ""
257 OpMemberDecorate %7 0 Offset 0
258 OpMemberDecorate %7 1 Offset 4
259 OpDecorate %7 Block
260 OpDecorate %9 DescriptorSet 0
261 OpDecorate %9 Binding 0
262 %2 = OpTypeVoid
263 %3 = OpTypeFunction %2
264 %6 = OpTypeInt 32 1
265 %10 = OpConstant %6 42
266 %7 = OpTypeStruct %6 %6
267 %8 = OpTypePointer StorageBuffer %7
268 %9 = OpVariable %8 StorageBuffer
269 %4 = OpFunction %2 None %3
270 %5 = OpLabel
271 OpReturn
272 OpFunctionEnd
273 )";
274
275 const auto env = SPV_ENV_UNIVERSAL_1_5;
276 const auto consumer = nullptr;
277 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
278 spvtools::ValidatorOptions validator_options;
279 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
280 kConsoleMessageConsumer));
281 TransformationContext transformation_context(
282 MakeUnique<FactManager>(context.get()), validator_options);
283 ASSERT_FALSE(TransformationAddConstantComposite(100, 7, {10, 10}, false)
284 .IsApplicable(context.get(), transformation_context));
285 }
286
287 } // namespace
288 } // namespace fuzz
289 } // namespace spvtools
290