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