42
42
bool TransformationCompositeExtract::IsApplicable(
43
opt::IRContext* context,
44
const spvtools::fuzz::FactManager& /*unused*/) const {
45
if (!fuzzerutil::IsFreshId(context, message_.fresh_id())) {
43
opt::IRContext* ir_context, const TransformationContext& /*unused*/) const {
44
if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) {
48
47
auto instruction_to_insert_before =
49
FindInstruction(message_.instruction_to_insert_before(), context);
48
FindInstruction(message_.instruction_to_insert_before(), ir_context);
50
49
if (!instruction_to_insert_before) {
53
52
auto composite_instruction =
54
context->get_def_use_mgr()->GetDef(message_.composite_id());
53
ir_context->get_def_use_mgr()->GetDef(message_.composite_id());
55
54
if (!composite_instruction) {
58
if (auto block = context->get_instr_block(composite_instruction)) {
57
if (auto block = ir_context->get_instr_block(composite_instruction)) {
59
58
if (composite_instruction == instruction_to_insert_before ||
60
!context->GetDominatorAnalysis(block->GetParent())
59
!ir_context->GetDominatorAnalysis(block->GetParent())
61
60
->Dominates(composite_instruction, instruction_to_insert_before)) {
79
return fuzzerutil::WalkCompositeTypeIndices(
80
context, composite_instruction->type_id(), message_.index()) != 0;
78
return fuzzerutil::WalkCompositeTypeIndices(ir_context,
79
composite_instruction->type_id(),
80
message_.index()) != 0;
83
83
void TransformationCompositeExtract::Apply(
84
opt::IRContext* context, spvtools::fuzz::FactManager* fact_manager) const {
84
opt::IRContext* ir_context,
85
TransformationContext* transformation_context) const {
85
86
opt::Instruction::OperandList extract_operands;
86
87
extract_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.composite_id()}});
87
88
for (auto an_index : message_.index()) {
88
89
extract_operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {an_index}});
90
91
auto composite_instruction =
91
context->get_def_use_mgr()->GetDef(message_.composite_id());
92
ir_context->get_def_use_mgr()->GetDef(message_.composite_id());
92
93
auto extracted_type = fuzzerutil::WalkCompositeTypeIndices(
93
context, composite_instruction->type_id(), message_.index());
94
ir_context, composite_instruction->type_id(), message_.index());
95
FindInstruction(message_.instruction_to_insert_before(), context)
96
FindInstruction(message_.instruction_to_insert_before(), ir_context)
96
97
->InsertBefore(MakeUnique<opt::Instruction>(
97
context, SpvOpCompositeExtract, extracted_type, message_.fresh_id(),
100
fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id());
102
context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone);
98
ir_context, SpvOpCompositeExtract, extracted_type,
99
message_.fresh_id(), extract_operands));
101
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
103
ir_context->InvalidateAnalysesExceptFor(
104
opt::IRContext::Analysis::kAnalysisNone);
104
106
// Add the fact that the id storing the extracted element is synonymous with
105
107
// the index into the structure.
111
113
MakeDataDescriptor(message_.composite_id(), std::move(indices));
112
114
protobufs::DataDescriptor data_descriptor_for_result_id =
113
115
MakeDataDescriptor(message_.fresh_id(), {});
114
fact_manager->AddFactDataSynonym(data_descriptor_for_extracted_element,
115
data_descriptor_for_result_id, context);
116
transformation_context->GetFactManager()->AddFactDataSynonym(
117
data_descriptor_for_extracted_element, data_descriptor_for_result_id,
118
121
protobufs::Transformation TransformationCompositeExtract::ToMessage() const {