1 // Copyright (c) 2020 André Perez Maselco
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "source/fuzz/transformation_add_image_sample_unused_components.h"
17 #include "source/fuzz/fuzzer_util.h"
18 #include "source/fuzz/instruction_descriptor.h"
23 TransformationAddImageSampleUnusedComponents::
24 TransformationAddImageSampleUnusedComponents(
25 protobufs::TransformationAddImageSampleUnusedComponents message
)
26 : message_(std::move(message
)) {}
28 TransformationAddImageSampleUnusedComponents::
29 TransformationAddImageSampleUnusedComponents(
30 uint32_t coordinate_with_unused_components_id
,
31 const protobufs::InstructionDescriptor
& instruction_descriptor
) {
32 message_
.set_coordinate_with_unused_components_id(
33 coordinate_with_unused_components_id
);
34 *message_
.mutable_instruction_descriptor() = instruction_descriptor
;
37 bool TransformationAddImageSampleUnusedComponents::IsApplicable(
38 opt::IRContext
* ir_context
, const TransformationContext
& /*unused*/) const {
39 auto image_sample_instruction
=
40 FindInstruction(message_
.instruction_descriptor(), ir_context
);
42 // The image sample instruction must be defined.
43 if (image_sample_instruction
== nullptr) {
47 // The instruction must be an image sample instruction.
48 if (!spvOpcodeIsImageSample(image_sample_instruction
->opcode())) {
52 uint32_t coordinate_id
= image_sample_instruction
->GetSingleWordInOperand(1);
53 auto coordinate_instruction
=
54 ir_context
->get_def_use_mgr()->GetDef(coordinate_id
);
55 auto coordinate_type
=
56 ir_context
->get_type_mgr()->GetType(coordinate_instruction
->type_id());
58 // It must be possible to add unused components.
59 if (coordinate_type
->AsVector() &&
60 coordinate_type
->AsVector()->element_count() == 4) {
64 auto coordinate_with_unused_components_instruction
=
65 ir_context
->get_def_use_mgr()->GetDef(
66 message_
.coordinate_with_unused_components_id());
68 // The coordinate with unused components instruction must be defined.
69 if (coordinate_with_unused_components_instruction
== nullptr) {
73 // It must be an OpCompositeConstruct instruction such that it can be checked
74 // that the original components are present.
75 if (coordinate_with_unused_components_instruction
->opcode() !=
76 spv::Op::OpCompositeConstruct
) {
80 // The first constituent must be the original coordinate.
81 if (coordinate_with_unused_components_instruction
->GetSingleWordInOperand(
82 0) != coordinate_id
) {
86 auto coordinate_with_unused_components_type
=
87 ir_context
->get_type_mgr()->GetType(
88 coordinate_with_unused_components_instruction
->type_id());
90 // |coordinate_with_unused_components_type| must be a vector.
91 if (!coordinate_with_unused_components_type
->AsVector()) {
98 void TransformationAddImageSampleUnusedComponents::Apply(
99 opt::IRContext
* ir_context
, TransformationContext
* /*unused*/) const {
100 // Sets the coordinate operand.
101 auto image_sample_instruction
=
102 FindInstruction(message_
.instruction_descriptor(), ir_context
);
103 image_sample_instruction
->SetInOperand(
104 1, {message_
.coordinate_with_unused_components_id()});
105 ir_context
->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone
);
108 protobufs::Transformation
109 TransformationAddImageSampleUnusedComponents::ToMessage() const {
110 protobufs::Transformation result
;
111 *result
.mutable_add_image_sample_unused_components() = message_
;
115 std::unordered_set
<uint32_t>
116 TransformationAddImageSampleUnusedComponents::GetFreshIds() const {
117 return std::unordered_set
<uint32_t>();
121 } // namespace spvtools