1 // Copyright (c) 2020 Google LLC 2 // 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 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 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. 14 15 #include "source/fuzz/transformation_add_relaxed_decoration.h" 16 17 #include "source/fuzz/fuzzer_util.h" 18 19 namespace spvtools { 20 namespace fuzz { 21 TransformationAddRelaxedDecoration(protobufs::TransformationAddRelaxedDecoration message)22TransformationAddRelaxedDecoration::TransformationAddRelaxedDecoration( 23 protobufs::TransformationAddRelaxedDecoration message) 24 : message_(std::move(message)) {} 25 TransformationAddRelaxedDecoration(uint32_t result_id)26TransformationAddRelaxedDecoration::TransformationAddRelaxedDecoration( 27 uint32_t result_id) { 28 message_.set_result_id(result_id); 29 } 30 IsApplicable(opt::IRContext * ir_context,const TransformationContext & transformation_context) const31bool TransformationAddRelaxedDecoration::IsApplicable( 32 opt::IRContext* ir_context, 33 const TransformationContext& transformation_context) const { 34 // |message_.result_id| must be the id of an instruction. 35 auto instr = ir_context->get_def_use_mgr()->GetDef(message_.result_id()); 36 if (!instr) { 37 return false; 38 } 39 opt::BasicBlock* cur_block = ir_context->get_instr_block(instr); 40 // The instruction must have a block. 41 if (cur_block == nullptr) { 42 return false; 43 } 44 // |cur_block| must be a dead block. 45 if (!(transformation_context.GetFactManager()->BlockIsDead( 46 cur_block->id()))) { 47 return false; 48 } 49 // The instruction must be numeric. 50 return IsNumeric(instr->opcode()); 51 } 52 Apply(opt::IRContext * ir_context,TransformationContext *) const53void TransformationAddRelaxedDecoration::Apply( 54 opt::IRContext* ir_context, TransformationContext* /*unused*/) const { 55 // Add a RelaxedPrecision decoration targeting |message_.result_id|. 56 ir_context->get_decoration_mgr()->AddDecoration( 57 message_.result_id(), SpvDecorationRelaxedPrecision); 58 } 59 ToMessage() const60protobufs::Transformation TransformationAddRelaxedDecoration::ToMessage() 61 const { 62 protobufs::Transformation result; 63 *result.mutable_add_relaxed_decoration() = message_; 64 return result; 65 } 66 IsNumeric(uint32_t opcode)67bool TransformationAddRelaxedDecoration::IsNumeric(uint32_t opcode) { 68 switch (opcode) { 69 case SpvOpConvertFToU: 70 case SpvOpConvertFToS: 71 case SpvOpConvertSToF: 72 case SpvOpConvertUToF: 73 case SpvOpUConvert: 74 case SpvOpSConvert: 75 case SpvOpFConvert: 76 case SpvOpConvertPtrToU: 77 case SpvOpSatConvertSToU: 78 case SpvOpSatConvertUToS: 79 case SpvOpVectorExtractDynamic: 80 case SpvOpVectorInsertDynamic: 81 case SpvOpVectorShuffle: 82 case SpvOpTranspose: 83 case SpvOpSNegate: 84 case SpvOpFNegate: 85 case SpvOpIAdd: 86 case SpvOpFAdd: 87 case SpvOpISub: 88 case SpvOpFSub: 89 case SpvOpIMul: 90 case SpvOpFMul: 91 case SpvOpUDiv: 92 case SpvOpSDiv: 93 case SpvOpFDiv: 94 case SpvOpUMod: 95 case SpvOpSRem: 96 case SpvOpSMod: 97 case SpvOpFRem: 98 case SpvOpFMod: 99 case SpvOpVectorTimesScalar: 100 case SpvOpMatrixTimesScalar: 101 case SpvOpVectorTimesMatrix: 102 case SpvOpMatrixTimesVector: 103 case SpvOpMatrixTimesMatrix: 104 case SpvOpOuterProduct: 105 case SpvOpDot: 106 case SpvOpIAddCarry: 107 case SpvOpISubBorrow: 108 case SpvOpUMulExtended: 109 case SpvOpSMulExtended: 110 case SpvOpShiftRightLogical: 111 case SpvOpShiftRightArithmetic: 112 case SpvOpShiftLeftLogical: 113 case SpvOpBitwiseOr: 114 case SpvOpBitwiseXor: 115 case SpvOpBitwiseAnd: 116 case SpvOpNot: 117 case SpvOpBitFieldInsert: 118 case SpvOpBitFieldSExtract: 119 case SpvOpBitFieldUExtract: 120 case SpvOpBitReverse: 121 case SpvOpBitCount: 122 case SpvOpAtomicLoad: 123 case SpvOpAtomicStore: 124 case SpvOpAtomicExchange: 125 case SpvOpAtomicCompareExchange: 126 case SpvOpAtomicCompareExchangeWeak: 127 case SpvOpAtomicIIncrement: 128 case SpvOpAtomicIDecrement: 129 case SpvOpAtomicIAdd: 130 case SpvOpAtomicISub: 131 case SpvOpAtomicSMin: 132 case SpvOpAtomicUMin: 133 case SpvOpAtomicSMax: 134 case SpvOpAtomicUMax: 135 case SpvOpAtomicAnd: 136 case SpvOpAtomicOr: 137 case SpvOpAtomicXor: 138 return true; 139 default: 140 return false; 141 } 142 } 143 GetFreshIds() const144std::unordered_set<uint32_t> TransformationAddRelaxedDecoration::GetFreshIds() 145 const { 146 return std::unordered_set<uint32_t>(); 147 } 148 149 } // namespace fuzz 150 } // namespace spvtools