diff options
Diffstat (limited to 'source/fuzz/fuzzer_pass_add_stores.cpp')
-rw-r--r-- | source/fuzz/fuzzer_pass_add_stores.cpp | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/source/fuzz/fuzzer_pass_add_stores.cpp b/source/fuzz/fuzzer_pass_add_stores.cpp index f89428d3..606e4a63 100644 --- a/source/fuzz/fuzzer_pass_add_stores.cpp +++ b/source/fuzz/fuzzer_pass_add_stores.cpp @@ -23,9 +23,10 @@ namespace fuzz { FuzzerPassAddStores::FuzzerPassAddStores( opt::IRContext* ir_context, TransformationContext* transformation_context, FuzzerContext* fuzzer_context, - protobufs::TransformationSequence* transformations) + protobufs::TransformationSequence* transformations, + bool ignore_inapplicable_transformations) : FuzzerPass(ir_context, transformation_context, fuzzer_context, - transformations) {} + transformations, ignore_inapplicable_transformations) {} void FuzzerPassAddStores::Apply() { ForEachInstructionWithInstructionDescriptor( @@ -38,16 +39,20 @@ void FuzzerPassAddStores::Apply() { "The opcode of the instruction we might insert before must be " "the same as the opcode in the descriptor for the instruction"); + // Randomly decide whether to try inserting a store here. + if (!GetFuzzerContext()->ChoosePercentage( + GetFuzzerContext()->GetChanceOfAddingStore())) { + return; + } + // Check whether it is legitimate to insert a store before this // instruction. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpStore, inst_it)) { return; } - - // Randomly decide whether to try inserting a store here. - if (!GetFuzzerContext()->ChoosePercentage( - GetFuzzerContext()->GetChanceOfAddingStore())) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAtomicStore, + inst_it)) { return; } @@ -116,10 +121,49 @@ void FuzzerPassAddStores::Apply() { return; } - // Choose a value at random, and create and apply a storing - // transformation based on it and the pointer. + bool is_atomic_store = false; + uint32_t memory_scope_id = 0; + uint32_t memory_semantics_id = 0; + + auto storage_class = + static_cast<SpvStorageClass>(GetIRContext() + ->get_def_use_mgr() + ->GetDef(pointer->type_id()) + ->GetSingleWordInOperand(0)); + + switch (storage_class) { + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassWorkgroup: + case SpvStorageClassCrossWorkgroup: + case SpvStorageClassAtomicCounter: + case SpvStorageClassImage: + if (GetFuzzerContext()->ChoosePercentage( + GetFuzzerContext()->GetChanceOfAddingAtomicStore())) { + is_atomic_store = true; + + memory_scope_id = FindOrCreateConstant( + {SpvScopeInvocation}, + FindOrCreateIntegerType(32, GetFuzzerContext()->ChooseEven()), + false); + + memory_semantics_id = FindOrCreateConstant( + {static_cast<uint32_t>( + fuzzerutil::GetMemorySemanticsForStorageClass( + storage_class))}, + FindOrCreateIntegerType(32, GetFuzzerContext()->ChooseEven()), + false); + } + break; + + default: + break; + } + + // Create and apply the transformation. ApplyTransformation(TransformationStore( - pointer->result_id(), + pointer->result_id(), is_atomic_store, memory_scope_id, + memory_semantics_id, relevant_values[GetFuzzerContext()->RandomIndex(relevant_values)] ->result_id(), instruction_descriptor)); |