spirv-fuzz: Add TransformationMakeVectorOperationDynamic (#3597)

Fixes #3588.
This commit is contained in:
André Perez 2020-08-06 11:50:18 -03:00 committed by GitHub
parent d29eac95aa
commit 6d7f34fbfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 687 additions and 0 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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_;

View 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

View 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_

View File

@ -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.

View File

@ -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:

View 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

View 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_

View File

@ -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

View 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