mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
spirv-fuzz: add TransformationAddRelaxedDecoration (#3545)
Add TransformationAddRelaxedDecoration, which adds the RelaxedPrecision decoration to ids of numeric instructions (those yielding 32-bit ints or floats) in dead blocks. Fixes #3502
This commit is contained in:
parent
717e7877ca
commit
0d8fe0fba0
@ -52,6 +52,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
fuzzer_pass_add_local_variables.h
|
fuzzer_pass_add_local_variables.h
|
||||||
fuzzer_pass_add_no_contraction_decorations.h
|
fuzzer_pass_add_no_contraction_decorations.h
|
||||||
fuzzer_pass_add_parameters.h
|
fuzzer_pass_add_parameters.h
|
||||||
|
fuzzer_pass_add_relaxed_decorations.h
|
||||||
fuzzer_pass_add_stores.h
|
fuzzer_pass_add_stores.h
|
||||||
fuzzer_pass_add_vector_shuffle_instructions.h
|
fuzzer_pass_add_vector_shuffle_instructions.h
|
||||||
fuzzer_pass_adjust_branch_weights.h
|
fuzzer_pass_adjust_branch_weights.h
|
||||||
@ -104,6 +105,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
transformation_add_local_variable.h
|
transformation_add_local_variable.h
|
||||||
transformation_add_no_contraction_decoration.h
|
transformation_add_no_contraction_decoration.h
|
||||||
transformation_add_parameter.h
|
transformation_add_parameter.h
|
||||||
|
transformation_add_relaxed_decoration.h
|
||||||
transformation_add_spec_constant_op.h
|
transformation_add_spec_constant_op.h
|
||||||
transformation_add_synonym.h
|
transformation_add_synonym.h
|
||||||
transformation_add_type_array.h
|
transformation_add_type_array.h
|
||||||
@ -171,6 +173,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
fuzzer_pass_add_local_variables.cpp
|
fuzzer_pass_add_local_variables.cpp
|
||||||
fuzzer_pass_add_no_contraction_decorations.cpp
|
fuzzer_pass_add_no_contraction_decorations.cpp
|
||||||
fuzzer_pass_add_parameters.cpp
|
fuzzer_pass_add_parameters.cpp
|
||||||
|
fuzzer_pass_add_relaxed_decorations.cpp
|
||||||
fuzzer_pass_add_stores.cpp
|
fuzzer_pass_add_stores.cpp
|
||||||
fuzzer_pass_add_vector_shuffle_instructions.cpp
|
fuzzer_pass_add_vector_shuffle_instructions.cpp
|
||||||
fuzzer_pass_adjust_branch_weights.cpp
|
fuzzer_pass_adjust_branch_weights.cpp
|
||||||
@ -222,6 +225,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
transformation_add_local_variable.cpp
|
transformation_add_local_variable.cpp
|
||||||
transformation_add_no_contraction_decoration.cpp
|
transformation_add_no_contraction_decoration.cpp
|
||||||
transformation_add_parameter.cpp
|
transformation_add_parameter.cpp
|
||||||
|
transformation_add_relaxed_decoration.cpp
|
||||||
transformation_add_spec_constant_op.cpp
|
transformation_add_spec_constant_op.cpp
|
||||||
transformation_add_synonym.cpp
|
transformation_add_synonym.cpp
|
||||||
transformation_add_type_array.cpp
|
transformation_add_type_array.cpp
|
||||||
|
@ -42,6 +42,7 @@ const std::pair<uint32_t, uint32_t> kChanceOfAddingMatrixType = {20, 70};
|
|||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingNoContractionDecoration = {
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingNoContractionDecoration = {
|
||||||
5, 70};
|
5, 70};
|
||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingParameters = {5, 70};
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingParameters = {5, 70};
|
||||||
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingRelaxedDecoration = {20, 90};
|
||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingStore = {5, 50};
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingStore = {5, 50};
|
||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingSynonyms = {20, 50};
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingSynonyms = {20, 50};
|
||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingVectorType = {20, 70};
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingVectorType = {20, 70};
|
||||||
@ -154,6 +155,8 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
|
|||||||
ChooseBetweenMinAndMax(kChanceOfAddingNoContractionDecoration);
|
ChooseBetweenMinAndMax(kChanceOfAddingNoContractionDecoration);
|
||||||
chance_of_adding_parameters =
|
chance_of_adding_parameters =
|
||||||
ChooseBetweenMinAndMax(kChanceOfAddingParameters);
|
ChooseBetweenMinAndMax(kChanceOfAddingParameters);
|
||||||
|
chance_of_adding_relaxed_decoration_ =
|
||||||
|
ChooseBetweenMinAndMax(kChanceOfAddingRelaxedDecoration);
|
||||||
chance_of_adding_store_ = ChooseBetweenMinAndMax(kChanceOfAddingStore);
|
chance_of_adding_store_ = ChooseBetweenMinAndMax(kChanceOfAddingStore);
|
||||||
chance_of_adding_vector_shuffle_ =
|
chance_of_adding_vector_shuffle_ =
|
||||||
ChooseBetweenMinAndMax(kChanceOfAddingVectorShuffle);
|
ChooseBetweenMinAndMax(kChanceOfAddingVectorShuffle);
|
||||||
|
@ -143,6 +143,9 @@ class FuzzerContext {
|
|||||||
return chance_of_adding_no_contraction_decoration_;
|
return chance_of_adding_no_contraction_decoration_;
|
||||||
}
|
}
|
||||||
uint32_t GetChanceOfAddingParameters() { return chance_of_adding_parameters; }
|
uint32_t GetChanceOfAddingParameters() { return chance_of_adding_parameters; }
|
||||||
|
uint32_t GetChanceOfAddingRelaxedDecoration() {
|
||||||
|
return chance_of_adding_relaxed_decoration_;
|
||||||
|
}
|
||||||
uint32_t GetChanceOfAddingStore() { return chance_of_adding_store_; }
|
uint32_t GetChanceOfAddingStore() { return chance_of_adding_store_; }
|
||||||
uint32_t GetChanceOfAddingSynonyms() { return chance_of_adding_synonyms_; }
|
uint32_t GetChanceOfAddingSynonyms() { return chance_of_adding_synonyms_; }
|
||||||
uint32_t GetChanceOfAddingVectorShuffle() {
|
uint32_t GetChanceOfAddingVectorShuffle() {
|
||||||
@ -312,6 +315,7 @@ class FuzzerContext {
|
|||||||
uint32_t chance_of_adding_matrix_type_;
|
uint32_t chance_of_adding_matrix_type_;
|
||||||
uint32_t chance_of_adding_no_contraction_decoration_;
|
uint32_t chance_of_adding_no_contraction_decoration_;
|
||||||
uint32_t chance_of_adding_parameters;
|
uint32_t chance_of_adding_parameters;
|
||||||
|
uint32_t chance_of_adding_relaxed_decoration_;
|
||||||
uint32_t chance_of_adding_store_;
|
uint32_t chance_of_adding_store_;
|
||||||
uint32_t chance_of_adding_synonyms_;
|
uint32_t chance_of_adding_synonyms_;
|
||||||
uint32_t chance_of_adding_vector_shuffle_;
|
uint32_t chance_of_adding_vector_shuffle_;
|
||||||
|
55
source/fuzz/fuzzer_pass_add_relaxed_decorations.cpp
Normal file
55
source/fuzz/fuzzer_pass_add_relaxed_decorations.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) 2020 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/fuzzer_pass_add_relaxed_decorations.h"
|
||||||
|
|
||||||
|
#include "source/fuzz/transformation_add_relaxed_decoration.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
FuzzerPassAddRelaxedDecorations::FuzzerPassAddRelaxedDecorations(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||||
|
FuzzerContext* fuzzer_context,
|
||||||
|
protobufs::TransformationSequence* transformations)
|
||||||
|
: FuzzerPass(ir_context, transformation_context, fuzzer_context,
|
||||||
|
transformations) {}
|
||||||
|
|
||||||
|
FuzzerPassAddRelaxedDecorations::~FuzzerPassAddRelaxedDecorations() = default;
|
||||||
|
|
||||||
|
void FuzzerPassAddRelaxedDecorations::Apply() {
|
||||||
|
// Consider every instruction in every block in every function.
|
||||||
|
for (auto& function : *GetIRContext()->module()) {
|
||||||
|
for (auto& block : function) {
|
||||||
|
for (auto& inst : block) {
|
||||||
|
// Randomly choose whether to apply the RelaxedPrecision decoration
|
||||||
|
// to this instruction.
|
||||||
|
if (GetFuzzerContext()->ChoosePercentage(
|
||||||
|
GetFuzzerContext()->GetChanceOfAddingRelaxedDecoration())) {
|
||||||
|
TransformationAddRelaxedDecoration transformation(inst.result_id());
|
||||||
|
// Restrict attention to numeric instructions (returning 32-bit
|
||||||
|
// floats or ints according to SPIR-V documentation) in dead blocks.
|
||||||
|
if (transformation.IsApplicable(GetIRContext(),
|
||||||
|
*GetTransformationContext())) {
|
||||||
|
transformation.Apply(GetIRContext(), GetTransformationContext());
|
||||||
|
*GetTransformations()->add_transformation() =
|
||||||
|
transformation.ToMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
39
source/fuzz/fuzzer_pass_add_relaxed_decorations.h
Normal file
39
source/fuzz/fuzzer_pass_add_relaxed_decorations.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) 2020 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.
|
||||||
|
|
||||||
|
#ifndef SPIRV_TOOLS_FUZZER_PASS_ADD_RELAXED_DECORATIONS_H
|
||||||
|
#define SPIRV_TOOLS_FUZZER_PASS_ADD_RELAXED_DECORATIONS_H
|
||||||
|
|
||||||
|
#include "source/fuzz/fuzzer_pass.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// A pass that applies the Relaxed decoration to numeric instructions.
|
||||||
|
class FuzzerPassAddRelaxedDecorations : public FuzzerPass {
|
||||||
|
public:
|
||||||
|
FuzzerPassAddRelaxedDecorations(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||||
|
FuzzerContext* fuzzer_context,
|
||||||
|
protobufs::TransformationSequence* transformations);
|
||||||
|
|
||||||
|
~FuzzerPassAddRelaxedDecorations() override;
|
||||||
|
|
||||||
|
void Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SPIRV_TOOLS_FUZZER_PASS_ADD_RELAXED_DECORATIONS_H
|
@ -386,6 +386,7 @@ message Transformation {
|
|||||||
TransformationReplaceParameterWithGlobal replace_parameter_with_global = 55;
|
TransformationReplaceParameterWithGlobal replace_parameter_with_global = 55;
|
||||||
TransformationRecordSynonymousConstants record_synonymous_constants = 56;
|
TransformationRecordSynonymousConstants record_synonymous_constants = 56;
|
||||||
TransformationAddSynonym add_synonym = 57;
|
TransformationAddSynonym add_synonym = 57;
|
||||||
|
TransformationAddRelaxedDecoration add_relaxed_decoration = 58;
|
||||||
// Add additional option using the next available number.
|
// Add additional option using the next available number.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,6 +688,15 @@ message TransformationAddParameter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message TransformationAddRelaxedDecoration {
|
||||||
|
|
||||||
|
// Applies OpDecorate RelaxedPrecision to the given result id
|
||||||
|
|
||||||
|
// Result id to be decorated
|
||||||
|
uint32 result_id = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
message TransformationAddSpecConstantOp {
|
message TransformationAddSpecConstantOp {
|
||||||
|
|
||||||
// Adds OpSpecConstantOp into the module.
|
// Adds OpSpecConstantOp into the module.
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "source/fuzz/transformation_add_local_variable.h"
|
#include "source/fuzz/transformation_add_local_variable.h"
|
||||||
#include "source/fuzz/transformation_add_no_contraction_decoration.h"
|
#include "source/fuzz/transformation_add_no_contraction_decoration.h"
|
||||||
#include "source/fuzz/transformation_add_parameter.h"
|
#include "source/fuzz/transformation_add_parameter.h"
|
||||||
|
#include "source/fuzz/transformation_add_relaxed_decoration.h"
|
||||||
#include "source/fuzz/transformation_add_spec_constant_op.h"
|
#include "source/fuzz/transformation_add_spec_constant_op.h"
|
||||||
#include "source/fuzz/transformation_add_synonym.h"
|
#include "source/fuzz/transformation_add_synonym.h"
|
||||||
#include "source/fuzz/transformation_add_type_array.h"
|
#include "source/fuzz/transformation_add_type_array.h"
|
||||||
@ -128,6 +129,9 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
|
|||||||
message.add_no_contraction_decoration());
|
message.add_no_contraction_decoration());
|
||||||
case protobufs::Transformation::TransformationCase::kAddParameter:
|
case protobufs::Transformation::TransformationCase::kAddParameter:
|
||||||
return MakeUnique<TransformationAddParameter>(message.add_parameter());
|
return MakeUnique<TransformationAddParameter>(message.add_parameter());
|
||||||
|
case protobufs::Transformation::TransformationCase::kAddRelaxedDecoration:
|
||||||
|
return MakeUnique<TransformationAddRelaxedDecoration>(
|
||||||
|
message.add_relaxed_decoration());
|
||||||
case protobufs::Transformation::TransformationCase::kAddSpecConstantOp:
|
case protobufs::Transformation::TransformationCase::kAddSpecConstantOp:
|
||||||
return MakeUnique<TransformationAddSpecConstantOp>(
|
return MakeUnique<TransformationAddSpecConstantOp>(
|
||||||
message.add_spec_constant_op());
|
message.add_spec_constant_op());
|
||||||
|
146
source/fuzz/transformation_add_relaxed_decoration.cpp
Normal file
146
source/fuzz/transformation_add_relaxed_decoration.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// Copyright (c) 2020 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_relaxed_decoration.h"
|
||||||
|
|
||||||
|
#include "source/fuzz/fuzzer_util.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
TransformationAddRelaxedDecoration::TransformationAddRelaxedDecoration(
|
||||||
|
const spvtools::fuzz::protobufs::TransformationAddRelaxedDecoration&
|
||||||
|
message)
|
||||||
|
: message_(message) {}
|
||||||
|
|
||||||
|
TransformationAddRelaxedDecoration::TransformationAddRelaxedDecoration(
|
||||||
|
uint32_t result_id) {
|
||||||
|
message_.set_result_id(result_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformationAddRelaxedDecoration::IsApplicable(
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
const TransformationContext& transformation_context) 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;
|
||||||
|
}
|
||||||
|
opt::BasicBlock* cur_block = ir_context->get_instr_block(instr);
|
||||||
|
// The instruction must have a block.
|
||||||
|
if (cur_block == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// |cur_block| must be a dead block.
|
||||||
|
if (!(transformation_context.GetFactManager()->BlockIsDead(
|
||||||
|
cur_block->id()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// The instruction must be numeric.
|
||||||
|
return IsNumeric(instr->opcode());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformationAddRelaxedDecoration::Apply(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||||
|
// Add a RelaxedPrecision decoration targeting |message_.result_id|.
|
||||||
|
ir_context->get_decoration_mgr()->AddDecoration(
|
||||||
|
message_.result_id(), SpvDecorationRelaxedPrecision);
|
||||||
|
}
|
||||||
|
|
||||||
|
protobufs::Transformation TransformationAddRelaxedDecoration::ToMessage()
|
||||||
|
const {
|
||||||
|
protobufs::Transformation result;
|
||||||
|
*result.mutable_add_relaxed_decoration() = message_;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformationAddRelaxedDecoration::IsNumeric(uint32_t opcode) {
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpConvertFToU:
|
||||||
|
case SpvOpConvertFToS:
|
||||||
|
case SpvOpConvertSToF:
|
||||||
|
case SpvOpConvertUToF:
|
||||||
|
case SpvOpUConvert:
|
||||||
|
case SpvOpSConvert:
|
||||||
|
case SpvOpFConvert:
|
||||||
|
case SpvOpConvertPtrToU:
|
||||||
|
case SpvOpSatConvertSToU:
|
||||||
|
case SpvOpSatConvertUToS:
|
||||||
|
case SpvOpVectorExtractDynamic:
|
||||||
|
case SpvOpVectorInsertDynamic:
|
||||||
|
case SpvOpVectorShuffle:
|
||||||
|
case SpvOpTranspose:
|
||||||
|
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 SpvOpShiftRightLogical:
|
||||||
|
case SpvOpShiftRightArithmetic:
|
||||||
|
case SpvOpShiftLeftLogical:
|
||||||
|
case SpvOpBitwiseOr:
|
||||||
|
case SpvOpBitwiseXor:
|
||||||
|
case SpvOpBitwiseAnd:
|
||||||
|
case SpvOpNot:
|
||||||
|
case SpvOpBitFieldInsert:
|
||||||
|
case SpvOpBitFieldSExtract:
|
||||||
|
case SpvOpBitFieldUExtract:
|
||||||
|
case SpvOpBitReverse:
|
||||||
|
case SpvOpBitCount:
|
||||||
|
case SpvOpAtomicLoad:
|
||||||
|
case SpvOpAtomicStore:
|
||||||
|
case SpvOpAtomicExchange:
|
||||||
|
case SpvOpAtomicCompareExchange:
|
||||||
|
case SpvOpAtomicCompareExchangeWeak:
|
||||||
|
case SpvOpAtomicIIncrement:
|
||||||
|
case SpvOpAtomicIDecrement:
|
||||||
|
case SpvOpAtomicIAdd:
|
||||||
|
case SpvOpAtomicISub:
|
||||||
|
case SpvOpAtomicSMin:
|
||||||
|
case SpvOpAtomicUMin:
|
||||||
|
case SpvOpAtomicSMax:
|
||||||
|
case SpvOpAtomicUMax:
|
||||||
|
case SpvOpAtomicAnd:
|
||||||
|
case SpvOpAtomicOr:
|
||||||
|
case SpvOpAtomicXor:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
62
source/fuzz/transformation_add_relaxed_decoration.h
Normal file
62
source/fuzz/transformation_add_relaxed_decoration.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (c) 2020 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.
|
||||||
|
|
||||||
|
#ifndef SPIRV_TOOLS_TRANSFORMATION_ADD_RELAXED_DECORATION_H
|
||||||
|
#define SPIRV_TOOLS_TRANSFORMATION_ADD_RELAXED_DECORATION_H
|
||||||
|
|
||||||
|
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||||
|
#include "source/fuzz/transformation.h"
|
||||||
|
#include "source/fuzz/transformation_context.h"
|
||||||
|
#include "source/opt/ir_context.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
class TransformationAddRelaxedDecoration : public Transformation {
|
||||||
|
public:
|
||||||
|
explicit TransformationAddRelaxedDecoration(
|
||||||
|
const protobufs::TransformationAddRelaxedDecoration& message);
|
||||||
|
|
||||||
|
explicit TransformationAddRelaxedDecoration(uint32_t fresh_id);
|
||||||
|
|
||||||
|
// - |message_.result_id| must be the result id of an instruction, which is
|
||||||
|
// located in a dead block and Relaxed decoration can be applied.
|
||||||
|
// - It does not matter whether this instruction is already annotated with the
|
||||||
|
// Relaxed decoration.
|
||||||
|
bool IsApplicable(
|
||||||
|
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
const TransformationContext& transformation_context) const override;
|
||||||
|
|
||||||
|
// Adds a decoration of the form:
|
||||||
|
// 'OpDecoration |message_.result_id| RelaxedPrecision'
|
||||||
|
// to the module.
|
||||||
|
void Apply(opt::IRContext* ir_context,
|
||||||
|
TransformationContext* transformation_context) const override;
|
||||||
|
|
||||||
|
protobufs::Transformation ToMessage() const override;
|
||||||
|
|
||||||
|
// Returns true if and only if |opcode| is the opcode of an instruction
|
||||||
|
// that operates on 32-bit integers and 32-bit floats
|
||||||
|
// as defined by the SPIR-V specification.
|
||||||
|
static bool IsNumeric(uint32_t opcode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
protobufs::TransformationAddRelaxedDecoration message_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SPIRV_TOOLS_TRANSFORMATION_ADD_RELAXED_DECORATION_H
|
@ -41,6 +41,7 @@ if (${SPIRV_BUILD_FUZZER})
|
|||||||
transformation_add_local_variable_test.cpp
|
transformation_add_local_variable_test.cpp
|
||||||
transformation_add_no_contraction_decoration_test.cpp
|
transformation_add_no_contraction_decoration_test.cpp
|
||||||
transformation_add_parameter_test.cpp
|
transformation_add_parameter_test.cpp
|
||||||
|
transformation_add_relaxed_decoration_test.cpp
|
||||||
transformation_add_synonym_test.cpp
|
transformation_add_synonym_test.cpp
|
||||||
transformation_add_type_array_test.cpp
|
transformation_add_type_array_test.cpp
|
||||||
transformation_add_type_boolean_test.cpp
|
transformation_add_type_boolean_test.cpp
|
||||||
|
141
test/fuzz/transformation_add_relaxed_decoration_test.cpp
Normal file
141
test/fuzz/transformation_add_relaxed_decoration_test.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
// Copyright (c) 2020 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_relaxed_decoration.h"
|
||||||
|
#include "test/fuzz/fuzz_test_util.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
namespace {
|
||||||
|
TEST(TransformationAddRelaxedDecorationTest, BasicScenarios) {
|
||||||
|
// This is a simple transformation and this test handles the main cases.
|
||||||
|
|
||||||
|
std::string shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %4 "main"
|
||||||
|
OpExecutionMode %4 OriginUpperLeft
|
||||||
|
OpSource ESSL 310
|
||||||
|
OpName %4 "main"
|
||||||
|
OpName %8 "a"
|
||||||
|
OpName %10 "b"
|
||||||
|
OpName %14 "c"
|
||||||
|
%2 = OpTypeVoid
|
||||||
|
%3 = OpTypeFunction %2
|
||||||
|
%6 = OpTypeInt 32 1
|
||||||
|
%7 = OpTypePointer Function %6
|
||||||
|
%9 = OpConstant %6 4
|
||||||
|
%11 = OpConstant %6 6
|
||||||
|
%12 = OpTypeBool
|
||||||
|
%13 = OpTypePointer Function %12
|
||||||
|
%15 = OpConstantTrue %12
|
||||||
|
%4 = OpFunction %2 None %3
|
||||||
|
%5 = OpLabel
|
||||||
|
%8 = OpVariable %7 Function
|
||||||
|
%10 = OpVariable %7 Function
|
||||||
|
%14 = OpVariable %13 Function
|
||||||
|
OpStore %8 %9
|
||||||
|
OpStore %10 %11
|
||||||
|
OpStore %14 %15
|
||||||
|
OpSelectionMerge %19 None
|
||||||
|
OpBranchConditional %15 %19 %100
|
||||||
|
%100 = OpLabel
|
||||||
|
%25 = OpISub %6 %9 %11
|
||||||
|
%28 = OpLogicalNot %12 %15
|
||||||
|
OpBranch %19
|
||||||
|
%19 = OpLabel
|
||||||
|
%27 = OpISub %6 %9 %11
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
const auto env = SPV_ENV_UNIVERSAL_1_4;
|
||||||
|
const auto consumer = nullptr;
|
||||||
|
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||||
|
ASSERT_TRUE(IsValid(env, context.get()));
|
||||||
|
|
||||||
|
FactManager fact_manager;
|
||||||
|
spvtools::ValidatorOptions validator_options;
|
||||||
|
TransformationContext transformation_context(&fact_manager,
|
||||||
|
validator_options);
|
||||||
|
|
||||||
|
fact_manager.AddFactBlockIsDead(100);
|
||||||
|
|
||||||
|
// Invalid: 200 is not an id.
|
||||||
|
ASSERT_FALSE(TransformationAddRelaxedDecoration(200).IsApplicable(
|
||||||
|
context.get(), transformation_context));
|
||||||
|
// Invalid: 27 is not in a dead block.
|
||||||
|
ASSERT_FALSE(TransformationAddRelaxedDecoration(27).IsApplicable(
|
||||||
|
context.get(), transformation_context));
|
||||||
|
// Invalid: 28 is in a dead block, but returns bool (not numeric).
|
||||||
|
ASSERT_FALSE(TransformationAddRelaxedDecoration(28).IsApplicable(
|
||||||
|
context.get(), transformation_context));
|
||||||
|
// It is valid to add RelaxedPrecision to 25 (and it's fine to
|
||||||
|
// have a duplicate).
|
||||||
|
for (uint32_t result_id : {25u, 25u}) {
|
||||||
|
TransformationAddRelaxedDecoration transformation(result_id);
|
||||||
|
ASSERT_TRUE(
|
||||||
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
transformation.Apply(context.get(), &transformation_context);
|
||||||
|
ASSERT_TRUE(IsValid(env, context.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string after_transformation = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %4 "main"
|
||||||
|
OpExecutionMode %4 OriginUpperLeft
|
||||||
|
OpSource ESSL 310
|
||||||
|
OpName %4 "main"
|
||||||
|
OpName %8 "a"
|
||||||
|
OpName %10 "b"
|
||||||
|
OpName %14 "c"
|
||||||
|
OpDecorate %25 RelaxedPrecision
|
||||||
|
OpDecorate %25 RelaxedPrecision
|
||||||
|
%2 = OpTypeVoid
|
||||||
|
%3 = OpTypeFunction %2
|
||||||
|
%6 = OpTypeInt 32 1
|
||||||
|
%7 = OpTypePointer Function %6
|
||||||
|
%9 = OpConstant %6 4
|
||||||
|
%11 = OpConstant %6 6
|
||||||
|
%12 = OpTypeBool
|
||||||
|
%13 = OpTypePointer Function %12
|
||||||
|
%15 = OpConstantTrue %12
|
||||||
|
%4 = OpFunction %2 None %3
|
||||||
|
%5 = OpLabel
|
||||||
|
%8 = OpVariable %7 Function
|
||||||
|
%10 = OpVariable %7 Function
|
||||||
|
%14 = OpVariable %13 Function
|
||||||
|
OpStore %8 %9
|
||||||
|
OpStore %10 %11
|
||||||
|
OpStore %14 %15
|
||||||
|
OpSelectionMerge %19 None
|
||||||
|
OpBranchConditional %15 %19 %100
|
||||||
|
%100 = OpLabel
|
||||||
|
%25 = OpISub %6 %9 %11
|
||||||
|
%28 = OpLogicalNot %12 %15
|
||||||
|
OpBranch %19
|
||||||
|
%19 = OpLabel
|
||||||
|
%27 = OpISub %6 %9 %11
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
Loading…
Reference in New Issue
Block a user