blob: ae5c4af511181fd7626f72df4a7251b572201ed0 [file] [log] [blame]
// 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_expand_vector_reduction.h"
#include "gtest/gtest.h"
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/instruction_descriptor.h"
#include "test/fuzz/fuzz_test_util.h"
namespace spvtools {
namespace fuzz {
namespace {
TEST(TransformationExpandVectorReductionTest, IsApplicable) {
std::string reference_shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %9 "main"
; Types
%2 = OpTypeBool
%3 = OpTypeVector %2 2
%4 = OpTypeVoid
%5 = OpTypeFunction %4
; Constants
%6 = OpConstantTrue %2
%7 = OpConstantFalse %2
%8 = OpConstantComposite %3 %6 %7
; main function
%9 = OpFunction %4 None %5
%10 = OpLabel
%11 = OpAny %2 %8
%12 = OpAll %2 %8
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_5;
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
// Tests undefined instruction.
auto transformation = TransformationExpandVectorReduction(13, {14, 15, 16});
ASSERT_FALSE(
transformation.IsApplicable(context.get(), transformation_context));
// Tests non OpAny or OpAll instruction.
transformation = TransformationExpandVectorReduction(10, {13, 14, 15});
ASSERT_FALSE(
transformation.IsApplicable(context.get(), transformation_context));
// Tests the number of fresh ids being different than the necessary.
transformation = TransformationExpandVectorReduction(11, {13, 14});
ASSERT_FALSE(
transformation.IsApplicable(context.get(), transformation_context));
transformation = TransformationExpandVectorReduction(12, {13, 14, 15, 16});
ASSERT_FALSE(
transformation.IsApplicable(context.get(), transformation_context));
// Tests non-fresh ids.
transformation = TransformationExpandVectorReduction(11, {12, 13, 14});
ASSERT_FALSE(
transformation.IsApplicable(context.get(), transformation_context));
// Tests duplicated fresh ids.
transformation = TransformationExpandVectorReduction(11, {13, 13, 14});
ASSERT_FALSE(
transformation.IsApplicable(context.get(), transformation_context));
// Tests applicable transformations.
transformation = TransformationExpandVectorReduction(11, {13, 14, 15});
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
transformation = TransformationExpandVectorReduction(12, {13, 14, 15});
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationExpandVectorReductionTest, Apply) {
std::string reference_shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %13 "main"
; Types
%2 = OpTypeBool
%3 = OpTypeVector %2 2
%4 = OpTypeVector %2 3
%5 = OpTypeVector %2 4
%6 = OpTypeVoid
%7 = OpTypeFunction %6
; Constants
%8 = OpConstantTrue %2
%9 = OpConstantFalse %2
%10 = OpConstantComposite %3 %8 %9
%11 = OpConstantComposite %4 %8 %9 %8
%12 = OpConstantComposite %5 %8 %9 %8 %9
; main function
%13 = OpFunction %6 None %7
%14 = OpLabel
; OpAny for 2-dimensional vector
%15 = OpAny %2 %10
; OpAny for 3-dimensional vector
%16 = OpAny %2 %11
; OpAny for 4-dimensional vector
%17 = OpAny %2 %12
; OpAll for 2-dimensional vector
%18 = OpAll %2 %10
; OpAll for 3-dimensional vector
%19 = OpAll %2 %11
; OpAll for 4-dimensional vector
%20 = OpAll %2 %12
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_5;
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
// Adds OpAny synonym for 2-dimensional vector.
auto transformation = TransformationExpandVectorReduction(15, {21, 22, 23});
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(23, {}), MakeDataDescriptor(15, {})));
// Adds OpAny synonym for 3-dimensional vector.
transformation =
TransformationExpandVectorReduction(16, {24, 25, 26, 27, 28});
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(28, {}), MakeDataDescriptor(16, {})));
// Adds OpAny synonym for 4-dimensional vector.
transformation =
TransformationExpandVectorReduction(17, {29, 30, 31, 32, 33, 34, 35});
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(35, {}), MakeDataDescriptor(17, {})));
// Adds OpAll synonym for 2-dimensional vector.
transformation = TransformationExpandVectorReduction(18, {36, 37, 38});
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(38, {}), MakeDataDescriptor(18, {})));
// Adds OpAll synonym for 3-dimensional vector.
transformation =
TransformationExpandVectorReduction(19, {39, 40, 41, 42, 43});
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(43, {}), MakeDataDescriptor(19, {})));
// Adds OpAll synonym for 4-dimensional vector.
transformation =
TransformationExpandVectorReduction(20, {44, 45, 46, 47, 48, 49, 50});
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(50, {}), MakeDataDescriptor(20, {})));
std::string variant_shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %13 "main"
; Types
%2 = OpTypeBool
%3 = OpTypeVector %2 2
%4 = OpTypeVector %2 3
%5 = OpTypeVector %2 4
%6 = OpTypeVoid
%7 = OpTypeFunction %6
; Constants
%8 = OpConstantTrue %2
%9 = OpConstantFalse %2
%10 = OpConstantComposite %3 %8 %9
%11 = OpConstantComposite %4 %8 %9 %8
%12 = OpConstantComposite %5 %8 %9 %8 %9
; main function
%13 = OpFunction %6 None %7
%14 = OpLabel
; Add OpAny synonym for 2-dimensional vector
%21 = OpCompositeExtract %2 %10 0
%22 = OpCompositeExtract %2 %10 1
%23 = OpLogicalOr %2 %21 %22
%15 = OpAny %2 %10
; Add OpAny synonym for 3-dimensional vector
%24 = OpCompositeExtract %2 %11 0
%25 = OpCompositeExtract %2 %11 1
%26 = OpCompositeExtract %2 %11 2
%27 = OpLogicalOr %2 %24 %25
%28 = OpLogicalOr %2 %26 %27
%16 = OpAny %2 %11
; Add OpAny synonym for 4-dimensional vector
%29 = OpCompositeExtract %2 %12 0
%30 = OpCompositeExtract %2 %12 1
%31 = OpCompositeExtract %2 %12 2
%32 = OpCompositeExtract %2 %12 3
%33 = OpLogicalOr %2 %29 %30
%34 = OpLogicalOr %2 %31 %33
%35 = OpLogicalOr %2 %32 %34
%17 = OpAny %2 %12
; Add OpAll synonym for 2-dimensional vector
%36 = OpCompositeExtract %2 %10 0
%37 = OpCompositeExtract %2 %10 1
%38 = OpLogicalAnd %2 %36 %37
%18 = OpAll %2 %10
; Add OpAll synonym for 3-dimensional vector
%39 = OpCompositeExtract %2 %11 0
%40 = OpCompositeExtract %2 %11 1
%41 = OpCompositeExtract %2 %11 2
%42 = OpLogicalAnd %2 %39 %40
%43 = OpLogicalAnd %2 %41 %42
%19 = OpAll %2 %11
; Add OpAll synonym for 4-dimensional vector
%44 = OpCompositeExtract %2 %12 0
%45 = OpCompositeExtract %2 %12 1
%46 = OpCompositeExtract %2 %12 2
%47 = OpCompositeExtract %2 %12 3
%48 = OpLogicalAnd %2 %44 %45
%49 = OpLogicalAnd %2 %46 %48
%50 = OpLogicalAnd %2 %47 %49
%20 = OpAll %2 %12
OpReturn
OpFunctionEnd
)";
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
}
} // namespace
} // namespace fuzz
} // namespace spvtools