• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2020 André Perez Maselco
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_expand_vector_reduction.h"
16 
17 #include "gtest/gtest.h"
18 #include "source/fuzz/fuzzer_util.h"
19 #include "source/fuzz/instruction_descriptor.h"
20 #include "test/fuzz/fuzz_test_util.h"
21 
22 namespace spvtools {
23 namespace fuzz {
24 namespace {
25 
TEST(TransformationExpandVectorReductionTest,IsApplicable)26 TEST(TransformationExpandVectorReductionTest, IsApplicable) {
27   std::string reference_shader = R"(
28                OpCapability Shader
29           %1 = OpExtInstImport "GLSL.std.450"
30                OpMemoryModel Logical GLSL450
31                OpEntryPoint Vertex %9 "main"
32 
33           ; Types
34           %2 = OpTypeBool
35           %3 = OpTypeVector %2 2
36           %4 = OpTypeVoid
37           %5 = OpTypeFunction %4
38 
39           ; Constants
40           %6 = OpConstantTrue %2
41           %7 = OpConstantFalse %2
42           %8 = OpConstantComposite %3 %6 %7
43 
44           ; main function
45           %9 = OpFunction %4 None %5
46          %10 = OpLabel
47          %11 = OpAny %2 %8
48          %12 = OpAll %2 %8
49                OpReturn
50                OpFunctionEnd
51   )";
52 
53   const auto env = SPV_ENV_UNIVERSAL_1_5;
54   const auto consumer = nullptr;
55   const auto context =
56       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
57 
58   spvtools::ValidatorOptions validator_options;
59   TransformationContext transformation_context(
60       MakeUnique<FactManager>(context.get()), validator_options);
61   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
62                                                kConsoleMessageConsumer));
63 
64   // Tests undefined instruction.
65   auto transformation = TransformationExpandVectorReduction(13, {14, 15, 16});
66   ASSERT_FALSE(
67       transformation.IsApplicable(context.get(), transformation_context));
68 
69   // Tests non OpAny or OpAll instruction.
70   transformation = TransformationExpandVectorReduction(10, {13, 14, 15});
71   ASSERT_FALSE(
72       transformation.IsApplicable(context.get(), transformation_context));
73 
74   // Tests the number of fresh ids being different than the necessary.
75   transformation = TransformationExpandVectorReduction(11, {13, 14});
76   ASSERT_FALSE(
77       transformation.IsApplicable(context.get(), transformation_context));
78 
79   transformation = TransformationExpandVectorReduction(12, {13, 14, 15, 16});
80   ASSERT_FALSE(
81       transformation.IsApplicable(context.get(), transformation_context));
82 
83   // Tests non-fresh ids.
84   transformation = TransformationExpandVectorReduction(11, {12, 13, 14});
85   ASSERT_FALSE(
86       transformation.IsApplicable(context.get(), transformation_context));
87 
88   // Tests duplicated fresh ids.
89   transformation = TransformationExpandVectorReduction(11, {13, 13, 14});
90   ASSERT_FALSE(
91       transformation.IsApplicable(context.get(), transformation_context));
92 
93   // Tests applicable transformations.
94   transformation = TransformationExpandVectorReduction(11, {13, 14, 15});
95   ASSERT_TRUE(
96       transformation.IsApplicable(context.get(), transformation_context));
97 
98   transformation = TransformationExpandVectorReduction(12, {13, 14, 15});
99   ASSERT_TRUE(
100       transformation.IsApplicable(context.get(), transformation_context));
101 }
102 
TEST(TransformationExpandVectorReductionTest,Apply)103 TEST(TransformationExpandVectorReductionTest, Apply) {
104   std::string reference_shader = R"(
105                OpCapability Shader
106           %1 = OpExtInstImport "GLSL.std.450"
107                OpMemoryModel Logical GLSL450
108                OpEntryPoint Vertex %13 "main"
109 
110           ; Types
111           %2 = OpTypeBool
112           %3 = OpTypeVector %2 2
113           %4 = OpTypeVector %2 3
114           %5 = OpTypeVector %2 4
115           %6 = OpTypeVoid
116           %7 = OpTypeFunction %6
117 
118           ; Constants
119           %8 = OpConstantTrue %2
120           %9 = OpConstantFalse %2
121          %10 = OpConstantComposite %3 %8 %9
122          %11 = OpConstantComposite %4 %8 %9 %8
123          %12 = OpConstantComposite %5 %8 %9 %8 %9
124 
125          ; main function
126          %13 = OpFunction %6 None %7
127          %14 = OpLabel
128 
129          ; OpAny for 2-dimensional vector
130          %15 = OpAny %2 %10
131 
132          ; OpAny for 3-dimensional vector
133          %16 = OpAny %2 %11
134 
135          ; OpAny for 4-dimensional vector
136          %17 = OpAny %2 %12
137 
138          ; OpAll for 2-dimensional vector
139          %18 = OpAll %2 %10
140 
141          ; OpAll for 3-dimensional vector
142          %19 = OpAll %2 %11
143 
144          ; OpAll for 4-dimensional vector
145          %20 = OpAll %2 %12
146                OpReturn
147                OpFunctionEnd
148   )";
149 
150   const auto env = SPV_ENV_UNIVERSAL_1_5;
151   const auto consumer = nullptr;
152   const auto context =
153       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
154 
155   spvtools::ValidatorOptions validator_options;
156   TransformationContext transformation_context(
157       MakeUnique<FactManager>(context.get()), validator_options);
158   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
159                                                kConsoleMessageConsumer));
160 
161   // Adds OpAny synonym for 2-dimensional vector.
162   auto transformation = TransformationExpandVectorReduction(15, {21, 22, 23});
163   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
164   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
165       MakeDataDescriptor(23, {}), MakeDataDescriptor(15, {})));
166 
167   // Adds OpAny synonym for 3-dimensional vector.
168   transformation =
169       TransformationExpandVectorReduction(16, {24, 25, 26, 27, 28});
170   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
171   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
172       MakeDataDescriptor(28, {}), MakeDataDescriptor(16, {})));
173 
174   // Adds OpAny synonym for 4-dimensional vector.
175   transformation =
176       TransformationExpandVectorReduction(17, {29, 30, 31, 32, 33, 34, 35});
177   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
178   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
179       MakeDataDescriptor(35, {}), MakeDataDescriptor(17, {})));
180 
181   // Adds OpAll synonym for 2-dimensional vector.
182   transformation = TransformationExpandVectorReduction(18, {36, 37, 38});
183   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
184   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
185       MakeDataDescriptor(38, {}), MakeDataDescriptor(18, {})));
186 
187   // Adds OpAll synonym for 3-dimensional vector.
188   transformation =
189       TransformationExpandVectorReduction(19, {39, 40, 41, 42, 43});
190   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
191   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
192       MakeDataDescriptor(43, {}), MakeDataDescriptor(19, {})));
193 
194   // Adds OpAll synonym for 4-dimensional vector.
195   transformation =
196       TransformationExpandVectorReduction(20, {44, 45, 46, 47, 48, 49, 50});
197   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
198   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
199       MakeDataDescriptor(50, {}), MakeDataDescriptor(20, {})));
200 
201   std::string variant_shader = R"(
202                OpCapability Shader
203           %1 = OpExtInstImport "GLSL.std.450"
204                OpMemoryModel Logical GLSL450
205                OpEntryPoint Vertex %13 "main"
206 
207           ; Types
208           %2 = OpTypeBool
209           %3 = OpTypeVector %2 2
210           %4 = OpTypeVector %2 3
211           %5 = OpTypeVector %2 4
212           %6 = OpTypeVoid
213           %7 = OpTypeFunction %6
214 
215           ; Constants
216           %8 = OpConstantTrue %2
217           %9 = OpConstantFalse %2
218          %10 = OpConstantComposite %3 %8 %9
219          %11 = OpConstantComposite %4 %8 %9 %8
220          %12 = OpConstantComposite %5 %8 %9 %8 %9
221 
222          ; main function
223          %13 = OpFunction %6 None %7
224          %14 = OpLabel
225 
226          ; Add OpAny synonym for 2-dimensional vector
227          %21 = OpCompositeExtract %2 %10 0
228          %22 = OpCompositeExtract %2 %10 1
229          %23 = OpLogicalOr %2 %21 %22
230          %15 = OpAny %2 %10
231 
232          ; Add OpAny synonym for 3-dimensional vector
233          %24 = OpCompositeExtract %2 %11 0
234          %25 = OpCompositeExtract %2 %11 1
235          %26 = OpCompositeExtract %2 %11 2
236          %27 = OpLogicalOr %2 %24 %25
237          %28 = OpLogicalOr %2 %26 %27
238          %16 = OpAny %2 %11
239 
240          ; Add OpAny synonym for 4-dimensional vector
241          %29 = OpCompositeExtract %2 %12 0
242          %30 = OpCompositeExtract %2 %12 1
243          %31 = OpCompositeExtract %2 %12 2
244          %32 = OpCompositeExtract %2 %12 3
245          %33 = OpLogicalOr %2 %29 %30
246          %34 = OpLogicalOr %2 %31 %33
247          %35 = OpLogicalOr %2 %32 %34
248          %17 = OpAny %2 %12
249 
250          ; Add OpAll synonym for 2-dimensional vector
251          %36 = OpCompositeExtract %2 %10 0
252          %37 = OpCompositeExtract %2 %10 1
253          %38 = OpLogicalAnd %2 %36 %37
254          %18 = OpAll %2 %10
255 
256          ; Add OpAll synonym for 3-dimensional vector
257          %39 = OpCompositeExtract %2 %11 0
258          %40 = OpCompositeExtract %2 %11 1
259          %41 = OpCompositeExtract %2 %11 2
260          %42 = OpLogicalAnd %2 %39 %40
261          %43 = OpLogicalAnd %2 %41 %42
262          %19 = OpAll %2 %11
263 
264          ; Add OpAll synonym for 4-dimensional vector
265          %44 = OpCompositeExtract %2 %12 0
266          %45 = OpCompositeExtract %2 %12 1
267          %46 = OpCompositeExtract %2 %12 2
268          %47 = OpCompositeExtract %2 %12 3
269          %48 = OpLogicalAnd %2 %44 %45
270          %49 = OpLogicalAnd %2 %46 %48
271          %50 = OpLogicalAnd %2 %47 %49
272          %20 = OpAll %2 %12
273                OpReturn
274                OpFunctionEnd
275   )";
276 
277   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
278                                                kConsoleMessageConsumer));
279   ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
280 }
281 
282 }  // namespace
283 }  // namespace fuzz
284 }  // namespace spvtools
285