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/fuzz/transformation_wrap_vector_synonym.h" 108 #include "source/util/make_unique.h" 109 110 namespace spvtools { 111 namespace fuzz { 112 113 Transformation::~Transformation() = default; 114 FromMessage(const protobufs::Transformation & message)115std::unique_ptr<Transformation> Transformation::FromMessage( 116 const protobufs::Transformation& message) { 117 switch (message.transformation_case()) { 118 case protobufs::Transformation::TransformationCase::kAccessChain: 119 return MakeUnique<TransformationAccessChain>(message.access_chain()); 120 case protobufs::Transformation::TransformationCase:: 121 kAddBitInstructionSynonym: 122 return MakeUnique<TransformationAddBitInstructionSynonym>( 123 message.add_bit_instruction_synonym()); 124 case protobufs::Transformation::TransformationCase::kAddConstantBoolean: 125 return MakeUnique<TransformationAddConstantBoolean>( 126 message.add_constant_boolean()); 127 case protobufs::Transformation::TransformationCase::kAddConstantComposite: 128 return MakeUnique<TransformationAddConstantComposite>( 129 message.add_constant_composite()); 130 case protobufs::Transformation::TransformationCase::kAddConstantNull: 131 return MakeUnique<TransformationAddConstantNull>( 132 message.add_constant_null()); 133 case protobufs::Transformation::TransformationCase::kAddConstantScalar: 134 return MakeUnique<TransformationAddConstantScalar>( 135 message.add_constant_scalar()); 136 case protobufs::Transformation::TransformationCase::kAddCopyMemory: 137 return MakeUnique<TransformationAddCopyMemory>(message.add_copy_memory()); 138 case protobufs::Transformation::TransformationCase::kAddDeadBlock: 139 return MakeUnique<TransformationAddDeadBlock>(message.add_dead_block()); 140 case protobufs::Transformation::TransformationCase::kAddDeadBreak: 141 return MakeUnique<TransformationAddDeadBreak>(message.add_dead_break()); 142 case protobufs::Transformation::TransformationCase::kAddDeadContinue: 143 return MakeUnique<TransformationAddDeadContinue>( 144 message.add_dead_continue()); 145 case protobufs::Transformation::TransformationCase:: 146 kAddEarlyTerminatorWrapper: 147 return MakeUnique<TransformationAddEarlyTerminatorWrapper>( 148 message.add_early_terminator_wrapper()); 149 case protobufs::Transformation::TransformationCase::kAddFunction: 150 return MakeUnique<TransformationAddFunction>(message.add_function()); 151 case protobufs::Transformation::TransformationCase::kAddGlobalUndef: 152 return MakeUnique<TransformationAddGlobalUndef>( 153 message.add_global_undef()); 154 case protobufs::Transformation::TransformationCase::kAddGlobalVariable: 155 return MakeUnique<TransformationAddGlobalVariable>( 156 message.add_global_variable()); 157 case protobufs::Transformation::TransformationCase:: 158 kAddImageSampleUnusedComponents: 159 return MakeUnique<TransformationAddImageSampleUnusedComponents>( 160 message.add_image_sample_unused_components()); 161 case protobufs::Transformation::TransformationCase::kAddLocalVariable: 162 return MakeUnique<TransformationAddLocalVariable>( 163 message.add_local_variable()); 164 case protobufs::Transformation::TransformationCase::kAddLoopPreheader: 165 return MakeUnique<TransformationAddLoopPreheader>( 166 message.add_loop_preheader()); 167 case protobufs::Transformation::TransformationCase:: 168 kAddLoopToCreateIntConstantSynonym: 169 return MakeUnique<TransformationAddLoopToCreateIntConstantSynonym>( 170 message.add_loop_to_create_int_constant_synonym()); 171 case protobufs::Transformation::TransformationCase:: 172 kAddNoContractionDecoration: 173 return MakeUnique<TransformationAddNoContractionDecoration>( 174 message.add_no_contraction_decoration()); 175 case protobufs::Transformation::TransformationCase::kAddOpphiSynonym: 176 return MakeUnique<TransformationAddOpPhiSynonym>( 177 message.add_opphi_synonym()); 178 case protobufs::Transformation::TransformationCase::kAddParameter: 179 return MakeUnique<TransformationAddParameter>(message.add_parameter()); 180 case protobufs::Transformation::TransformationCase::kAddRelaxedDecoration: 181 return MakeUnique<TransformationAddRelaxedDecoration>( 182 message.add_relaxed_decoration()); 183 case protobufs::Transformation::TransformationCase::kAddSpecConstantOp: 184 return MakeUnique<TransformationAddSpecConstantOp>( 185 message.add_spec_constant_op()); 186 case protobufs::Transformation::TransformationCase::kAddSynonym: 187 return MakeUnique<TransformationAddSynonym>(message.add_synonym()); 188 case protobufs::Transformation::TransformationCase::kAddTypeArray: 189 return MakeUnique<TransformationAddTypeArray>(message.add_type_array()); 190 case protobufs::Transformation::TransformationCase::kAddTypeBoolean: 191 return MakeUnique<TransformationAddTypeBoolean>( 192 message.add_type_boolean()); 193 case protobufs::Transformation::TransformationCase::kAddTypeFloat: 194 return MakeUnique<TransformationAddTypeFloat>(message.add_type_float()); 195 case protobufs::Transformation::TransformationCase::kAddTypeFunction: 196 return MakeUnique<TransformationAddTypeFunction>( 197 message.add_type_function()); 198 case protobufs::Transformation::TransformationCase::kAddTypeInt: 199 return MakeUnique<TransformationAddTypeInt>(message.add_type_int()); 200 case protobufs::Transformation::TransformationCase::kAddTypeMatrix: 201 return MakeUnique<TransformationAddTypeMatrix>(message.add_type_matrix()); 202 case protobufs::Transformation::TransformationCase::kAddTypePointer: 203 return MakeUnique<TransformationAddTypePointer>( 204 message.add_type_pointer()); 205 case protobufs::Transformation::TransformationCase::kAddTypeStruct: 206 return MakeUnique<TransformationAddTypeStruct>(message.add_type_struct()); 207 case protobufs::Transformation::TransformationCase::kAddTypeVector: 208 return MakeUnique<TransformationAddTypeVector>(message.add_type_vector()); 209 case protobufs::Transformation::TransformationCase::kAdjustBranchWeights: 210 return MakeUnique<TransformationAdjustBranchWeights>( 211 message.adjust_branch_weights()); 212 case protobufs::Transformation::TransformationCase::kCompositeConstruct: 213 return MakeUnique<TransformationCompositeConstruct>( 214 message.composite_construct()); 215 case protobufs::Transformation::TransformationCase::kCompositeExtract: 216 return MakeUnique<TransformationCompositeExtract>( 217 message.composite_extract()); 218 case protobufs::Transformation::TransformationCase::kCompositeInsert: 219 return MakeUnique<TransformationCompositeInsert>( 220 message.composite_insert()); 221 case protobufs::Transformation::TransformationCase:: 222 kComputeDataSynonymFactClosure: 223 return MakeUnique<TransformationComputeDataSynonymFactClosure>( 224 message.compute_data_synonym_fact_closure()); 225 case protobufs::Transformation::TransformationCase:: 226 kDuplicateRegionWithSelection: 227 return MakeUnique<TransformationDuplicateRegionWithSelection>( 228 message.duplicate_region_with_selection()); 229 case protobufs::Transformation::TransformationCase::kEquationInstruction: 230 return MakeUnique<TransformationEquationInstruction>( 231 message.equation_instruction()); 232 case protobufs::Transformation::TransformationCase::kExpandVectorReduction: 233 return MakeUnique<TransformationExpandVectorReduction>( 234 message.expand_vector_reduction()); 235 case protobufs::Transformation::TransformationCase:: 236 kFlattenConditionalBranch: 237 return MakeUnique<TransformationFlattenConditionalBranch>( 238 message.flatten_conditional_branch()); 239 case protobufs::Transformation::TransformationCase::kFunctionCall: 240 return MakeUnique<TransformationFunctionCall>(message.function_call()); 241 case protobufs::Transformation::TransformationCase::kInlineFunction: 242 return MakeUnique<TransformationInlineFunction>( 243 message.inline_function()); 244 case protobufs::Transformation::TransformationCase:: 245 kInvertComparisonOperator: 246 return MakeUnique<TransformationInvertComparisonOperator>( 247 message.invert_comparison_operator()); 248 case protobufs::Transformation::TransformationCase::kLoad: 249 return MakeUnique<TransformationLoad>(message.load()); 250 case protobufs::Transformation::TransformationCase:: 251 kMakeVectorOperationDynamic: 252 return MakeUnique<TransformationMakeVectorOperationDynamic>( 253 message.make_vector_operation_dynamic()); 254 case protobufs::Transformation::TransformationCase::kMergeBlocks: 255 return MakeUnique<TransformationMergeBlocks>(message.merge_blocks()); 256 case protobufs::Transformation::TransformationCase::kMergeFunctionReturns: 257 return MakeUnique<TransformationMergeFunctionReturns>( 258 message.merge_function_returns()); 259 case protobufs::Transformation::TransformationCase::kMoveBlockDown: 260 return MakeUnique<TransformationMoveBlockDown>(message.move_block_down()); 261 case protobufs::Transformation::TransformationCase::kMoveInstructionDown: 262 return MakeUnique<TransformationMoveInstructionDown>( 263 message.move_instruction_down()); 264 case protobufs::Transformation::TransformationCase::kMutatePointer: 265 return MakeUnique<TransformationMutatePointer>(message.mutate_pointer()); 266 case protobufs::Transformation::TransformationCase::kOutlineFunction: 267 return MakeUnique<TransformationOutlineFunction>( 268 message.outline_function()); 269 case protobufs::Transformation::TransformationCase:: 270 kPermuteFunctionParameters: 271 return MakeUnique<TransformationPermuteFunctionParameters>( 272 message.permute_function_parameters()); 273 case protobufs::Transformation::TransformationCase::kPermutePhiOperands: 274 return MakeUnique<TransformationPermutePhiOperands>( 275 message.permute_phi_operands()); 276 case protobufs::Transformation::TransformationCase:: 277 kPropagateInstructionDown: 278 return MakeUnique<TransformationPropagateInstructionDown>( 279 message.propagate_instruction_down()); 280 case protobufs::Transformation::TransformationCase::kPropagateInstructionUp: 281 return MakeUnique<TransformationPropagateInstructionUp>( 282 message.propagate_instruction_up()); 283 case protobufs::Transformation::TransformationCase::kPushIdThroughVariable: 284 return MakeUnique<TransformationPushIdThroughVariable>( 285 message.push_id_through_variable()); 286 case protobufs::Transformation::TransformationCase:: 287 kRecordSynonymousConstants: 288 return MakeUnique<TransformationRecordSynonymousConstants>( 289 message.record_synonymous_constants()); 290 case protobufs::Transformation::TransformationCase:: 291 kReplaceAddSubMulWithCarryingExtended: 292 return MakeUnique<TransformationReplaceAddSubMulWithCarryingExtended>( 293 message.replace_add_sub_mul_with_carrying_extended()); 294 case protobufs::Transformation::TransformationCase:: 295 kReplaceBooleanConstantWithConstantBinary: 296 return MakeUnique<TransformationReplaceBooleanConstantWithConstantBinary>( 297 message.replace_boolean_constant_with_constant_binary()); 298 case protobufs::Transformation::TransformationCase:: 299 kReplaceBranchFromDeadBlockWithExit: 300 return MakeUnique<TransformationReplaceBranchFromDeadBlockWithExit>( 301 message.replace_branch_from_dead_block_with_exit()); 302 case protobufs::Transformation::TransformationCase:: 303 kReplaceConstantWithUniform: 304 return MakeUnique<TransformationReplaceConstantWithUniform>( 305 message.replace_constant_with_uniform()); 306 case protobufs::Transformation::TransformationCase:: 307 kReplaceCopyMemoryWithLoadStore: 308 return MakeUnique<TransformationReplaceCopyMemoryWithLoadStore>( 309 message.replace_copy_memory_with_load_store()); 310 case protobufs::Transformation::TransformationCase:: 311 kReplaceCopyObjectWithStoreLoad: 312 return MakeUnique<TransformationReplaceCopyObjectWithStoreLoad>( 313 message.replace_copy_object_with_store_load()); 314 case protobufs::Transformation::TransformationCase::kReplaceIdWithSynonym: 315 return MakeUnique<TransformationReplaceIdWithSynonym>( 316 message.replace_id_with_synonym()); 317 case protobufs::Transformation::TransformationCase::kReplaceIrrelevantId: 318 return MakeUnique<TransformationReplaceIrrelevantId>( 319 message.replace_irrelevant_id()); 320 case protobufs::Transformation::TransformationCase:: 321 kReplaceLinearAlgebraInstruction: 322 return MakeUnique<TransformationReplaceLinearAlgebraInstruction>( 323 message.replace_linear_algebra_instruction()); 324 case protobufs::Transformation::TransformationCase:: 325 kReplaceLoadStoreWithCopyMemory: 326 return MakeUnique<TransformationReplaceLoadStoreWithCopyMemory>( 327 message.replace_load_store_with_copy_memory()); 328 case protobufs::Transformation::TransformationCase:: 329 kReplaceOpselectWithConditionalBranch: 330 return MakeUnique<TransformationReplaceOpSelectWithConditionalBranch>( 331 message.replace_opselect_with_conditional_branch()); 332 case protobufs::Transformation::TransformationCase:: 333 kReplaceParameterWithGlobal: 334 return MakeUnique<TransformationReplaceParameterWithGlobal>( 335 message.replace_parameter_with_global()); 336 case protobufs::Transformation::TransformationCase:: 337 kReplaceParamsWithStruct: 338 return MakeUnique<TransformationReplaceParamsWithStruct>( 339 message.replace_params_with_struct()); 340 case protobufs::Transformation::TransformationCase:: 341 kReplaceOpphiIdFromDeadPredecessor: 342 return MakeUnique<TransformationReplaceOpPhiIdFromDeadPredecessor>( 343 message.replace_opphi_id_from_dead_predecessor()); 344 case protobufs::Transformation::TransformationCase::kSetFunctionControl: 345 return MakeUnique<TransformationSetFunctionControl>( 346 message.set_function_control()); 347 case protobufs::Transformation::TransformationCase::kSetLoopControl: 348 return MakeUnique<TransformationSetLoopControl>( 349 message.set_loop_control()); 350 case protobufs::Transformation::TransformationCase::kSetMemoryOperandsMask: 351 return MakeUnique<TransformationSetMemoryOperandsMask>( 352 message.set_memory_operands_mask()); 353 case protobufs::Transformation::TransformationCase::kSetSelectionControl: 354 return MakeUnique<TransformationSetSelectionControl>( 355 message.set_selection_control()); 356 case protobufs::Transformation::TransformationCase::kSplitBlock: 357 return MakeUnique<TransformationSplitBlock>(message.split_block()); 358 case protobufs::Transformation::TransformationCase::kStore: 359 return MakeUnique<TransformationStore>(message.store()); 360 case protobufs::Transformation::TransformationCase::kSwapCommutableOperands: 361 return MakeUnique<TransformationSwapCommutableOperands>( 362 message.swap_commutable_operands()); 363 case protobufs::Transformation::TransformationCase:: 364 kSwapConditionalBranchOperands: 365 return MakeUnique<TransformationSwapConditionalBranchOperands>( 366 message.swap_conditional_branch_operands()); 367 case protobufs::Transformation::TransformationCase::kSwapFunctionVariables: 368 return MakeUnique<TransformationSwapFunctionVariables>( 369 message.swap_function_variables()); 370 case protobufs::Transformation::TransformationCase::kSwapTwoFunctions: 371 return MakeUnique<TransformationSwapTwoFunctions>( 372 message.swap_two_functions()); 373 case protobufs::Transformation::TransformationCase:: 374 kToggleAccessChainInstruction: 375 return MakeUnique<TransformationToggleAccessChainInstruction>( 376 message.toggle_access_chain_instruction()); 377 case protobufs::Transformation::TransformationCase::kVectorShuffle: 378 return MakeUnique<TransformationVectorShuffle>(message.vector_shuffle()); 379 case protobufs::Transformation::TransformationCase:: 380 kWrapEarlyTerminatorInFunction: 381 return MakeUnique<TransformationWrapEarlyTerminatorInFunction>( 382 message.wrap_early_terminator_in_function()); 383 case protobufs::Transformation::TransformationCase::kWrapRegionInSelection: 384 return MakeUnique<TransformationWrapRegionInSelection>( 385 message.wrap_region_in_selection()); 386 case protobufs::Transformation::TransformationCase::kWrapVectorSynonym: 387 return MakeUnique<TransformationWrapVectorSynonym>( 388 message.wrap_vector_synonym()); 389 case protobufs::Transformation::TRANSFORMATION_NOT_SET: 390 assert(false && "An unset transformation was encountered."); 391 return nullptr; 392 } 393 assert(false && "Should be unreachable as all cases must be handled above."); 394 return nullptr; 395 } 396 CheckIdIsFreshAndNotUsedByThisTransformation(uint32_t id,opt::IRContext * ir_context,std::set<uint32_t> * ids_used_by_this_transformation)397bool Transformation::CheckIdIsFreshAndNotUsedByThisTransformation( 398 uint32_t id, opt::IRContext* ir_context, 399 std::set<uint32_t>* ids_used_by_this_transformation) { 400 if (!fuzzerutil::IsFreshId(ir_context, id)) { 401 return false; 402 } 403 if (ids_used_by_this_transformation->count(id) != 0) { 404 return false; 405 } 406 ids_used_by_this_transformation->insert(id); 407 return true; 408 } 409 410 } // namespace fuzz 411 } // namespace spvtools 412