mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
parent
7c213720bb
commit
c01f826bc6
@ -90,6 +90,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
transformation_add_global_variable.h
|
transformation_add_global_variable.h
|
||||||
transformation_add_local_variable.h
|
transformation_add_local_variable.h
|
||||||
transformation_add_no_contraction_decoration.h
|
transformation_add_no_contraction_decoration.h
|
||||||
|
transformation_add_spec_constant_op.h
|
||||||
transformation_add_type_array.h
|
transformation_add_type_array.h
|
||||||
transformation_add_type_boolean.h
|
transformation_add_type_boolean.h
|
||||||
transformation_add_type_float.h
|
transformation_add_type_float.h
|
||||||
@ -187,6 +188,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
transformation_add_global_variable.cpp
|
transformation_add_global_variable.cpp
|
||||||
transformation_add_local_variable.cpp
|
transformation_add_local_variable.cpp
|
||||||
transformation_add_no_contraction_decoration.cpp
|
transformation_add_no_contraction_decoration.cpp
|
||||||
|
transformation_add_spec_constant_op.cpp
|
||||||
transformation_add_type_array.cpp
|
transformation_add_type_array.cpp
|
||||||
transformation_add_type_boolean.cpp
|
transformation_add_type_boolean.cpp
|
||||||
transformation_add_type_float.cpp
|
transformation_add_type_float.cpp
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "source/fuzz/transformation_add_function.h"
|
#include "source/fuzz/transformation_add_function.h"
|
||||||
#include "source/fuzz/transformation_add_global_undef.h"
|
#include "source/fuzz/transformation_add_global_undef.h"
|
||||||
#include "source/fuzz/transformation_add_global_variable.h"
|
#include "source/fuzz/transformation_add_global_variable.h"
|
||||||
|
#include "source/fuzz/transformation_add_spec_constant_op.h"
|
||||||
#include "source/fuzz/transformation_add_type_array.h"
|
#include "source/fuzz/transformation_add_type_array.h"
|
||||||
#include "source/fuzz/transformation_add_type_boolean.h"
|
#include "source/fuzz/transformation_add_type_boolean.h"
|
||||||
#include "source/fuzz/transformation_add_type_float.h"
|
#include "source/fuzz/transformation_add_type_float.h"
|
||||||
@ -413,14 +414,41 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
|
|||||||
argument_type_ids));
|
argument_type_ids));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case SpvOpSpecConstantOp: {
|
||||||
|
new_result_id = GetFuzzerContext()->GetFreshId();
|
||||||
|
auto type_id = original_id_to_donated_id->at(type_or_value.type_id());
|
||||||
|
auto opcode = static_cast<SpvOp>(type_or_value.GetSingleWordInOperand(0));
|
||||||
|
|
||||||
|
// Make sure we take into account |original_id_to_donated_id| when
|
||||||
|
// computing operands for OpSpecConstantOp.
|
||||||
|
opt::Instruction::OperandList operands;
|
||||||
|
for (uint32_t i = 1; i < type_or_value.NumInOperands(); ++i) {
|
||||||
|
const auto& operand = type_or_value.GetInOperand(i);
|
||||||
|
auto data =
|
||||||
|
operand.type == SPV_OPERAND_TYPE_ID
|
||||||
|
? opt::Operand::OperandData{original_id_to_donated_id->at(
|
||||||
|
operand.words[0])}
|
||||||
|
: operand.words;
|
||||||
|
|
||||||
|
operands.push_back({operand.type, std::move(data)});
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyTransformation(TransformationAddSpecConstantOp(
|
||||||
|
new_result_id, type_id, opcode, std::move(operands)));
|
||||||
|
} break;
|
||||||
|
case SpvOpSpecConstantTrue:
|
||||||
|
case SpvOpSpecConstantFalse:
|
||||||
case SpvOpConstantTrue:
|
case SpvOpConstantTrue:
|
||||||
case SpvOpConstantFalse: {
|
case SpvOpConstantFalse: {
|
||||||
// It is OK to have duplicate definitions of True and False, so add
|
// It is OK to have duplicate definitions of True and False, so add
|
||||||
// these to the module, using a remapped Bool type.
|
// these to the module, using a remapped Bool type.
|
||||||
new_result_id = GetFuzzerContext()->GetFreshId();
|
new_result_id = GetFuzzerContext()->GetFreshId();
|
||||||
ApplyTransformation(TransformationAddConstantBoolean(
|
auto value = type_or_value.opcode() == SpvOpConstantTrue ||
|
||||||
new_result_id, type_or_value.opcode() == SpvOpConstantTrue));
|
type_or_value.opcode() == SpvOpSpecConstantTrue;
|
||||||
|
ApplyTransformation(
|
||||||
|
TransformationAddConstantBoolean(new_result_id, value));
|
||||||
} break;
|
} break;
|
||||||
|
case SpvOpSpecConstant:
|
||||||
case SpvOpConstant: {
|
case SpvOpConstant: {
|
||||||
// It is OK to have duplicate constant definitions, so add this to the
|
// It is OK to have duplicate constant definitions, so add this to the
|
||||||
// module using a remapped result type.
|
// module using a remapped result type.
|
||||||
@ -433,6 +461,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
|
|||||||
new_result_id, original_id_to_donated_id->at(type_or_value.type_id()),
|
new_result_id, original_id_to_donated_id->at(type_or_value.type_id()),
|
||||||
data_words));
|
data_words));
|
||||||
} break;
|
} break;
|
||||||
|
case SpvOpSpecConstantComposite:
|
||||||
case SpvOpConstantComposite: {
|
case SpvOpConstantComposite: {
|
||||||
assert(original_id_to_donated_id->count(type_or_value.type_id()) &&
|
assert(original_id_to_donated_id->count(type_or_value.type_id()) &&
|
||||||
"Composite types for which it is possible to create a constant "
|
"Composite types for which it is possible to create a constant "
|
||||||
|
@ -376,6 +376,7 @@ message Transformation {
|
|||||||
TransformationComputeDataSynonymFactClosure compute_data_synonym_fact_closure = 45;
|
TransformationComputeDataSynonymFactClosure compute_data_synonym_fact_closure = 45;
|
||||||
TransformationAdjustBranchWeights adjust_branch_weights = 46;
|
TransformationAdjustBranchWeights adjust_branch_weights = 46;
|
||||||
TransformationPushIdThroughVariable push_id_through_variable = 47;
|
TransformationPushIdThroughVariable push_id_through_variable = 47;
|
||||||
|
TransformationAddSpecConstantOp add_spec_constant_op = 48;
|
||||||
// Add additional option using the next available number.
|
// Add additional option using the next available number.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,6 +620,24 @@ message TransformationAddNoContractionDecoration {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message TransformationAddSpecConstantOp {
|
||||||
|
|
||||||
|
// Adds OpSpecConstantOp into the module.
|
||||||
|
|
||||||
|
// Result id for the new instruction.
|
||||||
|
uint32 fresh_id = 1;
|
||||||
|
|
||||||
|
// Type id for the new instruction.
|
||||||
|
uint32 type_id = 2;
|
||||||
|
|
||||||
|
// Opcode operand of the OpSpecConstantOp instruction.
|
||||||
|
uint32 opcode = 3;
|
||||||
|
|
||||||
|
// Operands of the |opcode| instruction.
|
||||||
|
repeated InstructionOperand operand = 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
message TransformationAddTypeArray {
|
message TransformationAddTypeArray {
|
||||||
|
|
||||||
// Adds an array type of the given element type and size to the module
|
// Adds an array type of the given element type and size to the module
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "source/fuzz/transformation_add_global_variable.h"
|
#include "source/fuzz/transformation_add_global_variable.h"
|
||||||
#include "source/fuzz/transformation_add_local_variable.h"
|
#include "source/fuzz/transformation_add_local_variable.h"
|
||||||
#include "source/fuzz/transformation_add_no_contraction_decoration.h"
|
#include "source/fuzz/transformation_add_no_contraction_decoration.h"
|
||||||
|
#include "source/fuzz/transformation_add_spec_constant_op.h"
|
||||||
#include "source/fuzz/transformation_add_type_array.h"
|
#include "source/fuzz/transformation_add_type_array.h"
|
||||||
#include "source/fuzz/transformation_add_type_boolean.h"
|
#include "source/fuzz/transformation_add_type_boolean.h"
|
||||||
#include "source/fuzz/transformation_add_type_float.h"
|
#include "source/fuzz/transformation_add_type_float.h"
|
||||||
@ -110,6 +111,9 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
|
|||||||
kAddNoContractionDecoration:
|
kAddNoContractionDecoration:
|
||||||
return MakeUnique<TransformationAddNoContractionDecoration>(
|
return MakeUnique<TransformationAddNoContractionDecoration>(
|
||||||
message.add_no_contraction_decoration());
|
message.add_no_contraction_decoration());
|
||||||
|
case protobufs::Transformation::TransformationCase::kAddSpecConstantOp:
|
||||||
|
return MakeUnique<TransformationAddSpecConstantOp>(
|
||||||
|
message.add_spec_constant_op());
|
||||||
case protobufs::Transformation::TransformationCase::kAddTypeArray:
|
case protobufs::Transformation::TransformationCase::kAddTypeArray:
|
||||||
return MakeUnique<TransformationAddTypeArray>(message.add_type_array());
|
return MakeUnique<TransformationAddTypeArray>(message.add_type_array());
|
||||||
case protobufs::Transformation::TransformationCase::kAddTypeBoolean:
|
case protobufs::Transformation::TransformationCase::kAddTypeBoolean:
|
||||||
|
84
source/fuzz/transformation_add_spec_constant_op.cpp
Normal file
84
source/fuzz/transformation_add_spec_constant_op.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright (c) 2020 Vasyl Teliman
|
||||||
|
//
|
||||||
|
// 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 <utility>
|
||||||
|
|
||||||
|
#include "source/fuzz/fuzzer_util.h"
|
||||||
|
#include "source/fuzz/transformation_add_spec_constant_op.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
TransformationAddSpecConstantOp::TransformationAddSpecConstantOp(
|
||||||
|
spvtools::fuzz::protobufs::TransformationAddSpecConstantOp message)
|
||||||
|
: message_(std::move(message)) {}
|
||||||
|
|
||||||
|
TransformationAddSpecConstantOp::TransformationAddSpecConstantOp(
|
||||||
|
uint32_t fresh_id, uint32_t type_id, SpvOp opcode,
|
||||||
|
const opt::Instruction::OperandList& operands) {
|
||||||
|
message_.set_fresh_id(fresh_id);
|
||||||
|
message_.set_type_id(type_id);
|
||||||
|
message_.set_opcode(opcode);
|
||||||
|
for (const auto& operand : operands) {
|
||||||
|
auto* op = message_.add_operand();
|
||||||
|
op->set_operand_type(operand.type);
|
||||||
|
for (auto word : operand.words) {
|
||||||
|
op->add_operand_data(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformationAddSpecConstantOp::IsApplicable(
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
const TransformationContext& transformation_context) const {
|
||||||
|
auto clone = fuzzerutil::CloneIRContext(ir_context);
|
||||||
|
ApplyImpl(clone.get());
|
||||||
|
return fuzzerutil::IsValid(clone.get(),
|
||||||
|
transformation_context.GetValidatorOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformationAddSpecConstantOp::Apply(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
|
||||||
|
ApplyImpl(ir_context);
|
||||||
|
ir_context->InvalidateAnalysesExceptFor(
|
||||||
|
opt::IRContext::Analysis::kAnalysisNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformationAddSpecConstantOp::ApplyImpl(
|
||||||
|
opt::IRContext* ir_context) const {
|
||||||
|
opt::Instruction::OperandList operands = {
|
||||||
|
{SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, {message_.opcode()}}};
|
||||||
|
|
||||||
|
for (const auto& operand : message_.operand()) {
|
||||||
|
std::vector<uint32_t> words(operand.operand_data().begin(),
|
||||||
|
operand.operand_data().end());
|
||||||
|
operands.push_back({static_cast<spv_operand_type_t>(operand.operand_type()),
|
||||||
|
std::move(words)});
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_context->AddGlobalValue(MakeUnique<opt::Instruction>(
|
||||||
|
ir_context, SpvOpSpecConstantOp, message_.type_id(), message_.fresh_id(),
|
||||||
|
std::move(operands)));
|
||||||
|
|
||||||
|
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
protobufs::Transformation TransformationAddSpecConstantOp::ToMessage() const {
|
||||||
|
protobufs::Transformation result;
|
||||||
|
*result.mutable_add_spec_constant_op() = message_;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
60
source/fuzz/transformation_add_spec_constant_op.h
Normal file
60
source/fuzz/transformation_add_spec_constant_op.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright (c) 2020 Vasyl Teliman
|
||||||
|
//
|
||||||
|
// 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_ADD_SPEC_CONSTANT_OP_H_
|
||||||
|
#define SOURCE_FUZZ_TRANSFORMATION_ADD_SPEC_CONSTANT_OP_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 TransformationAddSpecConstantOp : public Transformation {
|
||||||
|
public:
|
||||||
|
explicit TransformationAddSpecConstantOp(
|
||||||
|
protobufs::TransformationAddSpecConstantOp message);
|
||||||
|
|
||||||
|
TransformationAddSpecConstantOp(
|
||||||
|
uint32_t fresh_id, uint32_t type_id, SpvOp opcode,
|
||||||
|
const opt::Instruction::OperandList& operands);
|
||||||
|
|
||||||
|
// - |fresh_id| is a fresh result id in the module.
|
||||||
|
// - |type_id| is a valid result id of some OpType* instruction in the
|
||||||
|
// module. It is also a valid type id with respect to |opcode|.
|
||||||
|
// - |opcode| is one of the opcodes supported by OpSpecConstantOp.
|
||||||
|
// - |operands| are valid with respect to |opcode|
|
||||||
|
bool IsApplicable(
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
const TransformationContext& transformation_context) const override;
|
||||||
|
|
||||||
|
// |%fresh_id = OpSpecConstantOp %type_id opcode operands...| is added to the
|
||||||
|
// module.
|
||||||
|
void Apply(opt::IRContext* ir_context,
|
||||||
|
TransformationContext* transformation_context) const override;
|
||||||
|
|
||||||
|
protobufs::Transformation ToMessage() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ApplyImpl(opt::IRContext* ir_context) const;
|
||||||
|
|
||||||
|
protobufs::TransformationAddSpecConstantOp message_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_TRANSFORMATION_ADD_SPEC_CONSTANT_OP_H_
|
@ -12,6 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "source/fuzz/fuzzer_pass_donate_modules.h"
|
#include "source/fuzz/fuzzer_pass_donate_modules.h"
|
||||||
#include "source/fuzz/pseudo_random_generator.h"
|
#include "source/fuzz/pseudo_random_generator.h"
|
||||||
#include "test/fuzz/fuzz_test_util.h"
|
#include "test/fuzz/fuzz_test_util.h"
|
||||||
@ -1678,6 +1680,104 @@ TEST(FuzzerPassDonateModulesTest, Miscellaneous1) {
|
|||||||
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FuzzerPassDonateModulesTest, OpSpecConstantInstructions) {
|
||||||
|
std::string donor_shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %4 "main"
|
||||||
|
OpExecutionMode %4 OriginUpperLeft
|
||||||
|
OpSource ESSL 310
|
||||||
|
%2 = OpTypeVoid
|
||||||
|
%3 = OpTypeFunction %2
|
||||||
|
%6 = OpTypeBool
|
||||||
|
%7 = OpTypeInt 32 1
|
||||||
|
%8 = OpTypeStruct %6 %6 %7
|
||||||
|
%9 = OpSpecConstantTrue %6
|
||||||
|
%10 = OpSpecConstantFalse %6
|
||||||
|
%11 = OpSpecConstant %7 2
|
||||||
|
%12 = OpSpecConstantComposite %8 %9 %10 %11
|
||||||
|
%13 = OpSpecConstantOp %6 LogicalEqual %9 %10
|
||||||
|
%4 = OpFunction %2 None %3
|
||||||
|
%5 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::string recipient_shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %4 "main"
|
||||||
|
OpExecutionMode %4 OriginUpperLeft
|
||||||
|
OpSource ESSL 310
|
||||||
|
%2 = OpTypeVoid
|
||||||
|
%3 = OpTypeFunction %2
|
||||||
|
%4 = OpFunction %2 None %3
|
||||||
|
%5 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
const auto env = SPV_ENV_UNIVERSAL_1_3;
|
||||||
|
const auto consumer = nullptr;
|
||||||
|
const auto recipient_context =
|
||||||
|
BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
|
||||||
|
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
||||||
|
|
||||||
|
const auto donor_context =
|
||||||
|
BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
|
||||||
|
ASSERT_TRUE(IsValid(env, donor_context.get()));
|
||||||
|
|
||||||
|
FactManager fact_manager;
|
||||||
|
spvtools::ValidatorOptions validator_options;
|
||||||
|
TransformationContext transformation_context(&fact_manager,
|
||||||
|
validator_options);
|
||||||
|
|
||||||
|
PseudoRandomGenerator prng(0);
|
||||||
|
FuzzerContext fuzzer_context(&prng, 100);
|
||||||
|
protobufs::TransformationSequence transformation_sequence;
|
||||||
|
|
||||||
|
FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
|
||||||
|
&transformation_context, &fuzzer_context,
|
||||||
|
&transformation_sequence, {});
|
||||||
|
|
||||||
|
fuzzer_pass.DonateSingleModule(donor_context.get(), false);
|
||||||
|
|
||||||
|
// Check that the module is valid first.
|
||||||
|
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
||||||
|
|
||||||
|
std::string expected_shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %4 "main"
|
||||||
|
OpExecutionMode %4 OriginUpperLeft
|
||||||
|
OpSource ESSL 310
|
||||||
|
%2 = OpTypeVoid
|
||||||
|
%3 = OpTypeFunction %2
|
||||||
|
%100 = OpTypeBool
|
||||||
|
%101 = OpTypeInt 32 1
|
||||||
|
%102 = OpTypeStruct %100 %100 %101
|
||||||
|
%103 = OpConstantTrue %100
|
||||||
|
%104 = OpConstantFalse %100
|
||||||
|
%105 = OpConstant %101 2
|
||||||
|
%106 = OpConstantComposite %102 %103 %104 %105
|
||||||
|
%107 = OpSpecConstantOp %100 LogicalEqual %103 %104
|
||||||
|
%4 = OpFunction %2 None %3
|
||||||
|
%5 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
%108 = OpFunction %2 None %3
|
||||||
|
%109 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
// Now check that the transformation has produced the expected result.
|
||||||
|
ASSERT_TRUE(IsEqual(env, expected_shader, recipient_context.get()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace fuzz
|
} // namespace fuzz
|
||||||
} // namespace spvtools
|
} // namespace spvtools
|
||||||
|
Loading…
Reference in New Issue
Block a user