• 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(
128                    36, uint32_t(spv::FunctionControlMask::MaskNone))
129                    .IsApplicable(context.get(), transformation_context));
130   // Cannot add the Pure function control to %4 as it did not already have it
131   ASSERT_FALSE(TransformationSetFunctionControl(
132                    4, uint32_t(spv::FunctionControlMask::Pure))
133                    .IsApplicable(context.get(), transformation_context));
134   // Cannot add the Const function control to %21 as it did not already
135   // have it
136   ASSERT_FALSE(TransformationSetFunctionControl(
137                    21, uint32_t(spv::FunctionControlMask::Const))
138                    .IsApplicable(context.get(), transformation_context));
139 
140   // Set to None, removing Const
141   TransformationSetFunctionControl transformation1(
142       11, uint32_t(spv::FunctionControlMask::MaskNone));
143   ASSERT_TRUE(
144       transformation1.IsApplicable(context.get(), transformation_context));
145   ApplyAndCheckFreshIds(transformation1, context.get(),
146                         &transformation_context);
147 
148   // Set to Inline; silly to do it on an entry point, but it is allowed
149   TransformationSetFunctionControl transformation2(
150       4, uint32_t(spv::FunctionControlMask::Inline));
151   ASSERT_TRUE(
152       transformation2.IsApplicable(context.get(), transformation_context));
153   ApplyAndCheckFreshIds(transformation2, context.get(),
154                         &transformation_context);
155 
156   // Set to Pure, removing DontInline
157   TransformationSetFunctionControl transformation3(
158       17, uint32_t(spv::FunctionControlMask::Pure));
159   ASSERT_TRUE(
160       transformation3.IsApplicable(context.get(), transformation_context));
161   ApplyAndCheckFreshIds(transformation3, context.get(),
162                         &transformation_context);
163 
164   // Change from Inline to DontInline
165   TransformationSetFunctionControl transformation4(
166       13, uint32_t(spv::FunctionControlMask::DontInline));
167   ASSERT_TRUE(
168       transformation4.IsApplicable(context.get(), transformation_context));
169   ApplyAndCheckFreshIds(transformation4, context.get(),
170                         &transformation_context);
171 
172   std::string after_transformation = R"(
173                OpCapability Shader
174           %1 = OpExtInstImport "GLSL.std.450"
175                OpMemoryModel Logical GLSL450
176                OpEntryPoint Fragment %4 "main" %54
177                OpExecutionMode %4 OriginUpperLeft
178                OpSource ESSL 310
179                OpName %4 "main"
180                OpName %11 "foo(i1;i1;"
181                OpName %9 "a"
182                OpName %10 "b"
183                OpName %13 "bar("
184                OpName %17 "baz(i1;"
185                OpName %16 "x"
186                OpName %21 "boo(i1;i1;"
187                OpName %19 "a"
188                OpName %20 "b"
189                OpName %29 "g"
190                OpName %42 "param"
191                OpName %44 "param"
192                OpName %45 "param"
193                OpName %48 "param"
194                OpName %49 "param"
195                OpName %54 "color"
196                OpDecorate %54 Location 0
197           %2 = OpTypeVoid
198           %3 = OpTypeFunction %2
199           %6 = OpTypeInt 32 1
200           %7 = OpTypePointer Function %6
201           %8 = OpTypeFunction %6 %7 %7
202          %15 = OpTypeFunction %6 %7
203          %28 = OpTypePointer Private %6
204          %29 = OpVariable %28 Private
205          %30 = OpConstant %6 2
206          %31 = OpConstant %6 5
207          %51 = OpTypeFloat 32
208          %52 = OpTypeVector %51 4
209          %53 = OpTypePointer Output %52
210          %54 = OpVariable %53 Output
211           %4 = OpFunction %2 Inline %3
212           %5 = OpLabel
213          %42 = OpVariable %7 Function
214          %44 = OpVariable %7 Function
215          %45 = OpVariable %7 Function
216          %48 = OpVariable %7 Function
217          %49 = OpVariable %7 Function
218          %41 = OpFunctionCall %2 %13
219                OpStore %42 %30
220          %43 = OpFunctionCall %6 %17 %42
221                OpStore %44 %31
222          %46 = OpLoad %6 %29
223                OpStore %45 %46
224          %47 = OpFunctionCall %6 %21 %44 %45
225                OpStore %48 %43
226                OpStore %49 %47
227          %50 = OpFunctionCall %6 %11 %48 %49
228                OpReturn
229                OpFunctionEnd
230          %11 = OpFunction %6 None %8
231           %9 = OpFunctionParameter %7
232          %10 = OpFunctionParameter %7
233          %12 = OpLabel
234          %23 = OpLoad %6 %9
235          %24 = OpLoad %6 %10
236          %25 = OpIAdd %6 %23 %24
237                OpReturnValue %25
238                OpFunctionEnd
239          %13 = OpFunction %2 DontInline %3
240          %14 = OpLabel
241                OpStore %29 %30
242                OpReturn
243                OpFunctionEnd
244          %17 = OpFunction %6 Pure %15
245          %16 = OpFunctionParameter %7
246          %18 = OpLabel
247          %32 = OpLoad %6 %16
248          %33 = OpIAdd %6 %31 %32
249                OpReturnValue %33
250                OpFunctionEnd
251          %21 = OpFunction %6 DontInline %8
252          %19 = OpFunctionParameter %7
253          %20 = OpFunctionParameter %7
254          %22 = OpLabel
255          %36 = OpLoad %6 %19
256          %37 = OpLoad %6 %20
257          %38 = OpIMul %6 %36 %37
258                OpReturnValue %38
259                OpFunctionEnd
260   )";
261   ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
262 }
263 
264 }  // namespace
265 }  // namespace fuzz
266 }  // namespace spvtools
267