mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
spirv-fuzz: Add TransformationMakeVectorOperationDynamic (#3597)
Fixes #3588.
This commit is contained in:
parent
d29eac95aa
commit
6d7f34fbfe
@ -67,6 +67,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
fuzzer_pass_invert_comparison_operators.h
|
||||
fuzzer_pass_interchange_signedness_of_integer_operands.h
|
||||
fuzzer_pass_interchange_zero_like_constants.h
|
||||
fuzzer_pass_make_vector_operations_dynamic.h
|
||||
fuzzer_pass_merge_blocks.h
|
||||
fuzzer_pass_obfuscate_constants.h
|
||||
fuzzer_pass_outline_functions.h
|
||||
@ -133,6 +134,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
transformation_function_call.h
|
||||
transformation_invert_comparison_operator.h
|
||||
transformation_load.h
|
||||
transformation_make_vector_operation_dynamic.h
|
||||
transformation_merge_blocks.h
|
||||
transformation_move_block_down.h
|
||||
transformation_move_instruction_down.h
|
||||
@ -200,6 +202,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
fuzzer_pass_invert_comparison_operators.cpp
|
||||
fuzzer_pass_interchange_signedness_of_integer_operands.cpp
|
||||
fuzzer_pass_interchange_zero_like_constants.cpp
|
||||
fuzzer_pass_make_vector_operations_dynamic.cpp
|
||||
fuzzer_pass_merge_blocks.cpp
|
||||
fuzzer_pass_obfuscate_constants.cpp
|
||||
fuzzer_pass_outline_functions.cpp
|
||||
@ -265,6 +268,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
transformation_function_call.cpp
|
||||
transformation_invert_comparison_operator.cpp
|
||||
transformation_load.cpp
|
||||
transformation_make_vector_operation_dynamic.cpp
|
||||
transformation_merge_blocks.cpp
|
||||
transformation_move_block_down.cpp
|
||||
transformation_move_instruction_down.cpp
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.h"
|
||||
#include "source/fuzz/fuzzer_pass_interchange_zero_like_constants.h"
|
||||
#include "source/fuzz/fuzzer_pass_invert_comparison_operators.h"
|
||||
#include "source/fuzz/fuzzer_pass_make_vector_operations_dynamic.h"
|
||||
#include "source/fuzz/fuzzer_pass_merge_blocks.h"
|
||||
#include "source/fuzz/fuzzer_pass_obfuscate_constants.h"
|
||||
#include "source/fuzz/fuzzer_pass_outline_functions.h"
|
||||
@ -267,6 +268,9 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run(
|
||||
MaybeAddPass<FuzzerPassInvertComparisonOperators>(
|
||||
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
||||
transformation_sequence_out);
|
||||
MaybeAddPass<FuzzerPassMakeVectorOperationsDynamic>(
|
||||
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
||||
transformation_sequence_out);
|
||||
MaybeAddPass<FuzzerPassMergeBlocks>(
|
||||
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
||||
transformation_sequence_out);
|
||||
|
@ -72,6 +72,8 @@ const std::pair<uint32_t, uint32_t>
|
||||
const std::pair<uint32_t, uint32_t> kChanceOfInvertingComparisonOperators = {
|
||||
20, 50};
|
||||
const std::pair<uint32_t, uint32_t> kChanceOfMakingDonorLivesafe = {40, 60};
|
||||
const std::pair<uint32_t, uint32_t> kChanceOfMakingVectorOperationDynamic = {
|
||||
20, 90};
|
||||
const std::pair<uint32_t, uint32_t> kChanceOfMergingBlocks = {20, 95};
|
||||
const std::pair<uint32_t, uint32_t> kChanceOfMovingBlockDown = {20, 50};
|
||||
const std::pair<uint32_t, uint32_t> kChanceOfObfuscatingConstant = {10, 90};
|
||||
@ -208,6 +210,8 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
|
||||
ChooseBetweenMinAndMax(kChanceOfInvertingComparisonOperators);
|
||||
chance_of_making_donor_livesafe_ =
|
||||
ChooseBetweenMinAndMax(kChanceOfMakingDonorLivesafe);
|
||||
chance_of_making_vector_operation_dynamic_ =
|
||||
ChooseBetweenMinAndMax(kChanceOfMakingVectorOperationDynamic);
|
||||
chance_of_merging_blocks_ = ChooseBetweenMinAndMax(kChanceOfMergingBlocks);
|
||||
chance_of_moving_block_down_ =
|
||||
ChooseBetweenMinAndMax(kChanceOfMovingBlockDown);
|
||||
|
@ -198,6 +198,9 @@ class FuzzerContext {
|
||||
uint32_t ChanceOfMakingDonorLivesafe() {
|
||||
return chance_of_making_donor_livesafe_;
|
||||
}
|
||||
uint32_t GetChanceOfMakingVectorOperationDynamic() {
|
||||
return chance_of_making_vector_operation_dynamic_;
|
||||
}
|
||||
uint32_t GetChanceOfMergingBlocks() { return chance_of_merging_blocks_; }
|
||||
uint32_t GetChanceOfMovingBlockDown() { return chance_of_moving_block_down_; }
|
||||
uint32_t GetChanceOfObfuscatingConstant() {
|
||||
@ -363,6 +366,7 @@ class FuzzerContext {
|
||||
uint32_t chance_of_interchanging_zero_like_constants_;
|
||||
uint32_t chance_of_inverting_comparison_operators_;
|
||||
uint32_t chance_of_making_donor_livesafe_;
|
||||
uint32_t chance_of_making_vector_operation_dynamic_;
|
||||
uint32_t chance_of_merging_blocks_;
|
||||
uint32_t chance_of_moving_block_down_;
|
||||
uint32_t chance_of_obfuscating_constant_;
|
||||
|
71
source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp
Normal file
71
source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2020 André Perez Maselco
|
||||
//
|
||||
// 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_make_vector_operations_dynamic.h"
|
||||
|
||||
#include "source/fuzz/fuzzer_util.h"
|
||||
#include "source/fuzz/instruction_descriptor.h"
|
||||
#include "source/fuzz/transformation_make_vector_operation_dynamic.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
FuzzerPassMakeVectorOperationsDynamic::FuzzerPassMakeVectorOperationsDynamic(
|
||||
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||
FuzzerContext* fuzzer_context,
|
||||
protobufs::TransformationSequence* transformations)
|
||||
: FuzzerPass(ir_context, transformation_context, fuzzer_context,
|
||||
transformations) {}
|
||||
|
||||
FuzzerPassMakeVectorOperationsDynamic::
|
||||
~FuzzerPassMakeVectorOperationsDynamic() = default;
|
||||
|
||||
void FuzzerPassMakeVectorOperationsDynamic::Apply() {
|
||||
for (auto& function : *GetIRContext()->module()) {
|
||||
for (auto& block : function) {
|
||||
for (auto& instruction : block) {
|
||||
// Randomly decide whether to try applying the transformation.
|
||||
if (!GetFuzzerContext()->ChoosePercentage(
|
||||
GetFuzzerContext()
|
||||
->GetChanceOfMakingVectorOperationDynamic())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// |instruction| must be a vector operation.
|
||||
if (!TransformationMakeVectorOperationDynamic::IsVectorOperation(
|
||||
GetIRContext(), &instruction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure |instruction| has only one indexing operand.
|
||||
assert(instruction.NumInOperands() ==
|
||||
(instruction.opcode() == SpvOpCompositeExtract ? 2 : 3) &&
|
||||
"FuzzerPassMakeVectorOperationsDynamic: the composite "
|
||||
"instruction must have "
|
||||
"only one indexing operand.");
|
||||
|
||||
// Applies the make vector operation dynamic transformation.
|
||||
ApplyTransformation(TransformationMakeVectorOperationDynamic(
|
||||
instruction.result_id(),
|
||||
FindOrCreateIntegerConstant(
|
||||
{instruction.GetSingleWordInOperand(
|
||||
instruction.opcode() == SpvOpCompositeExtract ? 1 : 2)},
|
||||
32, GetFuzzerContext()->ChooseEven(), false)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
40
source/fuzz/fuzzer_pass_make_vector_operations_dynamic.h
Normal file
40
source/fuzz/fuzzer_pass_make_vector_operations_dynamic.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2020 André Perez Maselco
|
||||
//
|
||||
// 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 SOURCE_FUZZ_FUZZER_PASS_MAKE_VECTOR_OPERATIONS_DYNAMIC_H_
|
||||
#define SOURCE_FUZZ_FUZZER_PASS_MAKE_VECTOR_OPERATIONS_DYNAMIC_H_
|
||||
|
||||
#include "source/fuzz/fuzzer_pass.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
// Looks for OpCompositeExtract/Insert instructions on vectors, and replaces
|
||||
// them with OpVectorExtract/InsertDynamic.
|
||||
class FuzzerPassMakeVectorOperationsDynamic : public FuzzerPass {
|
||||
public:
|
||||
FuzzerPassMakeVectorOperationsDynamic(
|
||||
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||
FuzzerContext* fuzzer_context,
|
||||
protobufs::TransformationSequence* transformations);
|
||||
|
||||
~FuzzerPassMakeVectorOperationsDynamic() override;
|
||||
|
||||
void Apply() override;
|
||||
};
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_FUZZ_FUZZER_PASS_MAKE_VECTOR_OPERATIONS_DYNAMIC_H_
|
@ -409,6 +409,7 @@ message Transformation {
|
||||
TransformationReplaceLoadStoreWithCopyMemory replace_load_store_with_copy_memory = 62;
|
||||
TransformationAddLoopPreheader add_loop_preheader = 63;
|
||||
TransformationMoveInstructionDown move_instruction_down = 64;
|
||||
TransformationMakeVectorOperationDynamic make_vector_operation_dynamic = 65;
|
||||
// Add additional option using the next available number.
|
||||
}
|
||||
}
|
||||
@ -1106,6 +1107,21 @@ message TransformationLoad {
|
||||
|
||||
}
|
||||
|
||||
message TransformationMakeVectorOperationDynamic {
|
||||
|
||||
// A transformation that replaces the OpCompositeExtract and OpCompositeInsert
|
||||
// instructions with the OpVectorExtractDynamic and OpVectorInsertDynamic instructions.
|
||||
|
||||
// The composite instruction result id.
|
||||
uint32 instruction_result_id = 1;
|
||||
|
||||
// The OpCompositeExtract/Insert instructions accept integer literals as indices to the composite object.
|
||||
// However, the OpVectorInsert/ExtractDynamic instructions require its single index to be an integer instruction.
|
||||
// This is the result id of the integer instruction.
|
||||
uint32 constant_index_id = 2;
|
||||
|
||||
}
|
||||
|
||||
message TransformationMergeBlocks {
|
||||
|
||||
// A transformation that merges a block with its predecessor.
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "source/fuzz/transformation_function_call.h"
|
||||
#include "source/fuzz/transformation_invert_comparison_operator.h"
|
||||
#include "source/fuzz/transformation_load.h"
|
||||
#include "source/fuzz/transformation_make_vector_operation_dynamic.h"
|
||||
#include "source/fuzz/transformation_merge_blocks.h"
|
||||
#include "source/fuzz/transformation_move_block_down.h"
|
||||
#include "source/fuzz/transformation_move_instruction_down.h"
|
||||
@ -191,6 +192,10 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
|
||||
message.invert_comparison_operator());
|
||||
case protobufs::Transformation::TransformationCase::kLoad:
|
||||
return MakeUnique<TransformationLoad>(message.load());
|
||||
case protobufs::Transformation::TransformationCase::
|
||||
kMakeVectorOperationDynamic:
|
||||
return MakeUnique<TransformationMakeVectorOperationDynamic>(
|
||||
message.make_vector_operation_dynamic());
|
||||
case protobufs::Transformation::TransformationCase::kMergeBlocks:
|
||||
return MakeUnique<TransformationMergeBlocks>(message.merge_blocks());
|
||||
case protobufs::Transformation::TransformationCase::kMoveBlockDown:
|
||||
|
111
source/fuzz/transformation_make_vector_operation_dynamic.cpp
Normal file
111
source/fuzz/transformation_make_vector_operation_dynamic.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2020 André Perez Maselco
|
||||
//
|
||||
// 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_make_vector_operation_dynamic.h"
|
||||
|
||||
#include "source/fuzz/fuzzer_util.h"
|
||||
#include "source/fuzz/instruction_descriptor.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
TransformationMakeVectorOperationDynamic::
|
||||
TransformationMakeVectorOperationDynamic(
|
||||
const spvtools::fuzz::protobufs::
|
||||
TransformationMakeVectorOperationDynamic& message)
|
||||
: message_(message) {}
|
||||
|
||||
TransformationMakeVectorOperationDynamic::
|
||||
TransformationMakeVectorOperationDynamic(uint32_t instruction_result_id,
|
||||
uint32_t constant_index_id) {
|
||||
message_.set_instruction_result_id(instruction_result_id);
|
||||
message_.set_constant_index_id(constant_index_id);
|
||||
}
|
||||
|
||||
bool TransformationMakeVectorOperationDynamic::IsApplicable(
|
||||
opt::IRContext* ir_context, const TransformationContext& /*unused*/) const {
|
||||
// |instruction| must be a vector operation.
|
||||
auto instruction =
|
||||
ir_context->get_def_use_mgr()->GetDef(message_.instruction_result_id());
|
||||
if (!IsVectorOperation(ir_context, instruction)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// |constant_index_instruction| must be defined as an integer instruction.
|
||||
auto constant_index_instruction =
|
||||
ir_context->get_def_use_mgr()->GetDef(message_.constant_index_id());
|
||||
if (!constant_index_instruction || !constant_index_instruction->type_id() ||
|
||||
!ir_context->get_type_mgr()
|
||||
->GetType(constant_index_instruction->type_id())
|
||||
->AsInteger()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TransformationMakeVectorOperationDynamic::Apply(
|
||||
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||
auto instruction =
|
||||
ir_context->get_def_use_mgr()->GetDef(message_.instruction_result_id());
|
||||
|
||||
// The OpVectorInsertDynamic instruction has the vector and component operands
|
||||
// in reverse order in relation to the OpCompositeInsert corresponding
|
||||
// operands.
|
||||
if (instruction->opcode() == SpvOpCompositeInsert) {
|
||||
std::swap(instruction->GetInOperand(0), instruction->GetInOperand(1));
|
||||
}
|
||||
|
||||
// Sets the literal operand to the equivalent constant.
|
||||
instruction->SetInOperand(
|
||||
instruction->opcode() == SpvOpCompositeExtract ? 1 : 2,
|
||||
{message_.constant_index_id()});
|
||||
|
||||
// Sets the |instruction| opcode to the corresponding vector dynamic opcode.
|
||||
instruction->SetOpcode(instruction->opcode() == SpvOpCompositeExtract
|
||||
? SpvOpVectorExtractDynamic
|
||||
: SpvOpVectorInsertDynamic);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationMakeVectorOperationDynamic::ToMessage()
|
||||
const {
|
||||
protobufs::Transformation result;
|
||||
*result.mutable_make_vector_operation_dynamic() = message_;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TransformationMakeVectorOperationDynamic::IsVectorOperation(
|
||||
opt::IRContext* ir_context, opt::Instruction* instruction) {
|
||||
// |instruction| must be defined and must be an OpCompositeExtract/Insert
|
||||
// instruction.
|
||||
if (!instruction || (instruction->opcode() != SpvOpCompositeExtract &&
|
||||
instruction->opcode() != SpvOpCompositeInsert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The composite must be a vector.
|
||||
auto composite_instruction =
|
||||
ir_context->get_def_use_mgr()->GetDef(instruction->GetSingleWordInOperand(
|
||||
instruction->opcode() == SpvOpCompositeExtract ? 0 : 1));
|
||||
if (!ir_context->get_type_mgr()
|
||||
->GetType(composite_instruction->type_id())
|
||||
->AsVector()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
63
source/fuzz/transformation_make_vector_operation_dynamic.h
Normal file
63
source/fuzz/transformation_make_vector_operation_dynamic.h
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2020 André Perez Maselco
|
||||
//
|
||||
// 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 SOURCE_FUZZ_TRANSFORMATION_MAKE_VECTOR_OPERATION_DYNAMIC_H_
|
||||
#define SOURCE_FUZZ_TRANSFORMATION_MAKE_VECTOR_OPERATION_DYNAMIC_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 TransformationMakeVectorOperationDynamic : public Transformation {
|
||||
public:
|
||||
explicit TransformationMakeVectorOperationDynamic(
|
||||
const protobufs::TransformationMakeVectorOperationDynamic& message);
|
||||
|
||||
TransformationMakeVectorOperationDynamic(uint32_t instruction_result_id,
|
||||
uint32_t constant_index_id);
|
||||
|
||||
// - |message_.instruction_result_id| must be the result id of an
|
||||
// OpCompositeExtract/Insert instruction such that the composite operand is a
|
||||
// vector.
|
||||
// - |message_.constant_index_id| must be the result id of an integer
|
||||
// instruction such that its value equals the indexing literal of the
|
||||
// OpCompositeExtract/Insert instruction.
|
||||
bool IsApplicable(
|
||||
opt::IRContext* ir_context,
|
||||
const TransformationContext& transformation_context) const override;
|
||||
|
||||
// Replaces the OpCompositeExtract and OpCompositeInsert instructions with the
|
||||
// OpVectorExtractDynamic and OpVectorInsertDynamic instructions.
|
||||
void Apply(opt::IRContext* ir_context,
|
||||
TransformationContext* transformation_context) const override;
|
||||
|
||||
protobufs::Transformation ToMessage() const override;
|
||||
|
||||
// Checks |instruction| is defined, is an OpCompositeExtract/Insert
|
||||
// instruction and the composite operand is a vector.
|
||||
static bool IsVectorOperation(opt::IRContext* ir_context,
|
||||
opt::Instruction* instruction);
|
||||
|
||||
private:
|
||||
protobufs::TransformationMakeVectorOperationDynamic message_;
|
||||
};
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_FUZZ_TRANSFORMATION_MAKE_VECTOR_OPERATION_DYNAMIC_H_
|
@ -62,6 +62,7 @@ if (${SPIRV_BUILD_FUZZER})
|
||||
transformation_function_call_test.cpp
|
||||
transformation_invert_comparison_operator_test.cpp
|
||||
transformation_load_test.cpp
|
||||
transformation_make_vector_operation_dynamic_test.cpp
|
||||
transformation_merge_blocks_test.cpp
|
||||
transformation_move_block_down_test.cpp
|
||||
transformation_move_instruction_down_test.cpp
|
||||
|
364
test/fuzz/transformation_make_vector_operation_dynamic_test.cpp
Normal file
364
test/fuzz/transformation_make_vector_operation_dynamic_test.cpp
Normal file
@ -0,0 +1,364 @@
|
||||
// Copyright (c) 2020 André Perez Maselco
|
||||
//
|
||||
// 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_make_vector_operation_dynamic.h"
|
||||
#include "source/fuzz/instruction_descriptor.h"
|
||||
#include "test/fuzz/fuzz_test_util.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
namespace {
|
||||
|
||||
TEST(TransformationMakeVectorOperationDynamicTest, IsApplicable) {
|
||||
std::string reference_shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %22 "main"
|
||||
|
||||
; Types
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%4 = OpTypeInt 32 0
|
||||
%5 = OpTypeFloat 32
|
||||
%6 = OpTypeVector %5 2
|
||||
%7 = OpTypeVector %5 3
|
||||
%8 = OpTypeVector %5 4
|
||||
%9 = OpTypeMatrix %6 2
|
||||
|
||||
; Constant scalars
|
||||
%10 = OpConstant %4 0
|
||||
%11 = OpConstant %4 1
|
||||
%12 = OpConstant %4 2
|
||||
%13 = OpConstant %5 0
|
||||
%14 = OpConstant %5 1
|
||||
%15 = OpConstant %5 2
|
||||
%16 = OpConstant %5 3
|
||||
|
||||
; Constant composites
|
||||
%17 = OpConstantComposite %6 %13 %14
|
||||
%18 = OpConstantComposite %6 %15 %16
|
||||
%19 = OpConstantComposite %7 %13 %14 %15
|
||||
%20 = OpConstantComposite %8 %13 %14 %15 %16
|
||||
%21 = OpConstantComposite %9 %17 %18
|
||||
|
||||
; main function
|
||||
%22 = OpFunction %2 None %3
|
||||
%23 = OpLabel
|
||||
%24 = OpCompositeExtract %5 %17 0
|
||||
%25 = OpCompositeExtract %5 %17 1
|
||||
%26 = OpCompositeExtract %5 %18 0
|
||||
%27 = OpCompositeExtract %5 %18 1
|
||||
%28 = OpCompositeExtract %5 %19 0
|
||||
%29 = OpCompositeExtract %5 %19 1
|
||||
%30 = OpCompositeExtract %5 %19 2
|
||||
%31 = OpCompositeExtract %5 %20 0
|
||||
%32 = OpCompositeExtract %5 %20 1
|
||||
%33 = OpCompositeExtract %5 %20 2
|
||||
%34 = OpCompositeExtract %5 %20 3
|
||||
%35 = OpCompositeExtract %6 %21 0
|
||||
%36 = OpCompositeExtract %6 %21 1
|
||||
%37 = OpCompositeInsert %6 %15 %17 0
|
||||
%38 = OpCompositeInsert %6 %16 %17 1
|
||||
%39 = OpCompositeInsert %6 %13 %18 0
|
||||
%40 = OpCompositeInsert %6 %14 %18 1
|
||||
%41 = OpCompositeInsert %7 %13 %19 0
|
||||
%42 = OpCompositeInsert %7 %14 %19 1
|
||||
%43 = OpCompositeInsert %7 %15 %19 2
|
||||
%44 = OpCompositeInsert %8 %13 %20 0
|
||||
%45 = OpCompositeInsert %8 %14 %20 1
|
||||
%46 = OpCompositeInsert %8 %15 %20 2
|
||||
%47 = OpCompositeInsert %8 %16 %20 3
|
||||
%48 = OpCompositeInsert %9 %17 %21 0
|
||||
%49 = OpCompositeInsert %9 %18 %21 1
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_5;
|
||||
const auto consumer = nullptr;
|
||||
const auto context =
|
||||
BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
|
||||
// Tests undefined instruction.
|
||||
auto transformation = TransformationMakeVectorOperationDynamic(50, 10);
|
||||
ASSERT_FALSE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
// Tests non-composite instruction.
|
||||
transformation = TransformationMakeVectorOperationDynamic(23, 11);
|
||||
ASSERT_FALSE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
// Tests composite being a matrix.
|
||||
transformation = TransformationMakeVectorOperationDynamic(48, 12);
|
||||
ASSERT_FALSE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
// Tests literal not defined as constant.
|
||||
transformation = TransformationMakeVectorOperationDynamic(34, 51);
|
||||
ASSERT_FALSE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
// Tests applicable instructions.
|
||||
transformation = TransformationMakeVectorOperationDynamic(24, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(25, 11);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(26, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(37, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(38, 11);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(39, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
}
|
||||
|
||||
TEST(TransformationMakeVectorOperationDynamicTest, Apply) {
|
||||
std::string reference_shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %20 "main"
|
||||
|
||||
; Types
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%4 = OpTypeInt 32 0
|
||||
%5 = OpTypeFloat 32
|
||||
%6 = OpTypeVector %5 2
|
||||
%7 = OpTypeVector %5 3
|
||||
%8 = OpTypeVector %5 4
|
||||
|
||||
; Constant scalars
|
||||
%9 = OpConstant %4 0
|
||||
%10 = OpConstant %4 1
|
||||
%11 = OpConstant %4 2
|
||||
%12 = OpConstant %4 3
|
||||
%13 = OpConstant %5 0
|
||||
%14 = OpConstant %5 1
|
||||
%15 = OpConstant %5 2
|
||||
%16 = OpConstant %5 3
|
||||
|
||||
; Constant vectors
|
||||
%17 = OpConstantComposite %6 %13 %14
|
||||
%18 = OpConstantComposite %7 %13 %14 %15
|
||||
%19 = OpConstantComposite %8 %13 %14 %15 %16
|
||||
|
||||
; main function
|
||||
%20 = OpFunction %2 None %3
|
||||
%21 = OpLabel
|
||||
%22 = OpCompositeExtract %5 %17 0
|
||||
%23 = OpCompositeExtract %5 %17 1
|
||||
%24 = OpCompositeExtract %5 %18 0
|
||||
%25 = OpCompositeExtract %5 %18 1
|
||||
%26 = OpCompositeExtract %5 %18 2
|
||||
%27 = OpCompositeExtract %5 %19 0
|
||||
%28 = OpCompositeExtract %5 %19 1
|
||||
%29 = OpCompositeExtract %5 %19 2
|
||||
%30 = OpCompositeExtract %5 %19 3
|
||||
%31 = OpCompositeInsert %6 %13 %17 0
|
||||
%32 = OpCompositeInsert %6 %14 %17 1
|
||||
%33 = OpCompositeInsert %7 %13 %18 0
|
||||
%34 = OpCompositeInsert %7 %14 %18 1
|
||||
%35 = OpCompositeInsert %7 %15 %18 2
|
||||
%36 = OpCompositeInsert %8 %13 %19 0
|
||||
%37 = OpCompositeInsert %8 %14 %19 1
|
||||
%38 = OpCompositeInsert %8 %15 %19 2
|
||||
%39 = OpCompositeInsert %8 %16 %19 3
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_5;
|
||||
const auto consumer = nullptr;
|
||||
const auto context =
|
||||
BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
|
||||
auto transformation = TransformationMakeVectorOperationDynamic(22, 9);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(23, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(24, 9);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(25, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(26, 11);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(27, 9);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(28, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(29, 11);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(30, 12);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(31, 9);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(32, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(33, 9);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(34, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(35, 11);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(36, 9);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(37, 10);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(38, 11);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
transformation = TransformationMakeVectorOperationDynamic(39, 12);
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
transformation.Apply(context.get(), &transformation_context);
|
||||
|
||||
std::string variant_shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %20 "main"
|
||||
|
||||
; Types
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%4 = OpTypeInt 32 0
|
||||
%5 = OpTypeFloat 32
|
||||
%6 = OpTypeVector %5 2
|
||||
%7 = OpTypeVector %5 3
|
||||
%8 = OpTypeVector %5 4
|
||||
|
||||
; Constant scalars
|
||||
%9 = OpConstant %4 0
|
||||
%10 = OpConstant %4 1
|
||||
%11 = OpConstant %4 2
|
||||
%12 = OpConstant %4 3
|
||||
%13 = OpConstant %5 0
|
||||
%14 = OpConstant %5 1
|
||||
%15 = OpConstant %5 2
|
||||
%16 = OpConstant %5 3
|
||||
|
||||
; Constant vectors
|
||||
%17 = OpConstantComposite %6 %13 %14
|
||||
%18 = OpConstantComposite %7 %13 %14 %15
|
||||
%19 = OpConstantComposite %8 %13 %14 %15 %16
|
||||
|
||||
; main function
|
||||
%20 = OpFunction %2 None %3
|
||||
%21 = OpLabel
|
||||
%22 = OpVectorExtractDynamic %5 %17 %9
|
||||
%23 = OpVectorExtractDynamic %5 %17 %10
|
||||
%24 = OpVectorExtractDynamic %5 %18 %9
|
||||
%25 = OpVectorExtractDynamic %5 %18 %10
|
||||
%26 = OpVectorExtractDynamic %5 %18 %11
|
||||
%27 = OpVectorExtractDynamic %5 %19 %9
|
||||
%28 = OpVectorExtractDynamic %5 %19 %10
|
||||
%29 = OpVectorExtractDynamic %5 %19 %11
|
||||
%30 = OpVectorExtractDynamic %5 %19 %12
|
||||
%31 = OpVectorInsertDynamic %6 %17 %13 %9
|
||||
%32 = OpVectorInsertDynamic %6 %17 %14 %10
|
||||
%33 = OpVectorInsertDynamic %7 %18 %13 %9
|
||||
%34 = OpVectorInsertDynamic %7 %18 %14 %10
|
||||
%35 = OpVectorInsertDynamic %7 %18 %15 %11
|
||||
%36 = OpVectorInsertDynamic %8 %19 %13 %9
|
||||
%37 = OpVectorInsertDynamic %8 %19 %14 %10
|
||||
%38 = OpVectorInsertDynamic %8 %19 %15 %11
|
||||
%39 = OpVectorInsertDynamic %8 %19 %16 %12
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
Loading…
Reference in New Issue
Block a user