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_constant_null.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(TransformationAddConstantNullTest, BasicTest)25 TEST(TransformationAddConstantNullTest, 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 = OpTypeInt 32 1
37           %8 = OpTypeVector %6 2
38           %9 = OpTypeVector %6 3
39          %10 = OpTypeVector %6 4
40          %11 = OpTypeVector %7 2
41          %20 = OpTypeSampler
42          %21 = OpTypeImage %6 2D 0 0 0 0 Rgba32f
43          %22 = OpTypeSampledImage %21
44           %4 = OpFunction %2 None %3
45           %5 = OpLabel
46                OpReturn
47                OpFunctionEnd
48   )";
49 
50   const auto env = SPV_ENV_UNIVERSAL_1_4;
51   const auto consumer = nullptr;
52   const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
53   spvtools::ValidatorOptions validator_options;
54   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
55                                                kConsoleMessageConsumer));
56   TransformationContext transformation_context(
57       MakeUnique<FactManager>(context.get()), validator_options);
58   // Id already in use
59   ASSERT_FALSE(TransformationAddConstantNull(4, 11).IsApplicable(
60       context.get(), transformation_context));
61   // %1 is not a type
62   ASSERT_FALSE(TransformationAddConstantNull(100, 1).IsApplicable(
63       context.get(), transformation_context));
64 
65   // %3 is a function type
66   ASSERT_FALSE(TransformationAddConstantNull(100, 3).IsApplicable(
67       context.get(), transformation_context));
68 
69   // %20 is a sampler type
70   ASSERT_FALSE(TransformationAddConstantNull(100, 20).IsApplicable(
71       context.get(), transformation_context));
72 
73   // %21 is an image type
74   ASSERT_FALSE(TransformationAddConstantNull(100, 21).IsApplicable(
75       context.get(), transformation_context));
76 
77   // %22 is a sampled image type
78   ASSERT_FALSE(TransformationAddConstantNull(100, 22).IsApplicable(
79       context.get(), transformation_context));
80 
81   {
82     // %100 = OpConstantNull %6
83     TransformationAddConstantNull transformation(100, 6);
84     ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
85     ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(100));
86     ASSERT_TRUE(
87         transformation.IsApplicable(context.get(), transformation_context));
88     ApplyAndCheckFreshIds(transformation, context.get(),
89                           &transformation_context);
90     ASSERT_EQ(spv::Op::OpConstantNull,
91               context->get_def_use_mgr()->GetDef(100)->opcode());
92     ASSERT_EQ(
93         0.0F,
94         context->get_constant_mgr()->FindDeclaredConstant(100)->GetFloat());
95   }
96 
97   TransformationAddConstantNull transformations[] = {
98 
99       // %101 = OpConstantNull %7
100       TransformationAddConstantNull(101, 7),
101 
102       // %102 = OpConstantNull %8
103       TransformationAddConstantNull(102, 8),
104 
105       // %103 = OpConstantNull %9
106       TransformationAddConstantNull(103, 9),
107 
108       // %104 = OpConstantNull %10
109       TransformationAddConstantNull(104, 10),
110 
111       // %105 = OpConstantNull %11
112       TransformationAddConstantNull(105, 11)};
113 
114   for (auto& transformation : transformations) {
115     ASSERT_TRUE(
116         transformation.IsApplicable(context.get(), transformation_context));
117     ApplyAndCheckFreshIds(transformation, context.get(),
118                           &transformation_context);
119   }
120   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
121                                                kConsoleMessageConsumer));
122 
123   std::string after_transformation = R"(
124                OpCapability Shader
125           %1 = OpExtInstImport "GLSL.std.450"
126                OpMemoryModel Logical GLSL450
127                OpEntryPoint Fragment %4 "main"
128                OpExecutionMode %4 OriginUpperLeft
129                OpSource ESSL 310
130           %2 = OpTypeVoid
131           %3 = OpTypeFunction %2
132           %6 = OpTypeFloat 32
133           %7 = OpTypeInt 32 1
134           %8 = OpTypeVector %6 2
135           %9 = OpTypeVector %6 3
136          %10 = OpTypeVector %6 4
137          %11 = OpTypeVector %7 2
138          %20 = OpTypeSampler
139          %21 = OpTypeImage %6 2D 0 0 0 0 Rgba32f
140          %22 = OpTypeSampledImage %21
141         %100 = OpConstantNull %6
142         %101 = OpConstantNull %7
143         %102 = OpConstantNull %8
144         %103 = OpConstantNull %9
145         %104 = OpConstantNull %10
146         %105 = OpConstantNull %11
147           %4 = OpFunction %2 None %3
148           %5 = OpLabel
149                OpReturn
150                OpFunctionEnd
151   )";
152   ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
153 }
154 
155 }  // namespace
156 }  // namespace fuzz
157 }  // namespace spvtools
158