| 30 | transformations, ignore_inapplicable_transformations) {} |
| 31 | |
| 32 | void FuzzerPassWrapVectorSynonym::Apply() { |
| 33 | ForEachInstructionWithInstructionDescriptor( |
| 34 | [this](opt::Function* /*unused*/, opt::BasicBlock* /*unused*/, |
| 35 | opt::BasicBlock::iterator instruction_iterator, |
| 36 | const protobufs::InstructionDescriptor& instruction_descriptor) |
| 37 | -> void { |
| 38 | |
| 39 | // Randomly decide whether to wrap it to a vector operation. |
| 40 | if (!GetFuzzerContext()->ChoosePercentage( |
| 41 | GetFuzzerContext()->GetChanceOfWrappingVectorSynonym())) { |
| 42 | return; |
| 43 | } |
| 44 | |
| 45 | // The transformation is not applicable if the instruction has missing |
| 46 | // result id, type id, or is not supported type. |
| 47 | if (!TransformationWrapVectorSynonym::IsInstructionSupported( |
| 48 | GetIRContext(), *instruction_iterator)) { |
| 49 | return; |
| 50 | } |
| 51 | |
| 52 | // It must be valid to insert an OpCompositeConstruct instruction |
| 53 | // before |instruction_iterator|. |
| 54 | if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( |
| 55 | spv::Op::OpCompositeConstruct, instruction_iterator)) { |
| 56 | return; |
| 57 | } |
| 58 | |
| 59 | // Get the scalar operands from the original instruction. |
| 60 | opt::Instruction* operand1 = GetIRContext()->get_def_use_mgr()->GetDef( |
| 61 | instruction_iterator->GetSingleWordInOperand(0)); |
| 62 | opt::Instruction* operand2 = GetIRContext()->get_def_use_mgr()->GetDef( |
| 63 | instruction_iterator->GetSingleWordInOperand(1)); |
| 64 | |
| 65 | // We need to be able to make a synonym of the scalar operation's result |
| 66 | // id, as well as the operand ids (for example, they cannot be |
| 67 | // irrelevant). |
| 68 | if (!fuzzerutil::CanMakeSynonymOf(GetIRContext(), |
| 69 | *GetTransformationContext(), |
| 70 | *instruction_iterator)) { |
| 71 | return; |
| 72 | } |
| 73 | if (!fuzzerutil::CanMakeSynonymOf( |
| 74 | GetIRContext(), *GetTransformationContext(), *operand1)) { |
| 75 | return; |
| 76 | } |
| 77 | if (!fuzzerutil::CanMakeSynonymOf( |
| 78 | GetIRContext(), *GetTransformationContext(), *operand2)) { |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | // Get a random vector size from 2 to 4. |
| 83 | uint32_t vector_size = GetFuzzerContext()->GetWidthOfWrappingVector(); |
| 84 | |
| 85 | // Randomly choose a position that target ids should be placed at. |
| 86 | // The position is in range [0, n - 1], where n is the size of the |
| 87 | // vector. |
| 88 | uint32_t position = |
| 89 | GetFuzzerContext()->GetRandomIndexForWrappingVector(vector_size); |
nothing calls this directly
no test coverage detected