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)72std::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)206bool 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