| // Copyright (c) 2019 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "source/fuzz/transformation_add_no_contraction_decoration.h" |
| |
| #include "source/fuzz/fuzzer_util.h" |
| |
| namespace spvtools { |
| namespace fuzz { |
| |
| TransformationAddNoContractionDecoration:: |
| TransformationAddNoContractionDecoration( |
| protobufs::TransformationAddNoContractionDecoration message) |
| : message_(std::move(message)) {} |
| |
| TransformationAddNoContractionDecoration:: |
| TransformationAddNoContractionDecoration(uint32_t result_id) { |
| message_.set_result_id(result_id); |
| } |
| |
| bool TransformationAddNoContractionDecoration::IsApplicable( |
| opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { |
| // |message_.result_id| must be the id of an instruction. |
| auto instr = ir_context->get_def_use_mgr()->GetDef(message_.result_id()); |
| if (!instr) { |
| return false; |
| } |
| // The instruction must be arithmetic. |
| return IsArithmetic(instr->opcode()); |
| } |
| |
| void TransformationAddNoContractionDecoration::Apply( |
| opt::IRContext* ir_context, TransformationContext* /*unused*/) const { |
| // Add a NoContraction decoration targeting |message_.result_id|. |
| ir_context->get_decoration_mgr()->AddDecoration(message_.result_id(), |
| SpvDecorationNoContraction); |
| } |
| |
| protobufs::Transformation TransformationAddNoContractionDecoration::ToMessage() |
| const { |
| protobufs::Transformation result; |
| *result.mutable_add_no_contraction_decoration() = message_; |
| return result; |
| } |
| |
| bool TransformationAddNoContractionDecoration::IsArithmetic(uint32_t opcode) { |
| switch (opcode) { |
| case SpvOpSNegate: |
| case SpvOpFNegate: |
| case SpvOpIAdd: |
| case SpvOpFAdd: |
| case SpvOpISub: |
| case SpvOpFSub: |
| case SpvOpIMul: |
| case SpvOpFMul: |
| case SpvOpUDiv: |
| case SpvOpSDiv: |
| case SpvOpFDiv: |
| case SpvOpUMod: |
| case SpvOpSRem: |
| case SpvOpSMod: |
| case SpvOpFRem: |
| case SpvOpFMod: |
| case SpvOpVectorTimesScalar: |
| case SpvOpMatrixTimesScalar: |
| case SpvOpVectorTimesMatrix: |
| case SpvOpMatrixTimesVector: |
| case SpvOpMatrixTimesMatrix: |
| case SpvOpOuterProduct: |
| case SpvOpDot: |
| case SpvOpIAddCarry: |
| case SpvOpISubBorrow: |
| case SpvOpUMulExtended: |
| case SpvOpSMulExtended: |
| case SpvOpAny: |
| case SpvOpAll: |
| case SpvOpIsNan: |
| case SpvOpIsInf: |
| case SpvOpIsFinite: |
| case SpvOpIsNormal: |
| case SpvOpSignBitSet: |
| case SpvOpLessOrGreater: |
| case SpvOpOrdered: |
| case SpvOpUnordered: |
| case SpvOpLogicalEqual: |
| case SpvOpLogicalNotEqual: |
| case SpvOpLogicalOr: |
| case SpvOpLogicalAnd: |
| case SpvOpLogicalNot: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| std::unordered_set<uint32_t> |
| TransformationAddNoContractionDecoration::GetFreshIds() const { |
| return std::unordered_set<uint32_t>(); |
| } |
| |
| } // namespace fuzz |
| } // namespace spvtools |