• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_set_function_control.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(TransformationSetFunctionControlTest,VariousScenarios)25 TEST(TransformationSetFunctionControlTest, VariousScenarios) {
26   // This is a simple transformation; this test captures the important things
27   // to check for.
28 
29   std::string shader = R"(
30                OpCapability Shader
31           %1 = OpExtInstImport "GLSL.std.450"
32                OpMemoryModel Logical GLSL450
33                OpEntryPoint Fragment %4 "main" %54
34                OpExecutionMode %4 OriginUpperLeft
35                OpSource ESSL 310
36                OpName %4 "main"
37                OpName %11 "foo(i1;i1;"
38                OpName %9 "a"
39                OpName %10 "b"
40                OpName %13 "bar("
41                OpName %17 "baz(i1;"
42                OpName %16 "x"
43                OpName %21 "boo(i1;i1;"
44                OpName %19 "a"
45                OpName %20 "b"
46                OpName %29 "g"
47                OpName %42 "param"
48                OpName %44 "param"
49                OpName %45 "param"
50                OpName %48 "param"
51                OpName %49 "param"
52                OpName %54 "color"
53                OpDecorate %54 Location 0
54           %2 = OpTypeVoid
55           %3 = OpTypeFunction %2
56           %6 = OpTypeInt 32 1
57           %7 = OpTypePointer Function %6
58           %8 = OpTypeFunction %6 %7 %7
59          %15 = OpTypeFunction %6 %7
60          %28 = OpTypePointer Private %6
61          %29 = OpVariable %28 Private
62          %30 = OpConstant %6 2
63          %31 = OpConstant %6 5
64          %51 = OpTypeFloat 32
65          %52 = OpTypeVector %51 4
66          %53 = OpTypePointer Output %52
67          %54 = OpVariable %53 Output
68           %4 = OpFunction %2 None %3
69           %5 = OpLabel
70          %42 = OpVariable %7 Function
71          %44 = OpVariable %7 Function
72          %45 = OpVariable %7 Function
73          %48 = OpVariable %7 Function
74          %49 = OpVariable %7 Function
75          %41 = OpFunctionCall %2 %13
76                OpStore %42 %30
77          %43 = OpFunctionCall %6 %17 %42
78                OpStore %44 %31
79          %46 = OpLoad %6 %29
80                OpStore %45 %46
81          %47 = OpFunctionCall %6 %21 %44 %45
82                OpStore %48 %43
83                OpStore %49 %47
84          %50 = OpFunctionCall %6 %11 %48 %49
85                OpReturn
86                OpFunctionEnd
87          %11 = OpFunction %6 Const %8
88           %9 = OpFunctionParameter %7
89          %10 = OpFunctionParameter %7
90          %12 = OpLabel
91          %23 = OpLoad %6 %9
92          %24 = OpLoad %6 %10
93          %25 = OpIAdd %6 %23 %24
94                OpReturnValue %25
95                OpFunctionEnd
96          %13 = OpFunction %2 Inline %3
97          %14 = OpLabel
98                OpStore %29 %30
99                OpReturn
100                OpFunctionEnd
101          %17 = OpFunction %6 Pure|DontInline %15
102          %16 = OpFunctionParameter %7
103          %18 = OpLabel
104          %32 = OpLoad %6 %16
105          %33 = OpIAdd %6 %31 %32
106                OpReturnValue %33
107                OpFunctionEnd
108          %21 = OpFunction %6 DontInline %8
109          %19 = OpFunctionParameter %7
110          %20 = OpFunctionParameter %7
111          %22 = OpLabel
112          %36 = OpLoad %6 %19
113          %37 = OpLoad %6 %20
114          %38 = OpIMul %6 %36 %37
115                OpReturnValue %38
116                OpFunctionEnd
117   )";
118 
119   const auto env = SPV_ENV_UNIVERSAL_1_3;
120   const auto consumer = nullptr;
121   const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
122 
123   spvtools::ValidatorOptions validator_options;
124   TransformationContext transformation_context(
125       MakeUnique<FactManager>(context.get()), validator_options);
126   // %36 is not a function
127   ASSERT_FALSE(TransformationSetFunctionControl(36, SpvFunctionControlMaskNone)
128                    .IsApplicable(context.get(), transformation_context));
129   // Cannot add the Pure function control to %4 as it did not already have it
130   ASSERT_FALSE(TransformationSetFunctionControl(4, SpvFunctionControlPureMask)
131                    .IsApplicable(context.get(), transformation_context));
132   // Cannot add the Const function control to %21 as it did not already
133   // have it
134   ASSERT_FALSE(TransformationSetFunctionControl(21, SpvFunctionControlConstMask)
135                    .IsApplicable(context.get(), transformation_context));
136 
137   // Set to None, removing Const
138   TransformationSetFunctionControl transformation1(11,
139                                                    SpvFunctionControlMaskNone);
140   ASSERT_TRUE(
141       transformation1.IsApplicable(context.get(), transformation_context));
142   ApplyAndCheckFreshIds(transformation1, context.get(),
143                         &transformation_context);
144 
145   // Set to Inline; silly to do it on an entry point, but it is allowed
146   TransformationSetFunctionControl transformation2(
147       4, SpvFunctionControlInlineMask);
148   ASSERT_TRUE(
149       transformation2.IsApplicable(context.get(), transformation_context));
150   ApplyAndCheckFreshIds(transformation2, context.get(),
151                         &transformation_context);
152 
153   // Set to Pure, removing DontInline
154   TransformationSetFunctionControl transformation3(17,
155                                                    SpvFunctionControlPureMask);
156   ASSERT_TRUE(
157       transformation3.IsApplicable(context.get(), transformation_context));
158   ApplyAndCheckFreshIds(transformation3, context.get(),
159                         &transformation_context);
160 
161   // Change from Inline to DontInline
162   TransformationSetFunctionControl transformation4(
163       13, SpvFunctionControlDontInlineMask);
164   ASSERT_TRUE(
165       transformation4.IsApplicable(context.get(), transformation_context));
166   ApplyAndCheckFreshIds(transformation4, context.get(),
167                         &transformation_context);
168 
169   std::string after_transformation = R"(
170                OpCapability Shader
171           %1 = OpExtInstImport "GLSL.std.450"
172                OpMemoryModel Logical GLSL450
173                OpEntryPoint Fragment %4 "main" %54
174                OpExecutionMode %4 OriginUpperLeft
175                OpSource ESSL 310
176                OpName %4 "main"
177                OpName %11 "foo(i1;i1;"
178                OpName %9 "a"
179                OpName %10 "b"
180                OpName %13 "bar("
181                OpName %17 "baz(i1;"
182                OpName %16 "x"
183                OpName %21 "boo(i1;i1;"
184                OpName %19 "a"
185                OpName %20 "b"
186                OpName %29 "g"
187                OpName %42 "param"
188                OpName %44 "param"
189                OpName %45 "param"
190                OpName %48 "param"
191                OpName %49 "param"
192                OpName %54 "color"
193                OpDecorate %54 Location 0
194           %2 = OpTypeVoid
195           %3 = OpTypeFunction %2
196           %6 = OpTypeInt 32 1
197           %7 = OpTypePointer Function %6
198           %8 = OpTypeFunction %6 %7 %7
199          %15 = OpTypeFunction %6 %7
200          %28 = OpTypePointer Private %6
201          %29 = OpVariable %28 Private
202          %30 = OpConstant %6 2
203          %31 = OpConstant %6 5
204          %51 = OpTypeFloat 32
205          %52 = OpTypeVector %51 4
206          %53 = OpTypePointer Output %52
207          %54 = OpVariable %53 Output
208           %4 = OpFunction %2 Inline %3
209           %5 = OpLabel
210          %42 = OpVariable %7 Function
211          %44 = OpVariable %7 Function
212          %45 = OpVariable %7 Function
213          %48 = OpVariable %7 Function
214          %49 = OpVariable %7 Function
215          %41 = OpFunctionCall %2 %13
216                OpStore %42 %30
217          %43 = OpFunctionCall %6 %17 %42
218                OpStore %44 %31
219          %46 = OpLoad %6 %29
220                OpStore %45 %46
221          %47 = OpFunctionCall %6 %21 %44 %45
222                OpStore %48 %43
223                OpStore %49 %47
224          %50 = OpFunctionCall %6 %11 %48 %49
225                OpReturn
226                OpFunctionEnd
227          %11 = OpFunction %6 None %8
228           %9 = OpFunctionParameter %7
229          %10 = OpFunctionParameter %7
230          %12 = OpLabel
231          %23 = OpLoad %6 %9
232          %24 = OpLoad %6 %10
233          %25 = OpIAdd %6 %23 %24
234                OpReturnValue %25
235                OpFunctionEnd
236          %13 = OpFunction %2 DontInline %3
237          %14 = OpLabel
238                OpStore %29 %30
239                OpReturn
240                OpFunctionEnd
241          %17 = OpFunction %6 Pure %15
242          %16 = OpFunctionParameter %7
243          %18 = OpLabel
244          %32 = OpLoad %6 %16
245          %33 = OpIAdd %6 %31 %32
246                OpReturnValue %33
247                OpFunctionEnd
248          %21 = OpFunction %6 DontInline %8
249          %19 = OpFunctionParameter %7
250          %20 = OpFunctionParameter %7
251          %22 = OpLabel
252          %36 = OpLoad %6 %19
253          %37 = OpLoad %6 %20
254          %38 = OpIMul %6 %36 %37
255                OpReturnValue %38
256                OpFunctionEnd
257   )";
258   ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
259 }
260 
261 }  // namespace
262 }  // namespace fuzz
263 }  // namespace spvtools
264