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_bit_instruction_synonym.h" 22 #include "source/fuzz/transformation_add_constant_boolean.h" 23 #include "source/fuzz/transformation_add_constant_composite.h" 24 #include "source/fuzz/transformation_add_constant_null.h" 25 #include "source/fuzz/transformation_add_constant_scalar.h" 26 #include "source/fuzz/transformation_add_copy_memory.h" 27 #include "source/fuzz/transformation_add_dead_block.h" 28 #include "source/fuzz/transformation_add_dead_break.h" 29 #include "source/fuzz/transformation_add_dead_continue.h" 30 #include "source/fuzz/transformation_add_early_terminator_wrapper.h" 31 #include "source/fuzz/transformation_add_function.h" 32 #include "source/fuzz/transformation_add_global_undef.h" 33 #include "source/fuzz/transformation_add_global_variable.h" 34 #include "source/fuzz/transformation_add_image_sample_unused_components.h" 35 #include "source/fuzz/transformation_add_local_variable.h" 36 #include "source/fuzz/transformation_add_loop_preheader.h" 37 #include "source/fuzz/transformation_add_loop_to_create_int_constant_synonym.h" 38 #include "source/fuzz/transformation_add_no_contraction_decoration.h" 39 #include "source/fuzz/transformation_add_opphi_synonym.h" 40 #include "source/fuzz/transformation_add_parameter.h" 41 #include "source/fuzz/transformation_add_relaxed_decoration.h" 42 #include "source/fuzz/transformation_add_spec_constant_op.h" 43 #include "source/fuzz/transformation_add_synonym.h" 44 #include "source/fuzz/transformation_add_type_array.h" 45 #include "source/fuzz/transformation_add_type_boolean.h" 46 #include "source/fuzz/transformation_add_type_float.h" 47 #include "source/fuzz/transformation_add_type_function.h" 48 #include "source/fuzz/transformation_add_type_int.h" 49 #include "source/fuzz/transformation_add_type_matrix.h" 50 #include "source/fuzz/transformation_add_type_pointer.h" 51 #include "source/fuzz/transformation_add_type_struct.h" 52 #include "source/fuzz/transformation_add_type_vector.h" 53 #include "source/fuzz/transformation_adjust_branch_weights.h" 54 #include "source/fuzz/transformation_composite_construct.h" 55 #include "source/fuzz/transformation_composite_extract.h" 56 #include "source/fuzz/transformation_composite_insert.h" 57 #include "source/fuzz/transformation_compute_data_synonym_fact_closure.h" 58 #include "source/fuzz/transformation_duplicate_region_with_selection.h" 59 #include "source/fuzz/transformation_equation_instruction.h" 60 #include "source/fuzz/transformation_expand_vector_reduction.h" 61 #include "source/fuzz/transformation_flatten_conditional_branch.h" 62 #include "source/fuzz/transformation_function_call.h" 63 #include "source/fuzz/transformation_inline_function.h" 64 #include "source/fuzz/transformation_invert_comparison_operator.h" 65 #include "source/fuzz/transformation_load.h" 66 #include "source/fuzz/transformation_make_vector_operation_dynamic.h" 67 #include "source/fuzz/transformation_merge_blocks.h" 68 #include "source/fuzz/transformation_merge_function_returns.h" 69 #include "source/fuzz/transformation_move_block_down.h" 70 #include "source/fuzz/transformation_move_instruction_down.h" 71 #include "source/fuzz/transformation_mutate_pointer.h" 72 #include "source/fuzz/transformation_outline_function.h" 73 #include "source/fuzz/transformation_permute_function_parameters.h" 74 #include "source/fuzz/transformation_permute_phi_operands.h" 75 #include "source/fuzz/transformation_propagate_instruction_down.h" 76 #include "source/fuzz/transformation_propagate_instruction_up.h" 77 #include "source/fuzz/transformation_push_id_through_variable.h" 78 #include "source/fuzz/transformation_record_synonymous_constants.h" 79 #include "source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.h" 80 #include "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h" 81 #include "source/fuzz/transformation_replace_branch_from_dead_block_with_exit.h" 82 #include "source/fuzz/transformation_replace_constant_with_uniform.h" 83 #include "source/fuzz/transformation_replace_copy_memory_with_load_store.h" 84 #include "source/fuzz/transformation_replace_copy_object_with_store_load.h" 85 #include "source/fuzz/transformation_replace_id_with_synonym.h" 86 #include "source/fuzz/transformation_replace_irrelevant_id.h" 87 #include "source/fuzz/transformation_replace_linear_algebra_instruction.h" 88 #include "source/fuzz/transformation_replace_load_store_with_copy_memory.h" 89 #include "source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.h" 90 #include "source/fuzz/transformation_replace_opselect_with_conditional_branch.h" 91 #include "source/fuzz/transformation_replace_parameter_with_global.h" 92 #include "source/fuzz/transformation_replace_params_with_struct.h" 93 #include "source/fuzz/transformation_set_function_control.h" 94 #include "source/fuzz/transformation_set_loop_control.h" 95 #include "source/fuzz/transformation_set_memory_operands_mask.h" 96 #include "source/fuzz/transformation_set_selection_control.h" 97 #include "source/fuzz/transformation_split_block.h" 98 #include "source/fuzz/transformation_store.h" 99 #include "source/fuzz/transformation_swap_commutable_operands.h" 100 #include "source/fuzz/transformation_swap_conditional_branch_operands.h" 101 #include "source/fuzz/transformation_swap_function_variables.h" 102 #include "source/fuzz/transformation_swap_two_functions.h" 103 #include "source/fuzz/transformation_toggle_access_chain_instruction.h" 104 #include "source/fuzz/transformation_vector_shuffle.h" 105 #include "source/fuzz/transformation_wrap_early_terminator_in_function.h" 106 #include "source/fuzz/transformation_wrap_region_in_selection.h" 107 #include "source/util/make_unique.h" 108 109 namespace spvtools { 110 namespace fuzz { 111 112 Transformation::~Transformation() = default; 113 FromMessage(const protobufs::Transformation & message)114std::unique_ptr<Transformation> Transformation::FromMessage( 115 const protobufs::Transformation& message) { 116 switch (message.transformation_case()) { 117 case protobufs::Transformation::TransformationCase::kAccessChain: 118 return MakeUnique<TransformationAccessChain>(message.access_chain()); 119 case protobufs::Transformation::TransformationCase:: 120 kAddBitInstructionSynonym: 121 return MakeUnique<TransformationAddBitInstructionSynonym>( 122 message.add_bit_instruction_synonym()); 123 case protobufs::Transformation::TransformationCase::kAddConstantBoolean: 124 return MakeUnique<TransformationAddConstantBoolean>( 125 message.add_constant_boolean()); 126 case protobufs::Transformation::TransformationCase::kAddConstantComposite: 127 return MakeUnique<TransformationAddConstantComposite>( 128 message.add_constant_composite()); 129 case protobufs::Transformation::TransformationCase::kAddConstantNull: 130 return MakeUnique<TransformationAddConstantNull>( 131 message.add_constant_null()); 132 case protobufs::Transformation::TransformationCase::kAddConstantScalar: 133 return MakeUnique<TransformationAddConstantScalar>( 134 message.add_constant_scalar()); 135 case protobufs::Transformation::TransformationCase::kAddCopyMemory: 136 return MakeUnique<TransformationAddCopyMemory>(message.add_copy_memory()); 137 case protobufs::Transformation::TransformationCase::kAddDeadBlock: 138 return MakeUnique<TransformationAddDeadBlock>(message.add_dead_block()); 139 case protobufs::Transformation::TransformationCase::kAddDeadBreak: 140 return MakeUnique<TransformationAddDeadBreak>(message.add_dead_break()); 141 case protobufs::Transformation::TransformationCase::kAddDeadContinue: 142 return MakeUnique<TransformationAddDeadContinue>( 143 message.add_dead_continue()); 144 case protobufs::Transformation::TransformationCase:: 145 kAddEarlyTerminatorWrapper: 146 return MakeUnique<TransformationAddEarlyTerminatorWrapper>( 147 message.add_early_terminator_wrapper()); 148 case protobufs::Transformation::TransformationCase::kAddFunction: 149 return MakeUnique<TransformationAddFunction>(message.add_function()); 150 case protobufs::Transformation::TransformationCase::kAddGlobalUndef: 151 return MakeUnique<TransformationAddGlobalUndef>( 152 message.add_global_undef()); 153 case protobufs::Transformation::TransformationCase::kAddGlobalVariable: 154 return MakeUnique<TransformationAddGlobalVariable>( 155 message.add_global_variable()); 156 case protobufs::Transformation::TransformationCase:: 157 kAddImageSampleUnusedComponents: 158 return MakeUnique<TransformationAddImageSampleUnusedComponents>( 159 message.add_image_sample_unused_components()); 160 case protobufs::Transformation::TransformationCase::kAddLocalVariable: 161 return MakeUnique<TransformationAddLocalVariable>( 162 message.add_local_variable()); 163 case protobufs::Transformation::TransformationCase::kAddLoopPreheader: 164 return MakeUnique<TransformationAddLoopPreheader>( 165 message.add_loop_preheader()); 166 case protobufs::Transformation::TransformationCase:: 167 kAddLoopToCreateIntConstantSynonym: 168 return MakeUnique<TransformationAddLoopToCreateIntConstantSynonym>( 169 message.add_loop_to_create_int_constant_synonym()); 170 case protobufs::Transformation::TransformationCase:: 171 kAddNoContractionDecoration: 172 return MakeUnique<TransformationAddNoContractionDecoration>( 173 message.add_no_contraction_decoration()); 174 case protobufs::Transformation::TransformationCase::kAddOpphiSynonym: 175 return MakeUnique<TransformationAddOpPhiSynonym>( 176 message.add_opphi_synonym()); 177 case protobufs::Transformation::TransformationCase::kAddParameter: 178 return MakeUnique<TransformationAddParameter>(message.add_parameter()); 179 case protobufs::Transformation::TransformationCase::kAddRelaxedDecoration: 180 return MakeUnique<TransformationAddRelaxedDecoration>( 181 message.add_relaxed_decoration()); 182 case protobufs::Transformation::TransformationCase::kAddSpecConstantOp: 183 return MakeUnique<TransformationAddSpecConstantOp>( 184 message.add_spec_constant_op()); 185 case protobufs::Transformation::TransformationCase::kAddSynonym: 186 return MakeUnique<TransformationAddSynonym>(message.add_synonym()); 187 case protobufs::Transformation::TransformationCase::kAddTypeArray: 188 return MakeUnique<TransformationAddTypeArray>(message.add_type_array()); 189 case protobufs::Transformation::TransformationCase::kAddTypeBoolean: 190 return MakeUnique<TransformationAddTypeBoolean>( 191 message.add_type_boolean()); 192 case protobufs::Transformation::TransformationCase::kAddTypeFloat: 193 return MakeUnique<TransformationAddTypeFloat>(message.add_type_float()); 194 case protobufs::Transformation::TransformationCase::kAddTypeFunction: 195 return MakeUnique<TransformationAddTypeFunction>( 196 message.add_type_function()); 197 case protobufs::Transformation::TransformationCase::kAddTypeInt: 198 return MakeUnique<TransformationAddTypeInt>(message.add_type_int()); 199 case protobufs::Transformation::TransformationCase::kAddTypeMatrix: 200 return MakeUnique<TransformationAddTypeMatrix>(message.add_type_matrix()); 201 case protobufs::Transformation::TransformationCase::kAddTypePointer: 202 return MakeUnique<TransformationAddTypePointer>( 203 message.add_type_pointer()); 204 case protobufs::Transformation::TransformationCase::kAddTypeStruct: 205 return MakeUnique<TransformationAddTypeStruct>(message.add_type_struct()); 206 case protobufs::Transformation::TransformationCase::kAddTypeVector: 207 return MakeUnique<TransformationAddTypeVector>(message.add_type_vector()); 208 case protobufs::Transformation::TransformationCase::kAdjustBranchWeights: 209 return MakeUnique<TransformationAdjustBranchWeights>( 210 message.adjust_branch_weights()); 211 case protobufs::Transformation::TransformationCase::kCompositeConstruct: 212 return MakeUnique<TransformationCompositeConstruct>( 213 message.composite_construct()); 214 case protobufs::Transformation::TransformationCase::kCompositeExtract: 215 return MakeUnique<TransformationCompositeExtract>( 216 message.composite_extract()); 217 case protobufs::Transformation::TransformationCase::kCompositeInsert: 218 return MakeUnique<TransformationCompositeInsert>( 219 message.composite_insert()); 220 case protobufs::Transformation::TransformationCase:: 221 kComputeDataSynonymFactClosure: 222 return MakeUnique<TransformationComputeDataSynonymFactClosure>( 223 message.compute_data_synonym_fact_closure()); 224 case protobufs::Transformation::TransformationCase:: 225 kDuplicateRegionWithSelection: 226 return MakeUnique<TransformationDuplicateRegionWithSelection>( 227 message.duplicate_region_with_selection()); 228 case protobufs::Transformation::TransformationCase::kEquationInstruction: 229 return MakeUnique<TransformationEquationInstruction>( 230 message.equation_instruction()); 231 case protobufs::Transformation::TransformationCase::kExpandVectorReduction: 232 return MakeUnique<TransformationExpandVectorReduction>( 233 message.expand_vector_reduction()); 234 case protobufs::Transformation::TransformationCase:: 235 kFlattenConditionalBranch: 236 return MakeUnique<TransformationFlattenConditionalBranch>( 237 message.flatten_conditional_branch()); 238 case protobufs::Transformation::TransformationCase::kFunctionCall: 239 return MakeUnique<TransformationFunctionCall>(message.function_call()); 240 case protobufs::Transformation::TransformationCase::kInlineFunction: 241 return MakeUnique<TransformationInlineFunction>( 242 message.inline_function()); 243 case protobufs::Transformation::TransformationCase:: 244 kInvertComparisonOperator: 245 return MakeUnique<TransformationInvertComparisonOperator>( 246 message.invert_comparison_operator()); 247 case protobufs::Transformation::TransformationCase::kLoad: 248 return MakeUnique<TransformationLoad>(message.load()); 249 case protobufs::Transformation::TransformationCase:: 250 kMakeVectorOperationDynamic: 251 return MakeUnique<TransformationMakeVectorOperationDynamic>( 252 message.make_vector_operation_dynamic()); 253 case protobufs::Transformation::TransformationCase::kMergeBlocks: 254 return MakeUnique<TransformationMergeBlocks>(message.merge_blocks()); 255 case protobufs::Transformation::TransformationCase::kMergeFunctionReturns: 256 return MakeUnique<TransformationMergeFunctionReturns>( 257 message.merge_function_returns()); 258 case protobufs::Transformation::TransformationCase::kMoveBlockDown: 259 return MakeUnique<TransformationMoveBlockDown>(message.move_block_down()); 260 case protobufs::Transformation::TransformationCase::kMoveInstructionDown: 261 return MakeUnique<TransformationMoveInstructionDown>( 262 message.move_instruction_down()); 263 case protobufs::Transformation::TransformationCase::kMutatePointer: 264 return MakeUnique<TransformationMutatePointer>(message.mutate_pointer()); 265 case protobufs::Transformation::TransformationCase::kOutlineFunction: 266 return MakeUnique<TransformationOutlineFunction>( 267 message.outline_function()); 268 case protobufs::Transformation::TransformationCase:: 269 kPermuteFunctionParameters: 270 return MakeUnique<TransformationPermuteFunctionParameters>( 271 message.permute_function_parameters()); 272 case protobufs::Transformation::TransformationCase::kPermutePhiOperands: 273 return MakeUnique<TransformationPermutePhiOperands>( 274 message.permute_phi_operands()); 275 case protobufs::Transformation::TransformationCase:: 276 kPropagateInstructionDown: 277 return MakeUnique<TransformationPropagateInstructionDown>( 278 message.propagate_instruction_down()); 279 case protobufs::Transformation::TransformationCase::kPropagateInstructionUp: 280 return MakeUnique<TransformationPropagateInstructionUp>( 281 message.propagate_instruction_up()); 282 case protobufs::Transformation::TransformationCase::kPushIdThroughVariable: 283 return MakeUnique<TransformationPushIdThroughVariable>( 284 message.push_id_through_variable()); 285 case protobufs::Transformation::TransformationCase:: 286 kRecordSynonymousConstants: 287 return MakeUnique<TransformationRecordSynonymousConstants>( 288 message.record_synonymous_constants()); 289 case protobufs::Transformation::TransformationCase:: 290 kReplaceAddSubMulWithCarryingExtended: 291 return MakeUnique<TransformationReplaceAddSubMulWithCarryingExtended>( 292 message.replace_add_sub_mul_with_carrying_extended()); 293 case protobufs::Transformation::TransformationCase:: 294 kReplaceBooleanConstantWithConstantBinary: 295 return MakeUnique<TransformationReplaceBooleanConstantWithConstantBinary>( 296 message.replace_boolean_constant_with_constant_binary()); 297 case protobufs::Transformation::TransformationCase:: 298 kReplaceBranchFromDeadBlockWithExit: 299 return MakeUnique<TransformationReplaceBranchFromDeadBlockWithExit>( 300 message.replace_branch_from_dead_block_with_exit()); 301 case protobufs::Transformation::TransformationCase:: 302 kReplaceConstantWithUniform: 303 return MakeUnique<TransformationReplaceConstantWithUniform>( 304 message.replace_constant_with_uniform()); 305 case protobufs::Transformation::TransformationCase:: 306 kReplaceCopyMemoryWithLoadStore: 307 return MakeUnique<TransformationReplaceCopyMemoryWithLoadStore>( 308 message.replace_copy_memory_with_load_store()); 309 case protobufs::Transformation::TransformationCase:: 310 kReplaceCopyObjectWithStoreLoad: 311 return MakeUnique<TransformationReplaceCopyObjectWithStoreLoad>( 312 message.replace_copy_object_with_store_load()); 313 case protobufs::Transformation::TransformationCase::kReplaceIdWithSynonym: 314 return MakeUnique<TransformationReplaceIdWithSynonym>( 315 message.replace_id_with_synonym()); 316 case protobufs::Transformation::TransformationCase::kReplaceIrrelevantId: 317 return MakeUnique<TransformationReplaceIrrelevantId>( 318 message.replace_irrelevant_id()); 319 case protobufs::Transformation::TransformationCase:: 320 kReplaceLinearAlgebraInstruction: 321 return MakeUnique<TransformationReplaceLinearAlgebraInstruction>( 322 message.replace_linear_algebra_instruction()); 323 case protobufs::Transformation::TransformationCase:: 324 kReplaceLoadStoreWithCopyMemory: 325 return MakeUnique<TransformationReplaceLoadStoreWithCopyMemory>( 326 message.replace_load_store_with_copy_memory()); 327 case protobufs::Transformation::TransformationCase:: 328 kReplaceOpselectWithConditionalBranch: 329 return MakeUnique<TransformationReplaceOpSelectWithConditionalBranch>( 330 message.replace_opselect_with_conditional_branch()); 331 case protobufs::Transformation::TransformationCase:: 332 kReplaceParameterWithGlobal: 333 return MakeUnique<TransformationReplaceParameterWithGlobal>( 334 message.replace_parameter_with_global()); 335 case protobufs::Transformation::TransformationCase:: 336 kReplaceParamsWithStruct: 337 return MakeUnique<TransformationReplaceParamsWithStruct>( 338 message.replace_params_with_struct()); 339 case protobufs::Transformation::TransformationCase:: 340 kReplaceOpphiIdFromDeadPredecessor: 341 return MakeUnique<TransformationReplaceOpPhiIdFromDeadPredecessor>( 342 message.replace_opphi_id_from_dead_predecessor()); 343 case protobufs::Transformation::TransformationCase::kSetFunctionControl: 344 return MakeUnique<TransformationSetFunctionControl>( 345 message.set_function_control()); 346 case protobufs::Transformation::TransformationCase::kSetLoopControl: 347 return MakeUnique<TransformationSetLoopControl>( 348 message.set_loop_control()); 349 case protobufs::Transformation::TransformationCase::kSetMemoryOperandsMask: 350 return MakeUnique<TransformationSetMemoryOperandsMask>( 351 message.set_memory_operands_mask()); 352 case protobufs::Transformation::TransformationCase::kSetSelectionControl: 353 return MakeUnique<TransformationSetSelectionControl>( 354 message.set_selection_control()); 355 case protobufs::Transformation::TransformationCase::kSplitBlock: 356 return MakeUnique<TransformationSplitBlock>(message.split_block()); 357 case protobufs::Transformation::TransformationCase::kStore: 358 return MakeUnique<TransformationStore>(message.store()); 359 case protobufs::Transformation::TransformationCase::kSwapCommutableOperands: 360 return MakeUnique<TransformationSwapCommutableOperands>( 361 message.swap_commutable_operands()); 362 case protobufs::Transformation::TransformationCase:: 363 kSwapConditionalBranchOperands: 364 return MakeUnique<TransformationSwapConditionalBranchOperands>( 365 message.swap_conditional_branch_operands()); 366 case protobufs::Transformation::TransformationCase::kSwapFunctionVariables: 367 return MakeUnique<TransformationSwapFunctionVariables>( 368 message.swap_function_variables()); 369 case protobufs::Transformation::TransformationCase::kSwapTwoFunctions: 370 return MakeUnique<TransformationSwapTwoFunctions>( 371 message.swap_two_functions()); 372 case protobufs::Transformation::TransformationCase:: 373 kToggleAccessChainInstruction: 374 return MakeUnique<TransformationToggleAccessChainInstruction>( 375 message.toggle_access_chain_instruction()); 376 case protobufs::Transformation::TransformationCase::kVectorShuffle: 377 return MakeUnique<TransformationVectorShuffle>(message.vector_shuffle()); 378 case protobufs::Transformation::TransformationCase:: 379 kWrapEarlyTerminatorInFunction: 380 return MakeUnique<TransformationWrapEarlyTerminatorInFunction>( 381 message.wrap_early_terminator_in_function()); 382 case protobufs::Transformation::TransformationCase::kWrapRegionInSelection: 383 return MakeUnique<TransformationWrapRegionInSelection>( 384 message.wrap_region_in_selection()); 385 case protobufs::Transformation::TRANSFORMATION_NOT_SET: 386 assert(false && "An unset transformation was encountered."); 387 return nullptr; 388 } 389 assert(false && "Should be unreachable as all cases must be handled above."); 390 return nullptr; 391 } 392 CheckIdIsFreshAndNotUsedByThisTransformation(uint32_t id,opt::IRContext * ir_context,std::set<uint32_t> * ids_used_by_this_transformation)393bool Transformation::CheckIdIsFreshAndNotUsedByThisTransformation( 394 uint32_t id, opt::IRContext* ir_context, 395 std::set<uint32_t>* ids_used_by_this_transformation) { 396 if (!fuzzerutil::IsFreshId(ir_context, id)) { 397 return false; 398 } 399 if (ids_used_by_this_transformation->count(id) != 0) { 400 return false; 401 } 402 ids_used_by_this_transformation->insert(id); 403 return true; 404 } 405 406 } // namespace fuzz 407 } // namespace spvtools 408