• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/transformation_add_local_variable.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(TransformationAddLocalVariableTest,BasicTest)25 TEST(TransformationAddLocalVariableTest, 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 = OpTypeInt 32 1
36           %7 = OpTypeStruct %6 %6
37           %8 = OpTypePointer Function %7
38          %10 = OpConstant %6 1
39          %11 = OpConstant %6 2
40          %12 = OpConstantComposite %7 %10 %11
41          %13 = OpTypeFloat 32
42          %14 = OpTypeInt 32 0
43          %15 = OpConstant %14 3
44          %16 = OpTypeArray %13 %15
45          %17 = OpTypeBool
46          %18 = OpTypeStruct %16 %7 %17
47          %19 = OpTypePointer Function %18
48          %21 = OpConstant %13 1
49          %22 = OpConstant %13 2
50          %23 = OpConstant %13 4
51          %24 = OpConstantComposite %16 %21 %22 %23
52          %25 = OpConstant %6 5
53          %26 = OpConstant %6 6
54          %27 = OpConstantComposite %7 %25 %26
55          %28 = OpConstantFalse %17
56          %29 = OpConstantComposite %18 %24 %27 %28
57          %30 = OpTypeVector %13 2
58          %31 = OpTypePointer Function %30
59          %33 = OpConstantComposite %30 %21 %21
60          %34 = OpTypeVector %17 3
61          %35 = OpTypePointer Function %34
62          %37 = OpConstantTrue %17
63          %38 = OpConstantComposite %34 %37 %28 %28
64          %39 = OpTypeVector %13 4
65          %40 = OpTypeMatrix %39 3
66          %41 = OpTypePointer Function %40
67          %43 = OpConstantComposite %39 %21 %22 %23 %21
68          %44 = OpConstantComposite %39 %22 %23 %21 %22
69          %45 = OpConstantComposite %39 %23 %21 %22 %23
70          %46 = OpConstantComposite %40 %43 %44 %45
71          %50 = OpTypePointer Function %14
72          %51 = OpConstantNull %14
73           %4 = OpFunction %2 None %3
74           %5 = OpLabel
75                OpReturn
76                OpFunctionEnd
77   )";
78 
79   const auto env = SPV_ENV_UNIVERSAL_1_4;
80   const auto consumer = nullptr;
81   const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
82   spvtools::ValidatorOptions validator_options;
83   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
84                                                kConsoleMessageConsumer));
85   TransformationContext transformation_context(
86       MakeUnique<FactManager>(context.get()), validator_options);
87   // A few cases of inapplicable transformations:
88   // Id 4 is already in use
89   ASSERT_FALSE(TransformationAddLocalVariable(4, 50, 4, 51, true)
90                    .IsApplicable(context.get(), transformation_context));
91   // Type mismatch between initializer and pointer
92   ASSERT_FALSE(TransformationAddLocalVariable(105, 46, 4, 51, true)
93                    .IsApplicable(context.get(), transformation_context));
94   // Id 5 is not a function
95   ASSERT_FALSE(TransformationAddLocalVariable(105, 50, 5, 51, true)
96                    .IsApplicable(context.get(), transformation_context));
97 
98   // %105 = OpVariable %50 Function %51
99   {
100     TransformationAddLocalVariable transformation(105, 50, 4, 51, true);
101     ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(105));
102     ASSERT_EQ(nullptr, context->get_instr_block(105));
103     ASSERT_TRUE(
104         transformation.IsApplicable(context.get(), transformation_context));
105     ApplyAndCheckFreshIds(transformation, context.get(),
106                           &transformation_context);
107     ASSERT_EQ(spv::Op::OpVariable,
108               context->get_def_use_mgr()->GetDef(105)->opcode());
109     ASSERT_EQ(5, context->get_instr_block(105)->id());
110   }
111 
112   // %104 = OpVariable %41 Function %46
113   {
114     TransformationAddLocalVariable transformation(104, 41, 4, 46, false);
115     ASSERT_TRUE(
116         transformation.IsApplicable(context.get(), transformation_context));
117     ApplyAndCheckFreshIds(transformation, context.get(),
118                           &transformation_context);
119   }
120 
121   // %103 = OpVariable %35 Function %38
122   {
123     TransformationAddLocalVariable transformation(103, 35, 4, 38, true);
124     ASSERT_TRUE(
125         transformation.IsApplicable(context.get(), transformation_context));
126     ApplyAndCheckFreshIds(transformation, context.get(),
127                           &transformation_context);
128   }
129 
130   // %102 = OpVariable %31 Function %33
131   {
132     TransformationAddLocalVariable transformation(102, 31, 4, 33, false);
133     ASSERT_TRUE(
134         transformation.IsApplicable(context.get(), transformation_context));
135     ApplyAndCheckFreshIds(transformation, context.get(),
136                           &transformation_context);
137   }
138 
139   // %101 = OpVariable %19 Function %29
140   {
141     TransformationAddLocalVariable transformation(101, 19, 4, 29, true);
142     ASSERT_TRUE(
143         transformation.IsApplicable(context.get(), transformation_context));
144     ApplyAndCheckFreshIds(transformation, context.get(),
145                           &transformation_context);
146   }
147 
148   // %100 = OpVariable %8 Function %12
149   {
150     TransformationAddLocalVariable transformation(100, 8, 4, 12, false);
151     ASSERT_TRUE(
152         transformation.IsApplicable(context.get(), transformation_context));
153     ApplyAndCheckFreshIds(transformation, context.get(),
154                           &transformation_context);
155   }
156 
157   ASSERT_FALSE(
158       transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
159   ASSERT_TRUE(
160       transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
161   ASSERT_FALSE(
162       transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
163   ASSERT_TRUE(
164       transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103));
165   ASSERT_FALSE(
166       transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104));
167   ASSERT_TRUE(
168       transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105));
169 
170   std::string after_transformation = R"(
171                OpCapability Shader
172           %1 = OpExtInstImport "GLSL.std.450"
173                OpMemoryModel Logical GLSL450
174                OpEntryPoint Fragment %4 "main"
175                OpExecutionMode %4 OriginUpperLeft
176                OpSource ESSL 310
177           %2 = OpTypeVoid
178           %3 = OpTypeFunction %2
179           %6 = OpTypeInt 32 1
180           %7 = OpTypeStruct %6 %6
181           %8 = OpTypePointer Function %7
182          %10 = OpConstant %6 1
183          %11 = OpConstant %6 2
184          %12 = OpConstantComposite %7 %10 %11
185          %13 = OpTypeFloat 32
186          %14 = OpTypeInt 32 0
187          %15 = OpConstant %14 3
188          %16 = OpTypeArray %13 %15
189          %17 = OpTypeBool
190          %18 = OpTypeStruct %16 %7 %17
191          %19 = OpTypePointer Function %18
192          %21 = OpConstant %13 1
193          %22 = OpConstant %13 2
194          %23 = OpConstant %13 4
195          %24 = OpConstantComposite %16 %21 %22 %23
196          %25 = OpConstant %6 5
197          %26 = OpConstant %6 6
198          %27 = OpConstantComposite %7 %25 %26
199          %28 = OpConstantFalse %17
200          %29 = OpConstantComposite %18 %24 %27 %28
201          %30 = OpTypeVector %13 2
202          %31 = OpTypePointer Function %30
203          %33 = OpConstantComposite %30 %21 %21
204          %34 = OpTypeVector %17 3
205          %35 = OpTypePointer Function %34
206          %37 = OpConstantTrue %17
207          %38 = OpConstantComposite %34 %37 %28 %28
208          %39 = OpTypeVector %13 4
209          %40 = OpTypeMatrix %39 3
210          %41 = OpTypePointer Function %40
211          %43 = OpConstantComposite %39 %21 %22 %23 %21
212          %44 = OpConstantComposite %39 %22 %23 %21 %22
213          %45 = OpConstantComposite %39 %23 %21 %22 %23
214          %46 = OpConstantComposite %40 %43 %44 %45
215          %50 = OpTypePointer Function %14
216          %51 = OpConstantNull %14
217           %4 = OpFunction %2 None %3
218           %5 = OpLabel
219         %100 = OpVariable %8 Function %12
220         %101 = OpVariable %19 Function %29
221         %102 = OpVariable %31 Function %33
222         %103 = OpVariable %35 Function %38
223         %104 = OpVariable %41 Function %46
224         %105 = OpVariable %50 Function %51
225                OpReturn
226                OpFunctionEnd
227   )";
228   ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
229 }
230 
231 }  // namespace
232 }  // namespace fuzz
233 }  // namespace spvtools
234