From 3ffacc75772707766a8c40cfa7b2f30e8e81a588 Mon Sep 17 00:00:00 2001 From: Vasyl Teliman Date: Tue, 11 Aug 2020 20:10:35 +0300 Subject: [PATCH 1/3] Fix type width --- .../fuzzer_pass_add_equation_instructions.cpp | 66 +++++++++++++++---- .../fuzzer_pass_add_equation_instructions.h | 8 +++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp index 9170ada228..3ad398d939 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp @@ -112,20 +112,8 @@ void FuzzerPassAddEquationInstructions::Apply() { return; } case SpvOpBitcast: { - std::vector candidate_instructions; - for (const auto* inst : available_instructions) { - const auto* type = - GetIRContext()->get_type_mgr()->GetType(inst->type_id()); - assert(type && "Instruction has invalid type"); - if ((type->AsVector() && - (type->AsVector()->element_type()->AsInteger() || - type->AsVector()->element_type()->AsFloat())) || - type->AsInteger() || type->AsFloat()) { - // We support OpBitcast for only scalars or vectors of - // numerical type. - candidate_instructions.push_back(inst); - } - } + const auto candidate_instructions = + GetNumericalInstructions(available_instructions); if (!candidate_instructions.empty()) { const auto* operand_inst = @@ -356,5 +344,55 @@ FuzzerPassAddEquationInstructions::RestrictToElementBitWidth( return result; } +std::vector +FuzzerPassAddEquationInstructions::GetNumericalInstructions( + const std::vector& instructions) const { + std::vector result; + + for (auto* inst : instructions) { + const auto* type = GetIRContext()->get_type_mgr()->GetType(inst->type_id()); + assert(type && "Instruction has invalid type"); + + if (const auto* vector_type = type->AsVector()) { + type = vector_type->element_type(); + } + + if (!type->AsInteger() && !type->AsFloat()) { + // Only numerical scalars or vectors of numerical components are + // supported. + continue; + } + + switch (type->AsInteger() ? type->AsInteger()->width() + : type->AsFloat()->width()) { + case 32: + break; + case 64: + if (!GetIRContext()->get_feature_mgr()->HasCapability( + SpvCapabilityFloat64) || + !GetIRContext()->get_feature_mgr()->HasCapability( + SpvCapabilityInt64)) { + continue; + } + break; + case 16: + if (!GetIRContext()->get_feature_mgr()->HasCapability( + SpvCapabilityFloat16) || + !GetIRContext()->get_feature_mgr()->HasCapability( + SpvCapabilityInt16)) { + continue; + } + break; + default: + // |element_width| is not supported. + continue; + } + + result.push_back(inst); + } + + return result; +} + } // namespace fuzz } // namespace spvtools diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.h b/source/fuzz/fuzzer_pass_add_equation_instructions.h index 8328b6b8bf..9ce581eb30 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.h +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.h @@ -51,6 +51,14 @@ class FuzzerPassAddEquationInstructions : public FuzzerPass { std::vector GetBooleanInstructions( const std::vector& instructions) const; + // Yields those instructions in |instructions| that have a scalar numerical or + // a vector of numerical components type. Only 16, 32 and 64-bit numericals + // are supported if both OpTypeInt and OpTypeFloat instructions can be created + // with the specified width (e.g. for 16-bit types both Float16 and Int16 + // capabilities must be present). + std::vector GetNumericalInstructions( + const std::vector& instructions) const; + // Requires that |instructions| are scalars or vectors of some type. Returns // only those instructions whose width is |width|. If |width| is 1 this means // the scalars. From c5c3f8bac44d0dea369bee255d41c2b85baef583 Mon Sep 17 00:00:00 2001 From: Vasyl Teliman Date: Tue, 11 Aug 2020 20:43:04 +0300 Subject: [PATCH 2/3] More fixes --- .../fuzzer_pass_add_equation_instructions.cpp | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp index 3ad398d939..f76de8750e 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp @@ -76,8 +76,39 @@ void FuzzerPassAddEquationInstructions::Apply() { switch (opcode) { case SpvOpConvertSToF: case SpvOpConvertUToF: { - auto candidate_instructions = - GetIntegerInstructions(available_instructions); + std::vector candidate_instructions; + for (const auto* inst : + GetIntegerInstructions(available_instructions)) { + const auto* type = + GetIRContext()->get_type_mgr()->GetType(inst->type_id()); + assert(type && "|inst| has invalid type"); + + if (const auto* vector_type = type->AsVector()) { + type = vector_type->element_type(); + } + + switch (type->AsInteger()->width()) { + case 16: + if (!GetIRContext()->get_feature_mgr()->HasCapability( + SpvCapabilityFloat16)) { + continue; + } + break; + case 32: + break; + case 64: + if (!GetIRContext()->get_feature_mgr()->HasCapability( + SpvCapabilityFloat64)) { + continue; + } + break; + default: + // Width is not supported. + continue; + } + + candidate_instructions.push_back(inst); + } if (candidate_instructions.empty()) { break; From d6ec47551deb02847e7bd28d1354115059203cdf Mon Sep 17 00:00:00 2001 From: Vasyl Teliman Date: Tue, 11 Aug 2020 20:55:12 +0300 Subject: [PATCH 3/3] Small refactorings --- .../fuzzer_pass_add_equation_instructions.cpp | 70 +++++++------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp index f76de8750e..62fcfea7f7 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp @@ -21,6 +21,26 @@ namespace spvtools { namespace fuzz { +namespace { + +bool IsBitWidthSupported(opt::IRContext* ir_context, uint32_t bit_width) { + switch (bit_width) { + case 32: + return true; + case 64: + return ir_context->get_feature_mgr()->HasCapability( + SpvCapabilityFloat64) && + ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt64); + case 16: + return ir_context->get_feature_mgr()->HasCapability( + SpvCapabilityFloat16) && + ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt16); + default: + return false; + } +} + +} // namespace FuzzerPassAddEquationInstructions::FuzzerPassAddEquationInstructions( opt::IRContext* ir_context, TransformationContext* transformation_context, @@ -87,27 +107,10 @@ void FuzzerPassAddEquationInstructions::Apply() { type = vector_type->element_type(); } - switch (type->AsInteger()->width()) { - case 16: - if (!GetIRContext()->get_feature_mgr()->HasCapability( - SpvCapabilityFloat16)) { - continue; - } - break; - case 32: - break; - case 64: - if (!GetIRContext()->get_feature_mgr()->HasCapability( - SpvCapabilityFloat64)) { - continue; - } - break; - default: - // Width is not supported. - continue; + if (IsBitWidthSupported(GetIRContext(), + type->AsInteger()->width())) { + candidate_instructions.push_back(inst); } - - candidate_instructions.push_back(inst); } if (candidate_instructions.empty()) { @@ -394,29 +397,10 @@ FuzzerPassAddEquationInstructions::GetNumericalInstructions( continue; } - switch (type->AsInteger() ? type->AsInteger()->width() - : type->AsFloat()->width()) { - case 32: - break; - case 64: - if (!GetIRContext()->get_feature_mgr()->HasCapability( - SpvCapabilityFloat64) || - !GetIRContext()->get_feature_mgr()->HasCapability( - SpvCapabilityInt64)) { - continue; - } - break; - case 16: - if (!GetIRContext()->get_feature_mgr()->HasCapability( - SpvCapabilityFloat16) || - !GetIRContext()->get_feature_mgr()->HasCapability( - SpvCapabilityInt16)) { - continue; - } - break; - default: - // |element_width| is not supported. - continue; + if (!IsBitWidthSupported(GetIRContext(), type->AsInteger() + ? type->AsInteger()->width() + : type->AsFloat()->width())) { + continue; } result.push_back(inst);