mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
parent
f9b088fe0d
commit
7e75fea9ec
@ -98,7 +98,7 @@ void FuzzerPassReplaceParamsWithStruct::Apply() {
|
||||
parameter_id.push_back(params[index]->result_id());
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, uint32_t> caller_id_to_fresh_id;
|
||||
std::map<uint32_t, uint32_t> caller_id_to_fresh_id;
|
||||
for (const auto* inst :
|
||||
fuzzerutil::GetCallers(GetIRContext(), function.result_id())) {
|
||||
caller_id_to_fresh_id[inst->result_id()] =
|
||||
|
@ -1273,6 +1273,31 @@ bool TypesAreEqualUpToSign(opt::IRContext* ir_context, uint32_t type1_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<uint32_t, uint32_t> RepeatedUInt32PairToMap(
|
||||
const google::protobuf::RepeatedPtrField<protobufs::UInt32Pair>& data) {
|
||||
std::map<uint32_t, uint32_t> result;
|
||||
|
||||
for (const auto& entry : data) {
|
||||
result[entry.first()] = entry.second();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
google::protobuf::RepeatedPtrField<protobufs::UInt32Pair>
|
||||
MapToRepeatedUInt32Pair(const std::map<uint32_t, uint32_t>& data) {
|
||||
google::protobuf::RepeatedPtrField<protobufs::UInt32Pair> result;
|
||||
|
||||
for (const auto& entry : data) {
|
||||
protobufs::UInt32Pair pair;
|
||||
pair.set_first(entry.first);
|
||||
pair.set_second(entry.second);
|
||||
*result.Add() = std::move(pair);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace fuzzerutil
|
||||
|
||||
} // namespace fuzz
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef SOURCE_FUZZ_FUZZER_UTIL_H_
|
||||
#define SOURCE_FUZZ_FUZZER_UTIL_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
@ -463,6 +464,16 @@ inline uint32_t FloatToWord(float value) {
|
||||
bool TypesAreEqualUpToSign(opt::IRContext* ir_context, uint32_t type1_id,
|
||||
uint32_t type2_id);
|
||||
|
||||
// Converts repeated field of UInt32Pair to a map. If two or more equal values
|
||||
// of |UInt32Pair::first()| are available in |data|, the last value of
|
||||
// |UInt32Pair::second()| is used.
|
||||
std::map<uint32_t, uint32_t> RepeatedUInt32PairToMap(
|
||||
const google::protobuf::RepeatedPtrField<protobufs::UInt32Pair>& data);
|
||||
|
||||
// Converts a map into a repeated field of UInt32Pair.
|
||||
google::protobuf::RepeatedPtrField<protobufs::UInt32Pair>
|
||||
MapToRepeatedUInt32Pair(const std::map<uint32_t, uint32_t>& data);
|
||||
|
||||
} // namespace fuzzerutil
|
||||
|
||||
} // namespace fuzz
|
||||
|
@ -1389,12 +1389,9 @@ message TransformationReplaceParamsWithStruct {
|
||||
uint32 fresh_parameter_id = 3;
|
||||
|
||||
// Fresh ids for struct objects containing values of replaced parameters.
|
||||
// This map contains a fresh id for at least every result id of a relevant
|
||||
// This field contains a fresh id for at least every result id of a relevant
|
||||
// OpFunctionCall instruction.
|
||||
//
|
||||
// While maps are not fully deterministic, the way this map is used does not
|
||||
// exhibit nondeterminism. Change to repeated Uint32Pair if this changes.
|
||||
map<uint32, uint32> caller_id_to_fresh_composite_id = 4;
|
||||
repeated UInt32Pair caller_id_to_fresh_composite_id = 4;
|
||||
|
||||
}
|
||||
|
||||
|
@ -21,20 +21,6 @@
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
namespace {
|
||||
|
||||
std::map<uint32_t, uint32_t> PairSequenceToMap(
|
||||
const google::protobuf::RepeatedPtrField<protobufs::UInt32Pair>&
|
||||
pair_sequence) {
|
||||
std::map<uint32_t, uint32_t> result;
|
||||
for (auto& pair : pair_sequence) {
|
||||
result[pair.first()] = pair.second();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TransformationOutlineFunction::TransformationOutlineFunction(
|
||||
const spvtools::fuzz::protobufs::TransformationOutlineFunction& message)
|
||||
: message_(message) {}
|
||||
@ -55,18 +41,10 @@ TransformationOutlineFunction::TransformationOutlineFunction(
|
||||
message_.set_new_function_region_entry_block(new_function_region_entry_block);
|
||||
message_.set_new_caller_result_id(new_caller_result_id);
|
||||
message_.set_new_callee_result_id(new_callee_result_id);
|
||||
for (auto& entry : input_id_to_fresh_id) {
|
||||
protobufs::UInt32Pair pair;
|
||||
pair.set_first(entry.first);
|
||||
pair.set_second(entry.second);
|
||||
*message_.add_input_id_to_fresh_id() = pair;
|
||||
}
|
||||
for (auto& entry : output_id_to_fresh_id) {
|
||||
protobufs::UInt32Pair pair;
|
||||
pair.set_first(entry.first);
|
||||
pair.set_second(entry.second);
|
||||
*message_.add_output_id_to_fresh_id() = pair;
|
||||
}
|
||||
*message_.mutable_input_id_to_fresh_id() =
|
||||
fuzzerutil::MapToRepeatedUInt32Pair(input_id_to_fresh_id);
|
||||
*message_.mutable_output_id_to_fresh_id() =
|
||||
fuzzerutil::MapToRepeatedUInt32Pair(output_id_to_fresh_id);
|
||||
}
|
||||
|
||||
bool TransformationOutlineFunction::IsApplicable(
|
||||
@ -252,8 +230,8 @@ bool TransformationOutlineFunction::IsApplicable(
|
||||
|
||||
// For each region input id, i.e. every id defined outside the region but
|
||||
// used inside the region, ...
|
||||
std::map<uint32_t, uint32_t> input_id_to_fresh_id_map =
|
||||
PairSequenceToMap(message_.input_id_to_fresh_id());
|
||||
auto input_id_to_fresh_id_map =
|
||||
fuzzerutil::RepeatedUInt32PairToMap(message_.input_id_to_fresh_id());
|
||||
for (auto id : GetRegionInputIds(ir_context, region_set, exit_block)) {
|
||||
// There needs to be a corresponding fresh id to be used as a function
|
||||
// parameter.
|
||||
@ -280,8 +258,8 @@ bool TransformationOutlineFunction::IsApplicable(
|
||||
|
||||
// For each region output id -- i.e. every id defined inside the region but
|
||||
// used outside the region, ...
|
||||
std::map<uint32_t, uint32_t> output_id_to_fresh_id_map =
|
||||
PairSequenceToMap(message_.output_id_to_fresh_id());
|
||||
auto output_id_to_fresh_id_map =
|
||||
fuzzerutil::RepeatedUInt32PairToMap(message_.output_id_to_fresh_id());
|
||||
for (auto id : GetRegionOutputIds(ir_context, region_set, exit_block)) {
|
||||
if (
|
||||
// ... there needs to be a corresponding fresh id that can hold the
|
||||
@ -323,10 +301,10 @@ void TransformationOutlineFunction::Apply(
|
||||
GetRegionOutputIds(ir_context, region_blocks, original_region_exit_block);
|
||||
|
||||
// Maps from input and output ids to fresh ids.
|
||||
std::map<uint32_t, uint32_t> input_id_to_fresh_id_map =
|
||||
PairSequenceToMap(message_.input_id_to_fresh_id());
|
||||
std::map<uint32_t, uint32_t> output_id_to_fresh_id_map =
|
||||
PairSequenceToMap(message_.output_id_to_fresh_id());
|
||||
auto input_id_to_fresh_id_map =
|
||||
fuzzerutil::RepeatedUInt32PairToMap(message_.input_id_to_fresh_id());
|
||||
auto output_id_to_fresh_id_map =
|
||||
fuzzerutil::RepeatedUInt32PairToMap(message_.output_id_to_fresh_id());
|
||||
|
||||
UpdateModuleIdBoundForFreshIds(ir_context, input_id_to_fresh_id_map,
|
||||
output_id_to_fresh_id_map);
|
||||
|
@ -28,8 +28,7 @@ TransformationReplaceParamsWithStruct::TransformationReplaceParamsWithStruct(
|
||||
TransformationReplaceParamsWithStruct::TransformationReplaceParamsWithStruct(
|
||||
const std::vector<uint32_t>& parameter_id, uint32_t fresh_function_type_id,
|
||||
uint32_t fresh_parameter_id,
|
||||
const std::unordered_map<uint32_t, uint32_t>&
|
||||
caller_id_to_fresh_composite_id) {
|
||||
const std::map<uint32_t, uint32_t>& caller_id_to_fresh_composite_id) {
|
||||
message_.set_fresh_function_type_id(fresh_function_type_id);
|
||||
message_.set_fresh_parameter_id(fresh_parameter_id);
|
||||
|
||||
@ -37,9 +36,8 @@ TransformationReplaceParamsWithStruct::TransformationReplaceParamsWithStruct(
|
||||
message_.add_parameter_id(id);
|
||||
}
|
||||
|
||||
message_.mutable_caller_id_to_fresh_composite_id()->insert(
|
||||
caller_id_to_fresh_composite_id.begin(),
|
||||
caller_id_to_fresh_composite_id.end());
|
||||
*message_.mutable_caller_id_to_fresh_composite_id() =
|
||||
fuzzerutil::MapToRepeatedUInt32Pair(caller_id_to_fresh_composite_id);
|
||||
}
|
||||
|
||||
bool TransformationReplaceParamsWithStruct::IsApplicable(
|
||||
@ -103,13 +101,15 @@ bool TransformationReplaceParamsWithStruct::IsApplicable(
|
||||
return false;
|
||||
}
|
||||
|
||||
auto caller_id_to_fresh_composite_id = fuzzerutil::RepeatedUInt32PairToMap(
|
||||
message_.caller_id_to_fresh_composite_id());
|
||||
|
||||
// Check that |callee_id_to_fresh_composite_id| is valid.
|
||||
for (const auto* inst :
|
||||
fuzzerutil::GetCallers(ir_context, function->result_id())) {
|
||||
// Check that the callee is present in the map. It's ok if the map contains
|
||||
// more ids that there are callees (those ids will not be used).
|
||||
if (!message_.caller_id_to_fresh_composite_id().contains(
|
||||
inst->result_id())) {
|
||||
if (!caller_id_to_fresh_composite_id.count(inst->result_id())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ bool TransformationReplaceParamsWithStruct::IsApplicable(
|
||||
std::vector<uint32_t> fresh_ids = {message_.fresh_function_type_id(),
|
||||
message_.fresh_parameter_id()};
|
||||
|
||||
for (const auto& entry : message_.caller_id_to_fresh_composite_id()) {
|
||||
for (const auto& entry : caller_id_to_fresh_composite_id) {
|
||||
fresh_ids.push_back(entry.second);
|
||||
}
|
||||
|
||||
@ -167,6 +167,9 @@ void TransformationReplaceParamsWithStruct::Apply(
|
||||
}
|
||||
}
|
||||
|
||||
auto caller_id_to_fresh_composite_id = fuzzerutil::RepeatedUInt32PairToMap(
|
||||
message_.caller_id_to_fresh_composite_id());
|
||||
|
||||
// Update all function calls.
|
||||
for (auto* inst : fuzzerutil::GetCallers(ir_context, function->result_id())) {
|
||||
// Create a list of operands for the OpCompositeConstruct instruction.
|
||||
@ -189,7 +192,7 @@ void TransformationReplaceParamsWithStruct::Apply(
|
||||
|
||||
// Insert OpCompositeConstruct before the function call.
|
||||
auto fresh_composite_id =
|
||||
message_.caller_id_to_fresh_composite_id().at(inst->result_id());
|
||||
caller_id_to_fresh_composite_id.at(inst->result_id());
|
||||
inst->InsertBefore(MakeUnique<opt::Instruction>(
|
||||
ir_context, SpvOpCompositeConstruct, struct_type_id, fresh_composite_id,
|
||||
std::move(composite_components)));
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifndef SOURCE_FUZZ_TRANSFORMATION_REPLACE_PARAMS_WITH_STRUCT_H_
|
||||
#define SOURCE_FUZZ_TRANSFORMATION_REPLACE_PARAMS_WITH_STRUCT_H_
|
||||
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||
#include "source/fuzz/transformation.h"
|
||||
@ -33,8 +33,7 @@ class TransformationReplaceParamsWithStruct : public Transformation {
|
||||
TransformationReplaceParamsWithStruct(
|
||||
const std::vector<uint32_t>& parameter_id,
|
||||
uint32_t fresh_function_type_id, uint32_t fresh_parameter_id,
|
||||
const std::unordered_map<uint32_t, uint32_t>&
|
||||
caller_id_to_fresh_composite_id);
|
||||
const std::map<uint32_t, uint32_t>& caller_id_to_fresh_composite_id);
|
||||
|
||||
// - Each element of |parameter_id| is a valid result id of some
|
||||
// OpFunctionParameter instruction. All parameter ids must correspond to
|
||||
|
Loading…
Reference in New Issue
Block a user