• 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.h"
16 
17 #include <cassert>
18 
19 #include "source/fuzz/fuzzer_util.h"
20 #include "source/fuzz/transformation_access_chain.h"
21 #include "source/fuzz/transformation_add_constant_boolean.h"
22 #include "source/fuzz/transformation_add_constant_composite.h"
23 #include "source/fuzz/transformation_add_constant_null.h"
24 #include "source/fuzz/transformation_add_constant_scalar.h"
25 #include "source/fuzz/transformation_add_dead_block.h"
26 #include "source/fuzz/transformation_add_dead_break.h"
27 #include "source/fuzz/transformation_add_dead_continue.h"
28 #include "source/fuzz/transformation_add_function.h"
29 #include "source/fuzz/transformation_add_global_undef.h"
30 #include "source/fuzz/transformation_add_global_variable.h"
31 #include "source/fuzz/transformation_add_local_variable.h"
32 #include "source/fuzz/transformation_add_no_contraction_decoration.h"
33 #include "source/fuzz/transformation_add_type_array.h"
34 #include "source/fuzz/transformation_add_type_boolean.h"
35 #include "source/fuzz/transformation_add_type_float.h"
36 #include "source/fuzz/transformation_add_type_function.h"
37 #include "source/fuzz/transformation_add_type_int.h"
38 #include "source/fuzz/transformation_add_type_matrix.h"
39 #include "source/fuzz/transformation_add_type_pointer.h"
40 #include "source/fuzz/transformation_add_type_struct.h"
41 #include "source/fuzz/transformation_add_type_vector.h"
42 #include "source/fuzz/transformation_composite_construct.h"
43 #include "source/fuzz/transformation_composite_extract.h"
44 #include "source/fuzz/transformation_compute_data_synonym_fact_closure.h"
45 #include "source/fuzz/transformation_copy_object.h"
46 #include "source/fuzz/transformation_equation_instruction.h"
47 #include "source/fuzz/transformation_function_call.h"
48 #include "source/fuzz/transformation_load.h"
49 #include "source/fuzz/transformation_merge_blocks.h"
50 #include "source/fuzz/transformation_move_block_down.h"
51 #include "source/fuzz/transformation_outline_function.h"
52 #include "source/fuzz/transformation_permute_function_parameters.h"
53 #include "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h"
54 #include "source/fuzz/transformation_replace_constant_with_uniform.h"
55 #include "source/fuzz/transformation_replace_id_with_synonym.h"
56 #include "source/fuzz/transformation_set_function_control.h"
57 #include "source/fuzz/transformation_set_loop_control.h"
58 #include "source/fuzz/transformation_set_memory_operands_mask.h"
59 #include "source/fuzz/transformation_set_selection_control.h"
60 #include "source/fuzz/transformation_split_block.h"
61 #include "source/fuzz/transformation_store.h"
62 #include "source/fuzz/transformation_swap_commutable_operands.h"
63 #include "source/fuzz/transformation_toggle_access_chain_instruction.h"
64 #include "source/fuzz/transformation_vector_shuffle.h"
65 #include "source/util/make_unique.h"
66 
67 namespace spvtools {
68 namespace fuzz {
69 
70 Transformation::~Transformation() = default;
71 
FromMessage(const protobufs::Transformation & message)72 std::unique_ptr<Transformation> Transformation::FromMessage(
73     const protobufs::Transformation& message) {
74   switch (message.transformation_case()) {
75     case protobufs::Transformation::TransformationCase::kAccessChain:
76       return MakeUnique<TransformationAccessChain>(message.access_chain());
77     case protobufs::Transformation::TransformationCase::kAddConstantBoolean:
78       return MakeUnique<TransformationAddConstantBoolean>(
79           message.add_constant_boolean());
80     case protobufs::Transformation::TransformationCase::kAddConstantComposite:
81       return MakeUnique<TransformationAddConstantComposite>(
82           message.add_constant_composite());
83     case protobufs::Transformation::TransformationCase::kAddConstantNull:
84       return MakeUnique<TransformationAddConstantNull>(
85           message.add_constant_null());
86     case protobufs::Transformation::TransformationCase::kAddConstantScalar:
87       return MakeUnique<TransformationAddConstantScalar>(
88           message.add_constant_scalar());
89     case protobufs::Transformation::TransformationCase::kAddDeadBlock:
90       return MakeUnique<TransformationAddDeadBlock>(message.add_dead_block());
91     case protobufs::Transformation::TransformationCase::kAddDeadBreak:
92       return MakeUnique<TransformationAddDeadBreak>(message.add_dead_break());
93     case protobufs::Transformation::TransformationCase::kAddDeadContinue:
94       return MakeUnique<TransformationAddDeadContinue>(
95           message.add_dead_continue());
96     case protobufs::Transformation::TransformationCase::kAddFunction:
97       return MakeUnique<TransformationAddFunction>(message.add_function());
98     case protobufs::Transformation::TransformationCase::kAddGlobalUndef:
99       return MakeUnique<TransformationAddGlobalUndef>(
100           message.add_global_undef());
101     case protobufs::Transformation::TransformationCase::kAddGlobalVariable:
102       return MakeUnique<TransformationAddGlobalVariable>(
103           message.add_global_variable());
104     case protobufs::Transformation::TransformationCase::kAddLocalVariable:
105       return MakeUnique<TransformationAddLocalVariable>(
106           message.add_local_variable());
107     case protobufs::Transformation::TransformationCase::
108         kAddNoContractionDecoration:
109       return MakeUnique<TransformationAddNoContractionDecoration>(
110           message.add_no_contraction_decoration());
111     case protobufs::Transformation::TransformationCase::kAddTypeArray:
112       return MakeUnique<TransformationAddTypeArray>(message.add_type_array());
113     case protobufs::Transformation::TransformationCase::kAddTypeBoolean:
114       return MakeUnique<TransformationAddTypeBoolean>(
115           message.add_type_boolean());
116     case protobufs::Transformation::TransformationCase::kAddTypeFloat:
117       return MakeUnique<TransformationAddTypeFloat>(message.add_type_float());
118     case protobufs::Transformation::TransformationCase::kAddTypeFunction:
119       return MakeUnique<TransformationAddTypeFunction>(
120           message.add_type_function());
121     case protobufs::Transformation::TransformationCase::kAddTypeInt:
122       return MakeUnique<TransformationAddTypeInt>(message.add_type_int());
123     case protobufs::Transformation::TransformationCase::kAddTypeMatrix:
124       return MakeUnique<TransformationAddTypeMatrix>(message.add_type_matrix());
125     case protobufs::Transformation::TransformationCase::kAddTypePointer:
126       return MakeUnique<TransformationAddTypePointer>(
127           message.add_type_pointer());
128     case protobufs::Transformation::TransformationCase::kAddTypeStruct:
129       return MakeUnique<TransformationAddTypeStruct>(message.add_type_struct());
130     case protobufs::Transformation::TransformationCase::kAddTypeVector:
131       return MakeUnique<TransformationAddTypeVector>(message.add_type_vector());
132     case protobufs::Transformation::TransformationCase::kCompositeConstruct:
133       return MakeUnique<TransformationCompositeConstruct>(
134           message.composite_construct());
135     case protobufs::Transformation::TransformationCase::kCompositeExtract:
136       return MakeUnique<TransformationCompositeExtract>(
137           message.composite_extract());
138     case protobufs::Transformation::TransformationCase::
139         kComputeDataSynonymFactClosure:
140       return MakeUnique<TransformationComputeDataSynonymFactClosure>(
141           message.compute_data_synonym_fact_closure());
142     case protobufs::Transformation::TransformationCase::kCopyObject:
143       return MakeUnique<TransformationCopyObject>(message.copy_object());
144     case protobufs::Transformation::TransformationCase::kEquationInstruction:
145       return MakeUnique<TransformationEquationInstruction>(
146           message.equation_instruction());
147     case protobufs::Transformation::TransformationCase::kFunctionCall:
148       return MakeUnique<TransformationFunctionCall>(message.function_call());
149     case protobufs::Transformation::TransformationCase::kLoad:
150       return MakeUnique<TransformationLoad>(message.load());
151     case protobufs::Transformation::TransformationCase::kMergeBlocks:
152       return MakeUnique<TransformationMergeBlocks>(message.merge_blocks());
153     case protobufs::Transformation::TransformationCase::kMoveBlockDown:
154       return MakeUnique<TransformationMoveBlockDown>(message.move_block_down());
155     case protobufs::Transformation::TransformationCase::kOutlineFunction:
156       return MakeUnique<TransformationOutlineFunction>(
157           message.outline_function());
158     case protobufs::Transformation::TransformationCase::
159         kPermuteFunctionParameters:
160       return MakeUnique<TransformationPermuteFunctionParameters>(
161           message.permute_function_parameters());
162     case protobufs::Transformation::TransformationCase::
163         kReplaceBooleanConstantWithConstantBinary:
164       return MakeUnique<TransformationReplaceBooleanConstantWithConstantBinary>(
165           message.replace_boolean_constant_with_constant_binary());
166     case protobufs::Transformation::TransformationCase::
167         kReplaceConstantWithUniform:
168       return MakeUnique<TransformationReplaceConstantWithUniform>(
169           message.replace_constant_with_uniform());
170     case protobufs::Transformation::TransformationCase::kReplaceIdWithSynonym:
171       return MakeUnique<TransformationReplaceIdWithSynonym>(
172           message.replace_id_with_synonym());
173     case protobufs::Transformation::TransformationCase::kSetFunctionControl:
174       return MakeUnique<TransformationSetFunctionControl>(
175           message.set_function_control());
176     case protobufs::Transformation::TransformationCase::kSetLoopControl:
177       return MakeUnique<TransformationSetLoopControl>(
178           message.set_loop_control());
179     case protobufs::Transformation::TransformationCase::kSetMemoryOperandsMask:
180       return MakeUnique<TransformationSetMemoryOperandsMask>(
181           message.set_memory_operands_mask());
182     case protobufs::Transformation::TransformationCase::kSetSelectionControl:
183       return MakeUnique<TransformationSetSelectionControl>(
184           message.set_selection_control());
185     case protobufs::Transformation::TransformationCase::kSplitBlock:
186       return MakeUnique<TransformationSplitBlock>(message.split_block());
187     case protobufs::Transformation::TransformationCase::kStore:
188       return MakeUnique<TransformationStore>(message.store());
189     case protobufs::Transformation::TransformationCase::kSwapCommutableOperands:
190       return MakeUnique<TransformationSwapCommutableOperands>(
191           message.swap_commutable_operands());
192     case protobufs::Transformation::TransformationCase::
193         kToggleAccessChainInstruction:
194       return MakeUnique<TransformationToggleAccessChainInstruction>(
195           message.toggle_access_chain_instruction());
196     case protobufs::Transformation::TransformationCase::kVectorShuffle:
197       return MakeUnique<TransformationVectorShuffle>(message.vector_shuffle());
198     case protobufs::Transformation::TRANSFORMATION_NOT_SET:
199       assert(false && "An unset transformation was encountered.");
200       return nullptr;
201   }
202   assert(false && "Should be unreachable as all cases must be handled above.");
203   return nullptr;
204 }
205 
CheckIdIsFreshAndNotUsedByThisTransformation(uint32_t id,opt::IRContext * ir_context,std::set<uint32_t> * ids_used_by_this_transformation)206 bool Transformation::CheckIdIsFreshAndNotUsedByThisTransformation(
207     uint32_t id, opt::IRContext* ir_context,
208     std::set<uint32_t>* ids_used_by_this_transformation) {
209   if (!fuzzerutil::IsFreshId(ir_context, id)) {
210     return false;
211   }
212   if (ids_used_by_this_transformation->count(id) != 0) {
213     return false;
214   }
215   ids_used_by_this_transformation->insert(id);
216   return true;
217 }
218 
219 }  // namespace fuzz
220 }  // namespace spvtools
221