mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-27 01:21:25 +00:00
Implement transformation to record synonymous constants. (#3494)
Adds a fact-only transformation that records that two constants in the module are synonymous.
This commit is contained in:
parent
94667fbf66
commit
5f8cdd8b45
@ -128,6 +128,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
transformation_permute_function_parameters.h
|
||||
transformation_permute_phi_operands.h
|
||||
transformation_push_id_through_variable.h
|
||||
transformation_record_synonymous_constants.h
|
||||
transformation_replace_boolean_constant_with_constant_binary.h
|
||||
transformation_replace_constant_with_uniform.h
|
||||
transformation_replace_id_with_synonym.h
|
||||
@ -243,6 +244,7 @@ if(SPIRV_BUILD_FUZZER)
|
||||
transformation_permute_function_parameters.cpp
|
||||
transformation_permute_phi_operands.cpp
|
||||
transformation_push_id_through_variable.cpp
|
||||
transformation_record_synonymous_constants.cpp
|
||||
transformation_replace_boolean_constant_with_constant_binary.cpp
|
||||
transformation_replace_constant_with_uniform.cpp
|
||||
transformation_replace_id_with_synonym.cpp
|
||||
|
@ -385,6 +385,7 @@ message Transformation {
|
||||
TransformationInvertComparisonOperator invert_comparison_operator = 54;
|
||||
TransformationAddImageSampleUnusedComponents add_image_sample_unused_components = 55;
|
||||
TransformationReplaceParameterWithGlobal replace_parameter_with_global = 56;
|
||||
TransformationRecordSynonymousConstants record_synonymous_constants = 57;
|
||||
// Add additional option using the next available number.
|
||||
}
|
||||
}
|
||||
@ -1123,6 +1124,26 @@ message TransformationPushIdThroughVariable {
|
||||
|
||||
}
|
||||
|
||||
message TransformationRecordSynonymousConstants {
|
||||
|
||||
// A transformation that, given the IDs to two synonymous constants,
|
||||
// records the fact that they are synonymous. The module is not changed.
|
||||
// Two constants are synonymous if:
|
||||
// - they have the same type (ignoring the presence of integer sign)
|
||||
// - they have the same opcode (one of OpConstant, OpConstantTrue,
|
||||
// OpConstantFalse, OpConstantNull)
|
||||
// - they have the same value
|
||||
// If the types are the same, OpConstantNull is equivalent to
|
||||
// OpConstantFalse or OpConstant with value zero.
|
||||
|
||||
// The id of a constant
|
||||
uint32 constant1_id = 1;
|
||||
|
||||
// The id of the synonym
|
||||
uint32 constant2_id = 2;
|
||||
|
||||
}
|
||||
|
||||
message TransformationReplaceParameterWithGlobal {
|
||||
|
||||
// Removes parameter with result id |parameter_id| from its function
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "source/fuzz/transformation_permute_function_parameters.h"
|
||||
#include "source/fuzz/transformation_permute_phi_operands.h"
|
||||
#include "source/fuzz/transformation_push_id_through_variable.h"
|
||||
#include "source/fuzz/transformation_record_synonymous_constants.h"
|
||||
#include "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h"
|
||||
#include "source/fuzz/transformation_replace_constant_with_uniform.h"
|
||||
#include "source/fuzz/transformation_replace_id_with_synonym.h"
|
||||
@ -194,6 +195,10 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
|
||||
case protobufs::Transformation::TransformationCase::kPushIdThroughVariable:
|
||||
return MakeUnique<TransformationPushIdThroughVariable>(
|
||||
message.push_id_through_variable());
|
||||
case protobufs::Transformation::TransformationCase::
|
||||
kRecordSynonymousConstants:
|
||||
return MakeUnique<TransformationRecordSynonymousConstants>(
|
||||
message.record_synonymous_constants());
|
||||
case protobufs::Transformation::TransformationCase::
|
||||
kReplaceParameterWithGlobal:
|
||||
return MakeUnique<TransformationReplaceParameterWithGlobal>(
|
||||
|
107
source/fuzz/transformation_record_synonymous_constants.cpp
Normal file
107
source/fuzz/transformation_record_synonymous_constants.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2020 Stefano Milizia
|
||||
// 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 "transformation_record_synonymous_constants.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
namespace {
|
||||
bool IsScalarZeroConstant(const opt::analysis::Constant* constant) {
|
||||
return constant->AsScalarConstant() && constant->IsZero();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TransformationRecordSynonymousConstants::
|
||||
TransformationRecordSynonymousConstants(
|
||||
const protobufs::TransformationRecordSynonymousConstants& message)
|
||||
: message_(message) {}
|
||||
|
||||
TransformationRecordSynonymousConstants::
|
||||
TransformationRecordSynonymousConstants(uint32_t constant1_id,
|
||||
uint32_t constant2_id) {
|
||||
message_.set_constant1_id(constant1_id);
|
||||
message_.set_constant2_id(constant2_id);
|
||||
}
|
||||
|
||||
bool TransformationRecordSynonymousConstants::IsApplicable(
|
||||
opt::IRContext* ir_context,
|
||||
const TransformationContext& /* unused */) const {
|
||||
// The ids must be different
|
||||
if (message_.constant1_id() == message_.constant2_id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto constant1 = ir_context->get_constant_mgr()->FindDeclaredConstant(
|
||||
message_.constant1_id());
|
||||
auto constant2 = ir_context->get_constant_mgr()->FindDeclaredConstant(
|
||||
message_.constant2_id());
|
||||
|
||||
// The constants must exist
|
||||
if (constant1 == nullptr || constant2 == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the constants are equal, then they are equivalent
|
||||
if (constant1 == constant2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the constants are two integers (signed or unsigned), they are equal
|
||||
// if they have the same width and the same data words.
|
||||
if (constant1->AsIntConstant() && constant2->AsIntConstant() &&
|
||||
constant1->type()->AsInteger()->width() ==
|
||||
constant2->type()->AsInteger()->width() &&
|
||||
constant1->AsIntConstant()->words() ==
|
||||
constant2->AsIntConstant()->words()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The types must be the same
|
||||
if (!constant1->type()->IsSame(constant2->type())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The constants are equivalent if one is null and the other is a static
|
||||
// constant with value 0.
|
||||
return (constant1->AsNullConstant() && IsScalarZeroConstant(constant2)) ||
|
||||
(IsScalarZeroConstant(constant1) && constant2->AsNullConstant());
|
||||
}
|
||||
|
||||
void TransformationRecordSynonymousConstants::Apply(
|
||||
opt::IRContext* ir_context,
|
||||
TransformationContext* transformation_context) const {
|
||||
protobufs::FactDataSynonym fact_data_synonym;
|
||||
// Define the two equivalent data descriptors (just containing the ids)
|
||||
*fact_data_synonym.mutable_data1() =
|
||||
MakeDataDescriptor(message_.constant1_id(), {});
|
||||
*fact_data_synonym.mutable_data2() =
|
||||
MakeDataDescriptor(message_.constant2_id(), {});
|
||||
protobufs::Fact fact;
|
||||
*fact.mutable_data_synonym_fact() = fact_data_synonym;
|
||||
|
||||
// Add the fact to the fact manager
|
||||
transformation_context->GetFactManager()->AddFact(fact, ir_context);
|
||||
}
|
||||
|
||||
protobufs::Transformation TransformationRecordSynonymousConstants::ToMessage()
|
||||
const {
|
||||
protobufs::Transformation result;
|
||||
*result.mutable_record_synonymous_constants() = message_;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
59
source/fuzz/transformation_record_synonymous_constants.h
Normal file
59
source/fuzz/transformation_record_synonymous_constants.h
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2020 Stefano Milizia
|
||||
// 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 SOURCE_FUZZ_TRANSFORMATION_RECORD_SYNONYMOUS_CONSTANTS_H
|
||||
#define SOURCE_FUZZ_TRANSFORMATION_RECORD_SYNONYMOUS_CONSTANTS_H
|
||||
|
||||
#include "source/fuzz/transformation.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
|
||||
class TransformationRecordSynonymousConstants : public Transformation {
|
||||
public:
|
||||
explicit TransformationRecordSynonymousConstants(
|
||||
const protobufs::TransformationRecordSynonymousConstants& message);
|
||||
|
||||
TransformationRecordSynonymousConstants(uint32_t constant1_id,
|
||||
uint32_t constant2_id);
|
||||
|
||||
// - |message_.constant_id| and |message_.synonym_id| are distinct ids
|
||||
// of constants
|
||||
// - |message_.constant_id| and |message_.synonym_id| refer to constants
|
||||
// that are equal or equivalent.
|
||||
// Two integers with the same width and value are equal, even if one is
|
||||
// signed and the other is not.
|
||||
// Constants are equivalent if both of them represent zero-like scalar
|
||||
// values of the same type (for example OpConstant of type int and value
|
||||
// 0 and OpConstantNull of type int).
|
||||
bool IsApplicable(
|
||||
opt::IRContext* ir_context,
|
||||
const TransformationContext& transformation_context) const override;
|
||||
|
||||
// Adds the fact that |message_.constant_id| and |message_.synonym_id|
|
||||
// are synonyms to the fact manager. The module is not changed.
|
||||
void Apply(opt::IRContext* ir_context,
|
||||
TransformationContext* transformation_context) const override;
|
||||
|
||||
protobufs::Transformation ToMessage() const override;
|
||||
|
||||
private:
|
||||
protobufs::TransformationRecordSynonymousConstants message_;
|
||||
};
|
||||
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_FUZZ_TRANSFORMATION_RECORD_SYNONYMOUS_CONSTANTS
|
@ -78,6 +78,7 @@ if (${SPIRV_BUILD_FUZZER})
|
||||
transformation_swap_commutable_operands_test.cpp
|
||||
transformation_swap_conditional_branch_operands_test.cpp
|
||||
transformation_toggle_access_chain_instruction_test.cpp
|
||||
transformation_record_synonymous_constants_test.cpp
|
||||
transformation_vector_shuffle_test.cpp
|
||||
uniform_buffer_element_descriptor_test.cpp)
|
||||
|
||||
|
325
test/fuzz/transformation_record_synonymous_constants_test.cpp
Normal file
325
test/fuzz/transformation_record_synonymous_constants_test.cpp
Normal file
@ -0,0 +1,325 @@
|
||||
// Copyright (c) 2020 Stefano Milizia
|
||||
// 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_record_synonymous_constants.h"
|
||||
|
||||
#include "test/fuzz/fuzz_test_util.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace fuzz {
|
||||
namespace {
|
||||
|
||||
// Apply the TransformationRecordSynonymousConstants defined by the given
|
||||
// constant1_id and constant2_id and check that the fact that the two
|
||||
// constants are synonym is recorded.
|
||||
void ApplyTransformationAndCheckFactManager(
|
||||
uint32_t constant1_id, uint32_t constant2_id, opt::IRContext* ir_context,
|
||||
TransformationContext* transformation_context) {
|
||||
TransformationRecordSynonymousConstants(constant1_id, constant2_id)
|
||||
.Apply(ir_context, transformation_context);
|
||||
|
||||
ASSERT_TRUE(transformation_context->GetFactManager()->IsSynonymous(
|
||||
MakeDataDescriptor(constant1_id, {}),
|
||||
MakeDataDescriptor(constant2_id, {})));
|
||||
}
|
||||
|
||||
TEST(TransformationRecordSynonymousConstantsTest, IntConstants) {
|
||||
std::string shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main" %17
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
OpName %4 "main"
|
||||
OpName %8 "a"
|
||||
OpName %10 "b"
|
||||
OpName %12 "c"
|
||||
OpName %17 "color"
|
||||
OpDecorate %8 RelaxedPrecision
|
||||
OpDecorate %10 RelaxedPrecision
|
||||
OpDecorate %12 RelaxedPrecision
|
||||
OpDecorate %17 Location 0
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeInt 32 0
|
||||
%19 = OpTypeInt 32 1
|
||||
%7 = OpTypePointer Function %6
|
||||
%9 = OpConstant %6 0
|
||||
%18 = OpConstant %6 0
|
||||
%11 = OpConstantNull %6
|
||||
%13 = OpConstant %6 1
|
||||
%20 = OpConstant %19 1
|
||||
%21 = OpConstant %19 -1
|
||||
%22 = OpConstant %6 1
|
||||
%14 = OpTypeFloat 32
|
||||
%15 = OpTypeVector %14 4
|
||||
%16 = OpTypePointer Output %15
|
||||
%17 = OpVariable %16 Output
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
%8 = OpVariable %7 Function
|
||||
%10 = OpVariable %7 Function
|
||||
%12 = OpVariable %7 Function
|
||||
OpStore %8 %9
|
||||
OpStore %10 %11
|
||||
OpStore %12 %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_4;
|
||||
const auto consumer = nullptr;
|
||||
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
// %3 is not a constant declaration
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(3, 9).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// Swapping the ids gives the same result
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(9, 3).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// The two constants must be different
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(9, 9).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %9 and %13 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(9, 13).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// Swapping the ids gives the same result
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(13, 9).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %11 and %13 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(11, 13).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// Swapping the ids gives the same result
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(13, 11).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %20 and %21 have different values
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(20, 21).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %13 and %22 are equal and thus equivalent (having the same value and type)
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(13, 22).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(13, 22, context.get(),
|
||||
&transformation_context);
|
||||
|
||||
// %13 and %20 are equal even if %13 is signed and %20 is unsigned
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(13, 20).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(13, 20, context.get(),
|
||||
&transformation_context);
|
||||
|
||||
// %9 and %11 are equivalent (OpConstant with value 0 and OpConstantNull)
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(9, 11).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(9, 11, context.get(),
|
||||
&transformation_context);
|
||||
|
||||
// Swapping the ids gives the same result
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(11, 9).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(11, 9, context.get(),
|
||||
&transformation_context);
|
||||
}
|
||||
|
||||
TEST(TransformationRecordSynonymousConstantsTest, BoolConstants) {
|
||||
std::string shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main" %19
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
OpName %4 "main"
|
||||
OpName %8 "b"
|
||||
OpName %19 "color"
|
||||
OpDecorate %19 Location 0
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeBool
|
||||
%7 = OpTypePointer Function %6
|
||||
%9 = OpConstantFalse %6
|
||||
%20 = OpConstantNull %6
|
||||
%11 = OpConstantTrue %6
|
||||
%21 = OpConstantFalse %6
|
||||
%22 = OpConstantTrue %6
|
||||
%16 = OpTypeFloat 32
|
||||
%17 = OpTypeVector %16 4
|
||||
%18 = OpTypePointer Output %17
|
||||
%19 = OpVariable %18 Output
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
%8 = OpVariable %7 Function
|
||||
OpStore %8 %9
|
||||
%10 = OpLoad %6 %8
|
||||
%12 = OpLogicalEqual %6 %10 %11
|
||||
OpSelectionMerge %14 None
|
||||
OpBranchConditional %12 %13 %14
|
||||
%13 = OpLabel
|
||||
OpReturn
|
||||
%14 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_4;
|
||||
const auto consumer = nullptr;
|
||||
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
// %9 and %11 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(9, 11).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %20 and %11 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(20, 11).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %9 and %21 are equivalent (both OpConstantFalse)
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(9, 21).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(9, 21, context.get(),
|
||||
&transformation_context);
|
||||
|
||||
// %11 and %22 are equivalent (both OpConstantTrue)
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(11, 22).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(11, 22, context.get(),
|
||||
&transformation_context);
|
||||
|
||||
// %9 and %20 are equivalent (OpConstantFalse and boolean OpConstantNull)
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(9, 20).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(9, 20, context.get(),
|
||||
&transformation_context);
|
||||
}
|
||||
|
||||
TEST(TransformationRecordSynonymousConstantsTest, FloatConstants) {
|
||||
std::string shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main" %22
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
OpName %4 "main"
|
||||
OpName %8 "a"
|
||||
OpName %10 "b"
|
||||
OpName %12 "c"
|
||||
OpName %22 "color"
|
||||
OpDecorate %22 Location 0
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 32
|
||||
%7 = OpTypePointer Function %6
|
||||
%9 = OpConstant %6 0
|
||||
%11 = OpConstantNull %6
|
||||
%13 = OpConstant %6 2
|
||||
%26 = OpConstant %6 2
|
||||
%16 = OpTypeBool
|
||||
%20 = OpTypeVector %6 4
|
||||
%21 = OpTypePointer Output %20
|
||||
%22 = OpVariable %21 Output
|
||||
%23 = OpConstantComposite %20 %9 %11 %9 %11
|
||||
%25 = OpConstantComposite %20 %11 %9 %9 %11
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
%8 = OpVariable %7 Function
|
||||
%10 = OpVariable %7 Function
|
||||
%12 = OpVariable %7 Function
|
||||
OpStore %8 %9
|
||||
OpStore %10 %11
|
||||
OpStore %12 %13
|
||||
%14 = OpLoad %6 %8
|
||||
%15 = OpLoad %6 %10
|
||||
%17 = OpFOrdEqual %16 %14 %15
|
||||
OpSelectionMerge %19 None
|
||||
OpBranchConditional %17 %18 %24
|
||||
%18 = OpLabel
|
||||
OpStore %22 %23
|
||||
OpBranch %19
|
||||
%24 = OpLabel
|
||||
OpStore %22 %25
|
||||
OpBranch %19
|
||||
%19 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_4;
|
||||
const auto consumer = nullptr;
|
||||
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
// %9 and %13 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(9, 13).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %11 and %13 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(11, 13).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %13 and %23 are not equivalent
|
||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(13, 23).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
// %13 and %26 are identical float constants
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(13, 26).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(13, 26, context.get(),
|
||||
&transformation_context);
|
||||
|
||||
// %9 and %11 are equivalent ()
|
||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(9, 11).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
ApplyTransformationAndCheckFactManager(9, 11, context.get(),
|
||||
&transformation_context);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
@ -35,7 +35,8 @@ AUTHORS = ['The Khronos Group Inc.',
|
||||
'Samsung Inc',
|
||||
'André Perez Maselco',
|
||||
'Vasyl Teliman',
|
||||
'Advanced Micro Devices, Inc.']
|
||||
'Advanced Micro Devices, Inc.',
|
||||
'Stefano Milizia']
|
||||
CURRENT_YEAR='2020'
|
||||
|
||||
YEARS = '(2014-2016|2015-2016|2015-2020|2016|2016-2017|2017|2017-2019|2018|2019|2020)'
|
||||
|
Loading…
Reference in New Issue
Block a user