mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-24 16:51:06 +00:00
spirv-fuzz: Add bit instruction synonym transformation (#3775)
This PR implements part of the add bit instruction synonym transformation. For now, the implementation covers the OpBitwiseOr, OpBitwiseXor and OpBitwiseAnd cases.
This commit is contained in:
parent
e7c84feda0
commit
e8ce4355ae
@ -52,6 +52,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
fuzzer_context.h
|
fuzzer_context.h
|
||||||
fuzzer_pass.h
|
fuzzer_pass.h
|
||||||
fuzzer_pass_add_access_chains.h
|
fuzzer_pass_add_access_chains.h
|
||||||
|
fuzzer_pass_add_bit_instruction_synonyms.h
|
||||||
fuzzer_pass_add_composite_inserts.h
|
fuzzer_pass_add_composite_inserts.h
|
||||||
fuzzer_pass_add_composite_types.h
|
fuzzer_pass_add_composite_types.h
|
||||||
fuzzer_pass_add_copy_memory.h
|
fuzzer_pass_add_copy_memory.h
|
||||||
@ -124,6 +125,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
shrinker.h
|
shrinker.h
|
||||||
transformation.h
|
transformation.h
|
||||||
transformation_access_chain.h
|
transformation_access_chain.h
|
||||||
|
transformation_add_bit_instruction_synonym.h
|
||||||
transformation_add_constant_boolean.h
|
transformation_add_constant_boolean.h
|
||||||
transformation_add_constant_composite.h
|
transformation_add_constant_composite.h
|
||||||
transformation_add_constant_null.h
|
transformation_add_constant_null.h
|
||||||
@ -217,6 +219,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
fuzzer_context.cpp
|
fuzzer_context.cpp
|
||||||
fuzzer_pass.cpp
|
fuzzer_pass.cpp
|
||||||
fuzzer_pass_add_access_chains.cpp
|
fuzzer_pass_add_access_chains.cpp
|
||||||
|
fuzzer_pass_add_bit_instruction_synonyms.cpp
|
||||||
fuzzer_pass_add_composite_inserts.cpp
|
fuzzer_pass_add_composite_inserts.cpp
|
||||||
fuzzer_pass_add_composite_types.cpp
|
fuzzer_pass_add_composite_types.cpp
|
||||||
fuzzer_pass_add_copy_memory.cpp
|
fuzzer_pass_add_copy_memory.cpp
|
||||||
@ -288,6 +291,7 @@ if(SPIRV_BUILD_FUZZER)
|
|||||||
shrinker.cpp
|
shrinker.cpp
|
||||||
transformation.cpp
|
transformation.cpp
|
||||||
transformation_access_chain.cpp
|
transformation_access_chain.cpp
|
||||||
|
transformation_add_bit_instruction_synonym.cpp
|
||||||
transformation_add_constant_boolean.cpp
|
transformation_add_constant_boolean.cpp
|
||||||
transformation_add_constant_composite.cpp
|
transformation_add_constant_composite.cpp
|
||||||
transformation_add_constant_null.cpp
|
transformation_add_constant_null.cpp
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "source/fuzz/fact_manager/fact_manager.h"
|
#include "source/fuzz/fact_manager/fact_manager.h"
|
||||||
#include "source/fuzz/fuzzer_context.h"
|
#include "source/fuzz/fuzzer_context.h"
|
||||||
#include "source/fuzz/fuzzer_pass_add_access_chains.h"
|
#include "source/fuzz/fuzzer_pass_add_access_chains.h"
|
||||||
|
#include "source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.h"
|
||||||
#include "source/fuzz/fuzzer_pass_add_composite_inserts.h"
|
#include "source/fuzz/fuzzer_pass_add_composite_inserts.h"
|
||||||
#include "source/fuzz/fuzzer_pass_add_composite_types.h"
|
#include "source/fuzz/fuzzer_pass_add_composite_types.h"
|
||||||
#include "source/fuzz/fuzzer_pass_add_copy_memory.h"
|
#include "source/fuzz/fuzzer_pass_add_copy_memory.h"
|
||||||
@ -205,6 +206,9 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run(
|
|||||||
MaybeAddPass<FuzzerPassAddAccessChains>(
|
MaybeAddPass<FuzzerPassAddAccessChains>(
|
||||||
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
||||||
transformation_sequence_out);
|
transformation_sequence_out);
|
||||||
|
MaybeAddPass<FuzzerPassAddBitInstructionSynonyms>(
|
||||||
|
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
||||||
|
transformation_sequence_out);
|
||||||
MaybeAddPass<FuzzerPassAddCompositeInserts>(
|
MaybeAddPass<FuzzerPassAddCompositeInserts>(
|
||||||
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
&passes, ir_context.get(), &transformation_context, &fuzzer_context,
|
||||||
transformation_sequence_out);
|
transformation_sequence_out);
|
||||||
|
@ -27,6 +27,8 @@ const std::pair<uint32_t, uint32_t> kChanceOfAddingAccessChain = {5, 50};
|
|||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingAnotherStructField = {20,
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingAnotherStructField = {20,
|
||||||
90};
|
90};
|
||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingArrayOrStructType = {20, 90};
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingArrayOrStructType = {20, 90};
|
||||||
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingBitInstructionSynonym = {20,
|
||||||
|
90};
|
||||||
const std::pair<uint32_t, uint32_t>
|
const std::pair<uint32_t, uint32_t>
|
||||||
kChanceOfAddingBothBranchesWhenReplacingOpSelect = {40, 60};
|
kChanceOfAddingBothBranchesWhenReplacingOpSelect = {40, 60};
|
||||||
const std::pair<uint32_t, uint32_t> kChanceOfAddingCompositeInsert = {20, 50};
|
const std::pair<uint32_t, uint32_t> kChanceOfAddingCompositeInsert = {20, 50};
|
||||||
@ -172,6 +174,8 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
|
|||||||
ChooseBetweenMinAndMax(kChanceOfAddingAnotherStructField);
|
ChooseBetweenMinAndMax(kChanceOfAddingAnotherStructField);
|
||||||
chance_of_adding_array_or_struct_type_ =
|
chance_of_adding_array_or_struct_type_ =
|
||||||
ChooseBetweenMinAndMax(kChanceOfAddingArrayOrStructType);
|
ChooseBetweenMinAndMax(kChanceOfAddingArrayOrStructType);
|
||||||
|
chance_of_adding_bit_instruction_synonym_ =
|
||||||
|
ChooseBetweenMinAndMax(kChanceOfAddingBitInstructionSynonym);
|
||||||
chance_of_adding_both_branches_when_replacing_opselect_ =
|
chance_of_adding_both_branches_when_replacing_opselect_ =
|
||||||
ChooseBetweenMinAndMax(kChanceOfAddingBothBranchesWhenReplacingOpSelect);
|
ChooseBetweenMinAndMax(kChanceOfAddingBothBranchesWhenReplacingOpSelect);
|
||||||
chance_of_adding_composite_insert_ =
|
chance_of_adding_composite_insert_ =
|
||||||
|
@ -115,6 +115,9 @@ class FuzzerContext {
|
|||||||
uint32_t GetChanceOfAddingArrayOrStructType() {
|
uint32_t GetChanceOfAddingArrayOrStructType() {
|
||||||
return chance_of_adding_array_or_struct_type_;
|
return chance_of_adding_array_or_struct_type_;
|
||||||
}
|
}
|
||||||
|
uint32_t GetChanceOfAddingBitInstructionSynonym() {
|
||||||
|
return chance_of_adding_bit_instruction_synonym_;
|
||||||
|
}
|
||||||
uint32_t GetChanceOfAddingBothBranchesWhenReplacingOpSelect() {
|
uint32_t GetChanceOfAddingBothBranchesWhenReplacingOpSelect() {
|
||||||
return chance_of_adding_both_branches_when_replacing_opselect_;
|
return chance_of_adding_both_branches_when_replacing_opselect_;
|
||||||
}
|
}
|
||||||
@ -379,6 +382,7 @@ class FuzzerContext {
|
|||||||
uint32_t chance_of_adding_access_chain_;
|
uint32_t chance_of_adding_access_chain_;
|
||||||
uint32_t chance_of_adding_another_struct_field_;
|
uint32_t chance_of_adding_another_struct_field_;
|
||||||
uint32_t chance_of_adding_array_or_struct_type_;
|
uint32_t chance_of_adding_array_or_struct_type_;
|
||||||
|
uint32_t chance_of_adding_bit_instruction_synonym_;
|
||||||
uint32_t chance_of_adding_both_branches_when_replacing_opselect_;
|
uint32_t chance_of_adding_both_branches_when_replacing_opselect_;
|
||||||
uint32_t chance_of_adding_composite_insert_;
|
uint32_t chance_of_adding_composite_insert_;
|
||||||
uint32_t chance_of_adding_copy_memory_;
|
uint32_t chance_of_adding_copy_memory_;
|
||||||
|
84
source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.cpp
Normal file
84
source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// 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_add_bit_instruction_synonyms.h"
|
||||||
|
|
||||||
|
#include "source/fuzz/fuzzer_util.h"
|
||||||
|
#include "source/fuzz/instruction_descriptor.h"
|
||||||
|
#include "source/fuzz/transformation_add_bit_instruction_synonym.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
FuzzerPassAddBitInstructionSynonyms::FuzzerPassAddBitInstructionSynonyms(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||||
|
FuzzerContext* fuzzer_context,
|
||||||
|
protobufs::TransformationSequence* transformations)
|
||||||
|
: FuzzerPass(ir_context, transformation_context, fuzzer_context,
|
||||||
|
transformations) {}
|
||||||
|
|
||||||
|
FuzzerPassAddBitInstructionSynonyms::~FuzzerPassAddBitInstructionSynonyms() =
|
||||||
|
default;
|
||||||
|
|
||||||
|
void FuzzerPassAddBitInstructionSynonyms::Apply() {
|
||||||
|
for (auto& function : *GetIRContext()->module()) {
|
||||||
|
for (auto& block : function) {
|
||||||
|
for (auto& instruction : block) {
|
||||||
|
// Randomly decides whether the transformation will be applied.
|
||||||
|
if (!GetFuzzerContext()->ChoosePercentage(
|
||||||
|
GetFuzzerContext()->GetChanceOfAddingBitInstructionSynonym())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3557):
|
||||||
|
// Right now we only support certain operations. When this issue is
|
||||||
|
// addressed the following conditional can use the function
|
||||||
|
// |spvOpcodeIsBit|.
|
||||||
|
if (instruction.opcode() != SpvOpBitwiseOr &&
|
||||||
|
instruction.opcode() != SpvOpBitwiseXor &&
|
||||||
|
instruction.opcode() != SpvOpBitwiseAnd) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right now, only integer operands are supported.
|
||||||
|
if (GetIRContext()
|
||||||
|
->get_type_mgr()
|
||||||
|
->GetType(instruction.type_id())
|
||||||
|
->AsVector()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure all bit indexes are defined as 32-bit unsigned integers.
|
||||||
|
uint32_t width = GetIRContext()
|
||||||
|
->get_type_mgr()
|
||||||
|
->GetType(instruction.type_id())
|
||||||
|
->AsInteger()
|
||||||
|
->width();
|
||||||
|
for (uint32_t i = 0; i < width; i++) {
|
||||||
|
FindOrCreateIntegerConstant({i}, 32, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies the add bit instruction synonym transformation.
|
||||||
|
ApplyTransformation(TransformationAddBitInstructionSynonym(
|
||||||
|
instruction.result_id(),
|
||||||
|
GetFuzzerContext()->GetFreshIds(
|
||||||
|
TransformationAddBitInstructionSynonym::GetRequiredFreshIdCount(
|
||||||
|
GetIRContext(), &instruction))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
41
source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.h
Normal file
41
source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// 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_ADD_BIT_INSTRUCTION_SYNONYMS_H_
|
||||||
|
#define SOURCE_FUZZ_FUZZER_PASS_ADD_BIT_INSTRUCTION_SYNONYMS_H_
|
||||||
|
|
||||||
|
#include "source/fuzz/fuzzer_pass.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// This fuzzer pass adds synonyms for bit instructions. It iterates over the
|
||||||
|
// module instructions, checks if they are bit instructions and randomly applies
|
||||||
|
// the transformation.
|
||||||
|
class FuzzerPassAddBitInstructionSynonyms : public FuzzerPass {
|
||||||
|
public:
|
||||||
|
FuzzerPassAddBitInstructionSynonyms(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||||
|
FuzzerContext* fuzzer_context,
|
||||||
|
protobufs::TransformationSequence* transformations);
|
||||||
|
|
||||||
|
~FuzzerPassAddBitInstructionSynonyms();
|
||||||
|
|
||||||
|
void Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_FUZZER_PASS_ADD_BIT_INSTRUCTION_SYNONYMS_H_
|
@ -496,6 +496,7 @@ message Transformation {
|
|||||||
TransformationReplaceOpSelectWithConditionalBranch replace_opselect_with_conditional_branch = 74;
|
TransformationReplaceOpSelectWithConditionalBranch replace_opselect_with_conditional_branch = 74;
|
||||||
TransformationDuplicateRegionWithSelection duplicate_region_with_selection = 75;
|
TransformationDuplicateRegionWithSelection duplicate_region_with_selection = 75;
|
||||||
TransformationFlattenConditionalBranch flatten_conditional_branch = 76;
|
TransformationFlattenConditionalBranch flatten_conditional_branch = 76;
|
||||||
|
TransformationAddBitInstructionSynonym add_bit_instruction_synonym = 77;
|
||||||
// Add additional option using the next available number.
|
// Add additional option using the next available number.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,6 +533,33 @@ message TransformationAccessChain {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message TransformationAddBitInstructionSynonym {
|
||||||
|
|
||||||
|
// A transformation that adds synonyms for bit instructions by evaluating
|
||||||
|
// each bit with the corresponding operation. There is a SPIR-V code example in the
|
||||||
|
// header file of the transformation class that can help understand the transformation.
|
||||||
|
|
||||||
|
// This transformation is only applicable if the described instruction has one of the following opcodes.
|
||||||
|
// Supported:
|
||||||
|
// OpBitwiseOr
|
||||||
|
// OpBitwiseXor
|
||||||
|
// OpBitwiseAnd
|
||||||
|
// To be supported in the future:
|
||||||
|
// OpShiftRightLogical
|
||||||
|
// OpShiftRightArithmetic
|
||||||
|
// OpShiftLeftLogical
|
||||||
|
// OpNot
|
||||||
|
// OpBitReverse
|
||||||
|
// OpBitCount
|
||||||
|
|
||||||
|
// The bit instruction result id.
|
||||||
|
uint32 instruction_result_id = 1;
|
||||||
|
|
||||||
|
// The fresh ids required to apply the transformation.
|
||||||
|
repeated uint32 fresh_ids = 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
message TransformationAddConstantBoolean {
|
message TransformationAddConstantBoolean {
|
||||||
|
|
||||||
// Supports adding the constants true and false to a module, which may be
|
// Supports adding the constants true and false to a module, which may be
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "source/fuzz/fuzzer_util.h"
|
#include "source/fuzz/fuzzer_util.h"
|
||||||
#include "source/fuzz/transformation_access_chain.h"
|
#include "source/fuzz/transformation_access_chain.h"
|
||||||
|
#include "source/fuzz/transformation_add_bit_instruction_synonym.h"
|
||||||
#include "source/fuzz/transformation_add_constant_boolean.h"
|
#include "source/fuzz/transformation_add_constant_boolean.h"
|
||||||
#include "source/fuzz/transformation_add_constant_composite.h"
|
#include "source/fuzz/transformation_add_constant_composite.h"
|
||||||
#include "source/fuzz/transformation_add_constant_null.h"
|
#include "source/fuzz/transformation_add_constant_null.h"
|
||||||
@ -105,6 +106,10 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
|
|||||||
switch (message.transformation_case()) {
|
switch (message.transformation_case()) {
|
||||||
case protobufs::Transformation::TransformationCase::kAccessChain:
|
case protobufs::Transformation::TransformationCase::kAccessChain:
|
||||||
return MakeUnique<TransformationAccessChain>(message.access_chain());
|
return MakeUnique<TransformationAccessChain>(message.access_chain());
|
||||||
|
case protobufs::Transformation::TransformationCase::
|
||||||
|
kAddBitInstructionSynonym:
|
||||||
|
return MakeUnique<TransformationAddBitInstructionSynonym>(
|
||||||
|
message.add_bit_instruction_synonym());
|
||||||
case protobufs::Transformation::TransformationCase::kAddConstantBoolean:
|
case protobufs::Transformation::TransformationCase::kAddConstantBoolean:
|
||||||
return MakeUnique<TransformationAddConstantBoolean>(
|
return MakeUnique<TransformationAddConstantBoolean>(
|
||||||
message.add_constant_boolean());
|
message.add_constant_boolean());
|
||||||
|
228
source/fuzz/transformation_add_bit_instruction_synonym.cpp
Normal file
228
source/fuzz/transformation_add_bit_instruction_synonym.cpp
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
// 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_add_bit_instruction_synonym.h"
|
||||||
|
|
||||||
|
#include "source/fuzz/fuzzer_util.h"
|
||||||
|
#include "source/fuzz/instruction_descriptor.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
TransformationAddBitInstructionSynonym::TransformationAddBitInstructionSynonym(
|
||||||
|
const spvtools::fuzz::protobufs::TransformationAddBitInstructionSynonym&
|
||||||
|
message)
|
||||||
|
: message_(message) {}
|
||||||
|
|
||||||
|
TransformationAddBitInstructionSynonym::TransformationAddBitInstructionSynonym(
|
||||||
|
const uint32_t instruction_result_id,
|
||||||
|
const std::vector<uint32_t>& fresh_ids) {
|
||||||
|
message_.set_instruction_result_id(instruction_result_id);
|
||||||
|
*message_.mutable_fresh_ids() =
|
||||||
|
google::protobuf::RepeatedField<google::protobuf::uint32>(
|
||||||
|
fresh_ids.begin(), fresh_ids.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformationAddBitInstructionSynonym::IsApplicable(
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
const TransformationContext& transformation_context) const {
|
||||||
|
auto instruction =
|
||||||
|
ir_context->get_def_use_mgr()->GetDef(message_.instruction_result_id());
|
||||||
|
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3557):
|
||||||
|
// Right now we only support certain operations. When this issue is addressed
|
||||||
|
// the following conditional can use the function |spvOpcodeIsBit|.
|
||||||
|
// |instruction| must be defined and must be a supported bit instruction.
|
||||||
|
if (!instruction || (instruction->opcode() != SpvOpBitwiseOr &&
|
||||||
|
instruction->opcode() != SpvOpBitwiseXor &&
|
||||||
|
instruction->opcode() != SpvOpBitwiseAnd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3792):
|
||||||
|
// Right now, only integer operands are supported.
|
||||||
|
if (ir_context->get_type_mgr()->GetType(instruction->type_id())->AsVector()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3791):
|
||||||
|
// This condition could be relaxed if the index exists as another integer
|
||||||
|
// type.
|
||||||
|
// All bit indexes must be defined as 32-bit unsigned integers.
|
||||||
|
uint32_t width = ir_context->get_type_mgr()
|
||||||
|
->GetType(instruction->type_id())
|
||||||
|
->AsInteger()
|
||||||
|
->width();
|
||||||
|
for (uint32_t i = 0; i < width; i++) {
|
||||||
|
if (!fuzzerutil::MaybeGetIntegerConstant(ir_context, transformation_context,
|
||||||
|
{i}, 32, false, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// |message_.fresh_ids.size| must have the exact number of fresh ids required
|
||||||
|
// to apply the transformation.
|
||||||
|
if (static_cast<uint32_t>(message_.fresh_ids().size()) !=
|
||||||
|
GetRequiredFreshIdCount(ir_context, instruction)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All ids in |message_.fresh_ids| must be fresh.
|
||||||
|
for (uint32_t fresh_id : message_.fresh_ids()) {
|
||||||
|
if (!fuzzerutil::IsFreshId(ir_context, fresh_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformationAddBitInstructionSynonym::Apply(
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
TransformationContext* transformation_context) const {
|
||||||
|
auto bit_instruction =
|
||||||
|
ir_context->get_def_use_mgr()->GetDef(message_.instruction_result_id());
|
||||||
|
|
||||||
|
switch (bit_instruction->opcode()) {
|
||||||
|
case SpvOpBitwiseOr:
|
||||||
|
case SpvOpBitwiseXor:
|
||||||
|
case SpvOpBitwiseAnd:
|
||||||
|
AddBitwiseSynonym(ir_context, transformation_context, bit_instruction);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "Should be unreachable.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
protobufs::Transformation TransformationAddBitInstructionSynonym::ToMessage()
|
||||||
|
const {
|
||||||
|
protobufs::Transformation result;
|
||||||
|
*result.mutable_add_bit_instruction_synonym() = message_;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TransformationAddBitInstructionSynonym::GetRequiredFreshIdCount(
|
||||||
|
opt::IRContext* ir_context, opt::Instruction* bit_instruction) {
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3557):
|
||||||
|
// Right now, only certain operations are supported.
|
||||||
|
switch (bit_instruction->opcode()) {
|
||||||
|
case SpvOpBitwiseOr:
|
||||||
|
case SpvOpBitwiseXor:
|
||||||
|
case SpvOpBitwiseAnd:
|
||||||
|
return 4 * ir_context->get_type_mgr()
|
||||||
|
->GetType(bit_instruction->type_id())
|
||||||
|
->AsInteger()
|
||||||
|
->width() -
|
||||||
|
1;
|
||||||
|
default:
|
||||||
|
assert(false && "Unsupported bit instruction.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformationAddBitInstructionSynonym::AddBitwiseSynonym(
|
||||||
|
opt::IRContext* ir_context, TransformationContext* transformation_context,
|
||||||
|
opt::Instruction* bit_instruction) const {
|
||||||
|
// Fresh id iterator.
|
||||||
|
auto fresh_id = message_.fresh_ids().begin();
|
||||||
|
|
||||||
|
// |width| is the bit width of operands (8, 16, 32 or 64).
|
||||||
|
const uint32_t width = ir_context->get_type_mgr()
|
||||||
|
->GetType(bit_instruction->type_id())
|
||||||
|
->AsInteger()
|
||||||
|
->width();
|
||||||
|
|
||||||
|
// |count| is the number of bits to be extracted and inserted at a time.
|
||||||
|
const uint32_t count = fuzzerutil::MaybeGetIntegerConstant(
|
||||||
|
ir_context, *transformation_context, {1}, 32, false, false);
|
||||||
|
|
||||||
|
// |bitwise_ids| is the collection of OpBiwise* instructions that evaluate a
|
||||||
|
// pair of extracted bits. Those ids will be used to insert the result bits.
|
||||||
|
std::vector<uint32_t> bitwise_ids(width);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < width; i++) {
|
||||||
|
// |offset| is the current bit index.
|
||||||
|
uint32_t offset = fuzzerutil::MaybeGetIntegerConstant(
|
||||||
|
ir_context, *transformation_context, {i}, 32, false, false);
|
||||||
|
|
||||||
|
// |bit_extract_ids| are the two extracted bits from the operands.
|
||||||
|
std::vector<uint32_t> bit_extract_ids;
|
||||||
|
|
||||||
|
// Extracts the i-th bit from operands.
|
||||||
|
for (auto operand = bit_instruction->begin() + 2;
|
||||||
|
operand != bit_instruction->end(); operand++) {
|
||||||
|
auto bit_extract =
|
||||||
|
opt::Instruction(ir_context, SpvOpBitFieldUExtract,
|
||||||
|
bit_instruction->type_id(), *fresh_id++,
|
||||||
|
{{SPV_OPERAND_TYPE_ID, operand->words},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {offset}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {count}}});
|
||||||
|
bit_instruction->InsertBefore(MakeUnique<opt::Instruction>(bit_extract));
|
||||||
|
fuzzerutil::UpdateModuleIdBound(ir_context, bit_extract.result_id());
|
||||||
|
bit_extract_ids.push_back(bit_extract.result_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies |bit_instruction| to the pair of extracted bits.
|
||||||
|
auto bitwise =
|
||||||
|
opt::Instruction(ir_context, bit_instruction->opcode(),
|
||||||
|
bit_instruction->type_id(), *fresh_id++,
|
||||||
|
{{SPV_OPERAND_TYPE_ID, {bit_extract_ids[0]}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {bit_extract_ids[1]}}});
|
||||||
|
bit_instruction->InsertBefore(MakeUnique<opt::Instruction>(bitwise));
|
||||||
|
fuzzerutil::UpdateModuleIdBound(ir_context, bitwise.result_id());
|
||||||
|
bitwise_ids[i] = bitwise.result_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first two ids in |bitwise_ids| are used to insert the first two bits of
|
||||||
|
// the result.
|
||||||
|
uint32_t offset = fuzzerutil::MaybeGetIntegerConstant(
|
||||||
|
ir_context, *transformation_context, {1}, 32, false, false);
|
||||||
|
auto bit_insert = opt::Instruction(ir_context, SpvOpBitFieldInsert,
|
||||||
|
bit_instruction->type_id(), *fresh_id++,
|
||||||
|
{{SPV_OPERAND_TYPE_ID, {bitwise_ids[0]}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {bitwise_ids[1]}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {offset}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {count}}});
|
||||||
|
bit_instruction->InsertBefore(MakeUnique<opt::Instruction>(bit_insert));
|
||||||
|
fuzzerutil::UpdateModuleIdBound(ir_context, bit_insert.result_id());
|
||||||
|
|
||||||
|
// Inserts the remaining bits.
|
||||||
|
for (uint32_t i = 2; i < width; i++) {
|
||||||
|
offset = fuzzerutil::MaybeGetIntegerConstant(
|
||||||
|
ir_context, *transformation_context, {i}, 32, false, false);
|
||||||
|
bit_insert =
|
||||||
|
opt::Instruction(ir_context, SpvOpBitFieldInsert,
|
||||||
|
bit_instruction->type_id(), *fresh_id++,
|
||||||
|
{{SPV_OPERAND_TYPE_ID, {bit_insert.result_id()}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {bitwise_ids[i]}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {offset}},
|
||||||
|
{SPV_OPERAND_TYPE_ID, {count}}});
|
||||||
|
bit_instruction->InsertBefore(MakeUnique<opt::Instruction>(bit_insert));
|
||||||
|
fuzzerutil::UpdateModuleIdBound(ir_context, bit_insert.result_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
|
||||||
|
|
||||||
|
// Adds the fact that the last |bit_insert| instruction is synonymous of
|
||||||
|
// |bit_instruction|.
|
||||||
|
transformation_context->GetFactManager()->AddFactDataSynonym(
|
||||||
|
MakeDataDescriptor(bit_insert.result_id(), {}),
|
||||||
|
MakeDataDescriptor(bit_instruction->result_id(), {}), ir_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
141
source/fuzz/transformation_add_bit_instruction_synonym.h
Normal file
141
source/fuzz/transformation_add_bit_instruction_synonym.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
// 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_ADD_BIT_INSTRUCTION_SYNONYM_H_
|
||||||
|
#define SOURCE_FUZZ_TRANSFORMATION_ADD_BIT_INSTRUCTION_SYNONYM_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 {
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// SPIR-V code to help understand the transformation.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------
|
||||||
|
// | Reference shader | Variant shader |
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------
|
||||||
|
// | OpCapability Shader | OpCapability Shader |
|
||||||
|
// | OpCapability Int8 | OpCapability Int8 |
|
||||||
|
// | %1 = OpExtInstImport "GLSL.std.450" | %1 = OpExtInstImport "GLSL.std.450" |
|
||||||
|
// | OpMemoryModel Logical GLSL450 | OpMemoryModel Logical GLSL450 |
|
||||||
|
// | OpEntryPoint Vertex %7 "main" | OpEntryPoint Vertex %7 "main" |
|
||||||
|
// | | |
|
||||||
|
// | ; Types | ; Types |
|
||||||
|
// | %2 = OpTypeInt 8 0 | %2 = OpTypeInt 8 0 |
|
||||||
|
// | %3 = OpTypeVoid | %3 = OpTypeVoid |
|
||||||
|
// | %4 = OpTypeFunction %3 | %4 = OpTypeFunction %3 |
|
||||||
|
// | | |
|
||||||
|
// | ; Constants | ; Constants |
|
||||||
|
// | %5 = OpConstant %2 0 | %5 = OpConstant %2 0 |
|
||||||
|
// | %6 = OpConstant %2 1 | %6 = OpConstant %2 1 |
|
||||||
|
// | | %10 = OpConstant %2 2 |
|
||||||
|
// | ; main function | %11 = OpConstant %2 3 |
|
||||||
|
// | %7 = OpFunction %3 None %4 | %12 = OpConstant %2 4 |
|
||||||
|
// | %8 = OpLabel | %13 = OpConstant %2 5 |
|
||||||
|
// | %9 = OpBitwiseOr %2 %5 %6 ; bit instruction | %14 = OpConstant %2 6 |
|
||||||
|
// | OpReturn | %15 = OpConstant %2 7 |
|
||||||
|
// | OpFunctionEnd | |
|
||||||
|
// | | ; main function |
|
||||||
|
// | | %7 = OpFunction %3 None %4 |
|
||||||
|
// | | %8 = OpLabel |
|
||||||
|
// | | |
|
||||||
|
// | | %16 = OpBitFieldUExtract %2 %5 %5 %6 ; extracts bit 0 from %5 |
|
||||||
|
// | | %17 = OpBitFieldUExtract %2 %6 %5 %6 ; extracts bit 0 from %6 |
|
||||||
|
// | | %18 = OpBitwiseOr %2 %16 %17 |
|
||||||
|
// | | |
|
||||||
|
// | | %19 = OpBitFieldUExtract %2 %5 %6 %6 ; extracts bit 1 from %5 |
|
||||||
|
// | | %20 = OpBitFieldUExtract %2 %6 %6 %6 ; extracts bit 1 from %6 |
|
||||||
|
// | | %21 = OpBitwiseOr %2 %19 %20 |
|
||||||
|
// | | |
|
||||||
|
// | | %22 = OpBitFieldUExtract %2 %5 %10 %6 ; extracts bit 2 from %5 |
|
||||||
|
// | | %23 = OpBitFieldUExtract %2 %6 %10 %6 ; extracts bit 2 from %6 |
|
||||||
|
// | | %24 = OpBitwiseOr %2 %22 %23 |
|
||||||
|
// | | |
|
||||||
|
// | | %25 = OpBitFieldUExtract %2 %5 %11 %6 ; extracts bit 3 from %5 |
|
||||||
|
// | | %26 = OpBitFieldUExtract %2 %6 %11 %6 ; extracts bit 3 from %6 |
|
||||||
|
// | | %27 = OpBitwiseOr %2 %25 %26 |
|
||||||
|
// | | |
|
||||||
|
// | | %28 = OpBitFieldUExtract %2 %5 %12 %6 ; extracts bit 4 from %5 |
|
||||||
|
// | | %29 = OpBitFieldUExtract %2 %6 %12 %6 ; extracts bit 4 from %6 |
|
||||||
|
// | | %30 = OpBitwiseOr %2 %28 %29 |
|
||||||
|
// | | |
|
||||||
|
// | | %31 = OpBitFieldUExtract %2 %5 %13 %6 ; extracts bit 5 from %5 |
|
||||||
|
// | | %32 = OpBitFieldUExtract %2 %6 %13 %6 ; extracts bit 5 from %6 |
|
||||||
|
// | | %33 = OpBitwiseOr %2 %31 %32 |
|
||||||
|
// | | |
|
||||||
|
// | | %34 = OpBitFieldUExtract %2 %5 %14 %6 ; extracts bit 6 from %5 |
|
||||||
|
// | | %35 = OpBitFieldUExtract %2 %6 %14 %6 ; extracts bit 6 from %6 |
|
||||||
|
// | | %36 = OpBitwiseOr %2 %34 %35 |
|
||||||
|
// | | |
|
||||||
|
// | | %37 = OpBitFieldUExtract %2 %5 %15 %6 ; extracts bit 7 from %5 |
|
||||||
|
// | | %38 = OpBitFieldUExtract %2 %6 %15 %6 ; extracts bit 7 from %6 |
|
||||||
|
// | | %39 = OpBitwiseOr %2 %37 %38 |
|
||||||
|
// | | |
|
||||||
|
// | | %40 = OpBitFieldInsert %2 %18 %21 %6 %6 ; inserts bit 1 |
|
||||||
|
// | | %41 = OpBitFieldInsert %2 %40 %24 %10 %6 ; inserts bit 2 |
|
||||||
|
// | | %42 = OpBitFieldInsert %2 %41 %27 %11 %6 ; inserts bit 3 |
|
||||||
|
// | | %43 = OpBitFieldInsert %2 %42 %30 %12 %6 ; inserts bit 4 |
|
||||||
|
// | | %44 = OpBitFieldInsert %2 %43 %33 %13 %6 ; inserts bit 5 |
|
||||||
|
// | | %45 = OpBitFieldInsert %2 %44 %36 %14 %6 ; inserts bit 6 |
|
||||||
|
// | | %46 = OpBitFieldInsert %2 %45 %39 %15 %6 ; inserts bit 7 |
|
||||||
|
// | | %9 = OpBitwiseOr %2 %5 %6 ; bit instruction |
|
||||||
|
// | | OpReturn |
|
||||||
|
// | | OpFunctionEnd |
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// After the transformation, %9 and %46 will be synonymous.
|
||||||
|
// clang-format on
|
||||||
|
class TransformationAddBitInstructionSynonym : public Transformation {
|
||||||
|
public:
|
||||||
|
explicit TransformationAddBitInstructionSynonym(
|
||||||
|
const protobufs::TransformationAddBitInstructionSynonym& message);
|
||||||
|
|
||||||
|
TransformationAddBitInstructionSynonym(
|
||||||
|
const uint32_t instruction_result_id,
|
||||||
|
const std::vector<uint32_t>& fresh_ids);
|
||||||
|
|
||||||
|
// - |message_.instruction_result_id| must be a bit instruction.
|
||||||
|
// - |message_.fresh_ids| must be fresh ids needed to apply the
|
||||||
|
// transformation.
|
||||||
|
bool IsApplicable(
|
||||||
|
opt::IRContext* ir_context,
|
||||||
|
const TransformationContext& transformation_context) const override;
|
||||||
|
|
||||||
|
// Adds a bit instruction synonym.
|
||||||
|
void Apply(opt::IRContext* ir_context,
|
||||||
|
TransformationContext* transformation_context) const override;
|
||||||
|
|
||||||
|
protobufs::Transformation ToMessage() const override;
|
||||||
|
|
||||||
|
// Returns the number of fresh ids required to apply the transformation.
|
||||||
|
static uint32_t GetRequiredFreshIdCount(opt::IRContext* ir_context,
|
||||||
|
opt::Instruction* bit_instruction);
|
||||||
|
|
||||||
|
private:
|
||||||
|
protobufs::TransformationAddBitInstructionSynonym message_;
|
||||||
|
|
||||||
|
// Adds an OpBitwise* synonym.
|
||||||
|
void AddBitwiseSynonym(opt::IRContext* ir_context,
|
||||||
|
TransformationContext* transformation_context,
|
||||||
|
opt::Instruction* bitwise_instruction) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_TRANSFORMATION_ADD_BIT_INSTRUCTION_SYNONYM_H_
|
@ -731,3 +731,20 @@ bool spvOpcodeIsAccessChain(SpvOp opcode) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool spvOpcodeIsBit(SpvOp opcode) {
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpShiftRightLogical:
|
||||||
|
case SpvOpShiftRightArithmetic:
|
||||||
|
case SpvOpShiftLeftLogical:
|
||||||
|
case SpvOpBitwiseOr:
|
||||||
|
case SpvOpBitwiseXor:
|
||||||
|
case SpvOpBitwiseAnd:
|
||||||
|
case SpvOpNot:
|
||||||
|
case SpvOpBitReverse:
|
||||||
|
case SpvOpBitCount:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -134,17 +134,20 @@ bool spvOpcodeIsDebug(SpvOp opcode);
|
|||||||
// where the order of the operands is irrelevant.
|
// where the order of the operands is irrelevant.
|
||||||
bool spvOpcodeIsCommutativeBinaryOperator(SpvOp opcode);
|
bool spvOpcodeIsCommutativeBinaryOperator(SpvOp opcode);
|
||||||
|
|
||||||
// Returns true for opcodes that represents linear algebra instructions.
|
// Returns true for opcodes that represent linear algebra instructions.
|
||||||
bool spvOpcodeIsLinearAlgebra(SpvOp opcode);
|
bool spvOpcodeIsLinearAlgebra(SpvOp opcode);
|
||||||
|
|
||||||
// Returns true for opcodes that represents an image sample instruction.
|
// Returns true for opcodes that represent image sample instructions.
|
||||||
bool spvOpcodeIsImageSample(SpvOp opcode);
|
bool spvOpcodeIsImageSample(SpvOp opcode);
|
||||||
|
|
||||||
// Returns a vector containing the indices of the memory semantics <id>
|
// Returns a vector containing the indices of the memory semantics <id>
|
||||||
// operands for |opcode|.
|
// operands for |opcode|.
|
||||||
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(SpvOp opcode);
|
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(SpvOp opcode);
|
||||||
|
|
||||||
// Returns true for opcodes that represents access chain instructions.
|
// Returns true for opcodes that represent access chain instructions.
|
||||||
bool spvOpcodeIsAccessChain(SpvOp opcode);
|
bool spvOpcodeIsAccessChain(SpvOp opcode);
|
||||||
|
|
||||||
|
// Returns true for opcodes that represent bit instructions.
|
||||||
|
bool spvOpcodeIsBit(SpvOp opcode);
|
||||||
|
|
||||||
#endif // SOURCE_OPCODE_H_
|
#endif // SOURCE_OPCODE_H_
|
||||||
|
@ -31,6 +31,7 @@ if (${SPIRV_BUILD_FUZZER})
|
|||||||
fuzzer_pass_test.cpp
|
fuzzer_pass_test.cpp
|
||||||
replayer_test.cpp
|
replayer_test.cpp
|
||||||
transformation_access_chain_test.cpp
|
transformation_access_chain_test.cpp
|
||||||
|
transformation_add_bit_instruction_synonym_test.cpp
|
||||||
transformation_add_constant_boolean_test.cpp
|
transformation_add_constant_boolean_test.cpp
|
||||||
transformation_add_constant_composite_test.cpp
|
transformation_add_constant_composite_test.cpp
|
||||||
transformation_add_constant_null_test.cpp
|
transformation_add_constant_null_test.cpp
|
||||||
|
463
test/fuzz/transformation_add_bit_instruction_synonym_test.cpp
Normal file
463
test/fuzz/transformation_add_bit_instruction_synonym_test.cpp
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
// 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_add_bit_instruction_synonym.h"
|
||||||
|
#include "source/fuzz/instruction_descriptor.h"
|
||||||
|
#include "test/fuzz/fuzz_test_util.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(TransformationAddBitInstructionSynonymTest, IsApplicable) {
|
||||||
|
std::string reference_shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Vertex %37 "main"
|
||||||
|
|
||||||
|
; Types
|
||||||
|
%2 = OpTypeInt 32 0
|
||||||
|
%3 = OpTypeVoid
|
||||||
|
%4 = OpTypeFunction %3
|
||||||
|
|
||||||
|
; Constants
|
||||||
|
%5 = OpConstant %2 0
|
||||||
|
%6 = OpConstant %2 1
|
||||||
|
%7 = OpConstant %2 2
|
||||||
|
%8 = OpConstant %2 3
|
||||||
|
%9 = OpConstant %2 4
|
||||||
|
%10 = OpConstant %2 5
|
||||||
|
%11 = OpConstant %2 6
|
||||||
|
%12 = OpConstant %2 7
|
||||||
|
%13 = OpConstant %2 8
|
||||||
|
%14 = OpConstant %2 9
|
||||||
|
%15 = OpConstant %2 10
|
||||||
|
%16 = OpConstant %2 11
|
||||||
|
%17 = OpConstant %2 12
|
||||||
|
%18 = OpConstant %2 13
|
||||||
|
%19 = OpConstant %2 14
|
||||||
|
%20 = OpConstant %2 15
|
||||||
|
%21 = OpConstant %2 16
|
||||||
|
%22 = OpConstant %2 17
|
||||||
|
%23 = OpConstant %2 18
|
||||||
|
%24 = OpConstant %2 19
|
||||||
|
%25 = OpConstant %2 20
|
||||||
|
%26 = OpConstant %2 21
|
||||||
|
%27 = OpConstant %2 22
|
||||||
|
%28 = OpConstant %2 23
|
||||||
|
%29 = OpConstant %2 24
|
||||||
|
%30 = OpConstant %2 25
|
||||||
|
%31 = OpConstant %2 26
|
||||||
|
%32 = OpConstant %2 27
|
||||||
|
%33 = OpConstant %2 28
|
||||||
|
%34 = OpConstant %2 29
|
||||||
|
%35 = OpConstant %2 30
|
||||||
|
%36 = OpConstant %2 31
|
||||||
|
|
||||||
|
; main function
|
||||||
|
%37 = OpFunction %3 None %4
|
||||||
|
%38 = OpLabel
|
||||||
|
%39 = OpBitwiseOr %2 %5 %6
|
||||||
|
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 bit instruction.
|
||||||
|
auto transformation = TransformationAddBitInstructionSynonym(
|
||||||
|
40, {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||||
|
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
|
||||||
|
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||||
|
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
|
||||||
|
93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
|
||||||
|
106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
|
||||||
|
119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
|
||||||
|
132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
|
||||||
|
145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
|
||||||
|
158, 159, 160, 161, 162, 163, 164, 165, 166, 167});
|
||||||
|
ASSERT_FALSE(
|
||||||
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
|
||||||
|
// Tests false bit instruction.
|
||||||
|
transformation = TransformationAddBitInstructionSynonym(
|
||||||
|
38, {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
|
||||||
|
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
|
||||||
|
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
|
||||||
|
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
|
||||||
|
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
|
||||||
|
105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
|
||||||
|
118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
|
||||||
|
131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
||||||
|
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
|
||||||
|
157, 158, 159, 160, 161, 162, 163, 164, 165, 166});
|
||||||
|
ASSERT_FALSE(
|
||||||
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
|
||||||
|
// Tests the number of fresh ids being different than the necessary.
|
||||||
|
transformation = TransformationAddBitInstructionSynonym(
|
||||||
|
39,
|
||||||
|
{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||||
|
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
|
||||||
|
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||||
|
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||||
|
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
|
||||||
|
110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
|
||||||
|
124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
|
||||||
|
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
|
||||||
|
152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165});
|
||||||
|
ASSERT_FALSE(
|
||||||
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
|
||||||
|
// Tests non-fresh ids.
|
||||||
|
transformation = TransformationAddBitInstructionSynonym(
|
||||||
|
39, {38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
||||||
|
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
|
||||||
|
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
|
||||||
|
91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
|
||||||
|
104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
|
||||||
|
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
|
||||||
|
130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
|
||||||
|
143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
|
||||||
|
156, 157, 158, 159, 160, 161, 162, 163, 164, 165});
|
||||||
|
ASSERT_FALSE(
|
||||||
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
|
||||||
|
// Tests applicable transformation.
|
||||||
|
transformation = TransformationAddBitInstructionSynonym(
|
||||||
|
39, {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
|
||||||
|
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
|
||||||
|
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
|
||||||
|
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
|
||||||
|
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
|
||||||
|
105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
|
||||||
|
118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
|
||||||
|
131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
||||||
|
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
|
||||||
|
157, 158, 159, 160, 161, 162, 163, 164, 165, 166});
|
||||||
|
ASSERT_TRUE(
|
||||||
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TransformationAddBitInstructionSynonymTest, AddBitwiseSynonym) {
|
||||||
|
std::string reference_shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Vertex %37 "main"
|
||||||
|
|
||||||
|
; Types
|
||||||
|
%2 = OpTypeInt 32 0
|
||||||
|
%3 = OpTypeVoid
|
||||||
|
%4 = OpTypeFunction %3
|
||||||
|
|
||||||
|
; Constants
|
||||||
|
%5 = OpConstant %2 0
|
||||||
|
%6 = OpConstant %2 1
|
||||||
|
%7 = OpConstant %2 2
|
||||||
|
%8 = OpConstant %2 3
|
||||||
|
%9 = OpConstant %2 4
|
||||||
|
%10 = OpConstant %2 5
|
||||||
|
%11 = OpConstant %2 6
|
||||||
|
%12 = OpConstant %2 7
|
||||||
|
%13 = OpConstant %2 8
|
||||||
|
%14 = OpConstant %2 9
|
||||||
|
%15 = OpConstant %2 10
|
||||||
|
%16 = OpConstant %2 11
|
||||||
|
%17 = OpConstant %2 12
|
||||||
|
%18 = OpConstant %2 13
|
||||||
|
%19 = OpConstant %2 14
|
||||||
|
%20 = OpConstant %2 15
|
||||||
|
%21 = OpConstant %2 16
|
||||||
|
%22 = OpConstant %2 17
|
||||||
|
%23 = OpConstant %2 18
|
||||||
|
%24 = OpConstant %2 19
|
||||||
|
%25 = OpConstant %2 20
|
||||||
|
%26 = OpConstant %2 21
|
||||||
|
%27 = OpConstant %2 22
|
||||||
|
%28 = OpConstant %2 23
|
||||||
|
%29 = OpConstant %2 24
|
||||||
|
%30 = OpConstant %2 25
|
||||||
|
%31 = OpConstant %2 26
|
||||||
|
%32 = OpConstant %2 27
|
||||||
|
%33 = OpConstant %2 28
|
||||||
|
%34 = OpConstant %2 29
|
||||||
|
%35 = OpConstant %2 30
|
||||||
|
%36 = OpConstant %2 31
|
||||||
|
|
||||||
|
; main function
|
||||||
|
%37 = OpFunction %3 None %4
|
||||||
|
%38 = OpLabel
|
||||||
|
%39 = OpBitwiseOr %2 %5 %6
|
||||||
|
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 = TransformationAddBitInstructionSynonym(
|
||||||
|
39, {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
|
||||||
|
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
|
||||||
|
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
|
||||||
|
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
|
||||||
|
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
|
||||||
|
105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
|
||||||
|
118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
|
||||||
|
131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
||||||
|
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
|
||||||
|
157, 158, 159, 160, 161, 162, 163, 164, 165, 166});
|
||||||
|
transformation.Apply(context.get(), &transformation_context);
|
||||||
|
|
||||||
|
std::string variant_shader = R"(
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Vertex %37 "main"
|
||||||
|
|
||||||
|
; Types
|
||||||
|
%2 = OpTypeInt 32 0
|
||||||
|
%3 = OpTypeVoid
|
||||||
|
%4 = OpTypeFunction %3
|
||||||
|
|
||||||
|
; Constants
|
||||||
|
%5 = OpConstant %2 0
|
||||||
|
%6 = OpConstant %2 1
|
||||||
|
%7 = OpConstant %2 2
|
||||||
|
%8 = OpConstant %2 3
|
||||||
|
%9 = OpConstant %2 4
|
||||||
|
%10 = OpConstant %2 5
|
||||||
|
%11 = OpConstant %2 6
|
||||||
|
%12 = OpConstant %2 7
|
||||||
|
%13 = OpConstant %2 8
|
||||||
|
%14 = OpConstant %2 9
|
||||||
|
%15 = OpConstant %2 10
|
||||||
|
%16 = OpConstant %2 11
|
||||||
|
%17 = OpConstant %2 12
|
||||||
|
%18 = OpConstant %2 13
|
||||||
|
%19 = OpConstant %2 14
|
||||||
|
%20 = OpConstant %2 15
|
||||||
|
%21 = OpConstant %2 16
|
||||||
|
%22 = OpConstant %2 17
|
||||||
|
%23 = OpConstant %2 18
|
||||||
|
%24 = OpConstant %2 19
|
||||||
|
%25 = OpConstant %2 20
|
||||||
|
%26 = OpConstant %2 21
|
||||||
|
%27 = OpConstant %2 22
|
||||||
|
%28 = OpConstant %2 23
|
||||||
|
%29 = OpConstant %2 24
|
||||||
|
%30 = OpConstant %2 25
|
||||||
|
%31 = OpConstant %2 26
|
||||||
|
%32 = OpConstant %2 27
|
||||||
|
%33 = OpConstant %2 28
|
||||||
|
%34 = OpConstant %2 29
|
||||||
|
%35 = OpConstant %2 30
|
||||||
|
%36 = OpConstant %2 31
|
||||||
|
|
||||||
|
; main function
|
||||||
|
%37 = OpFunction %3 None %4
|
||||||
|
%38 = OpLabel
|
||||||
|
|
||||||
|
%40 = OpBitFieldUExtract %2 %5 %5 %6 ; extracts bit 0 from %5
|
||||||
|
%41 = OpBitFieldUExtract %2 %6 %5 %6 ; extracts bit 0 from %6
|
||||||
|
%42 = OpBitwiseOr %2 %40 %41
|
||||||
|
|
||||||
|
%43 = OpBitFieldUExtract %2 %5 %6 %6 ; extracts bit 1 from %5
|
||||||
|
%44 = OpBitFieldUExtract %2 %6 %6 %6 ; extracts bit 1 from %6
|
||||||
|
%45 = OpBitwiseOr %2 %43 %44
|
||||||
|
|
||||||
|
%46 = OpBitFieldUExtract %2 %5 %7 %6 ; extracts bit 2 from %5
|
||||||
|
%47 = OpBitFieldUExtract %2 %6 %7 %6 ; extracts bit 2 from %6
|
||||||
|
%48 = OpBitwiseOr %2 %46 %47
|
||||||
|
|
||||||
|
%49 = OpBitFieldUExtract %2 %5 %8 %6 ; extracts bit 3 from %5
|
||||||
|
%50 = OpBitFieldUExtract %2 %6 %8 %6 ; extracts bit 3 from %6
|
||||||
|
%51 = OpBitwiseOr %2 %49 %50
|
||||||
|
|
||||||
|
%52 = OpBitFieldUExtract %2 %5 %9 %6 ; extracts bit 4 from %5
|
||||||
|
%53 = OpBitFieldUExtract %2 %6 %9 %6 ; extracts bit 4 from %6
|
||||||
|
%54 = OpBitwiseOr %2 %52 %53
|
||||||
|
|
||||||
|
%55 = OpBitFieldUExtract %2 %5 %10 %6 ; extracts bit 5 from %5
|
||||||
|
%56 = OpBitFieldUExtract %2 %6 %10 %6 ; extracts bit 5 from %6
|
||||||
|
%57 = OpBitwiseOr %2 %55 %56
|
||||||
|
|
||||||
|
%58 = OpBitFieldUExtract %2 %5 %11 %6 ; extracts bit 6 from %5
|
||||||
|
%59 = OpBitFieldUExtract %2 %6 %11 %6 ; extracts bit 6 from %6
|
||||||
|
%60 = OpBitwiseOr %2 %58 %59
|
||||||
|
|
||||||
|
%61 = OpBitFieldUExtract %2 %5 %12 %6 ; extracts bit 7 from %5
|
||||||
|
%62 = OpBitFieldUExtract %2 %6 %12 %6 ; extracts bit 7 from %6
|
||||||
|
%63 = OpBitwiseOr %2 %61 %62
|
||||||
|
|
||||||
|
%64 = OpBitFieldUExtract %2 %5 %13 %6 ; extracts bit 8 from %5
|
||||||
|
%65 = OpBitFieldUExtract %2 %6 %13 %6 ; extracts bit 8 from %6
|
||||||
|
%66 = OpBitwiseOr %2 %64 %65
|
||||||
|
|
||||||
|
%67 = OpBitFieldUExtract %2 %5 %14 %6 ; extracts bit 9 from %5
|
||||||
|
%68 = OpBitFieldUExtract %2 %6 %14 %6 ; extracts bit 9 from %6
|
||||||
|
%69 = OpBitwiseOr %2 %67 %68
|
||||||
|
|
||||||
|
%70 = OpBitFieldUExtract %2 %5 %15 %6 ; extracts bit 10 from %5
|
||||||
|
%71 = OpBitFieldUExtract %2 %6 %15 %6 ; extracts bit 10 from %6
|
||||||
|
%72 = OpBitwiseOr %2 %70 %71
|
||||||
|
|
||||||
|
%73 = OpBitFieldUExtract %2 %5 %16 %6 ; extracts bit 11 from %5
|
||||||
|
%74 = OpBitFieldUExtract %2 %6 %16 %6 ; extracts bit 11 from %6
|
||||||
|
%75 = OpBitwiseOr %2 %73 %74
|
||||||
|
|
||||||
|
%76 = OpBitFieldUExtract %2 %5 %17 %6 ; extracts bit 12 from %5
|
||||||
|
%77 = OpBitFieldUExtract %2 %6 %17 %6 ; extracts bit 12 from %6
|
||||||
|
%78 = OpBitwiseOr %2 %76 %77
|
||||||
|
|
||||||
|
%79 = OpBitFieldUExtract %2 %5 %18 %6 ; extracts bit 13 from %5
|
||||||
|
%80 = OpBitFieldUExtract %2 %6 %18 %6 ; extracts bit 13 from %6
|
||||||
|
%81 = OpBitwiseOr %2 %79 %80
|
||||||
|
|
||||||
|
%82 = OpBitFieldUExtract %2 %5 %19 %6 ; extracts bit 14 from %5
|
||||||
|
%83 = OpBitFieldUExtract %2 %6 %19 %6 ; extracts bit 14 from %6
|
||||||
|
%84 = OpBitwiseOr %2 %82 %83
|
||||||
|
|
||||||
|
%85 = OpBitFieldUExtract %2 %5 %20 %6 ; extracts bit 15 from %5
|
||||||
|
%86 = OpBitFieldUExtract %2 %6 %20 %6 ; extracts bit 15 from %6
|
||||||
|
%87 = OpBitwiseOr %2 %85 %86
|
||||||
|
|
||||||
|
%88 = OpBitFieldUExtract %2 %5 %21 %6 ; extracts bit 16 from %5
|
||||||
|
%89 = OpBitFieldUExtract %2 %6 %21 %6 ; extracts bit 16 from %6
|
||||||
|
%90 = OpBitwiseOr %2 %88 %89
|
||||||
|
|
||||||
|
%91 = OpBitFieldUExtract %2 %5 %22 %6 ; extracts bit 17 from %5
|
||||||
|
%92 = OpBitFieldUExtract %2 %6 %22 %6 ; extracts bit 17 from %6
|
||||||
|
%93 = OpBitwiseOr %2 %91 %92
|
||||||
|
|
||||||
|
%94 = OpBitFieldUExtract %2 %5 %23 %6 ; extracts bit 18 from %5
|
||||||
|
%95 = OpBitFieldUExtract %2 %6 %23 %6 ; extracts bit 18 from %6
|
||||||
|
%96 = OpBitwiseOr %2 %94 %95
|
||||||
|
|
||||||
|
%97 = OpBitFieldUExtract %2 %5 %24 %6 ; extracts bit 19 from %5
|
||||||
|
%98 = OpBitFieldUExtract %2 %6 %24 %6 ; extracts bit 19 from %6
|
||||||
|
%99 = OpBitwiseOr %2 %97 %98
|
||||||
|
|
||||||
|
%100 = OpBitFieldUExtract %2 %5 %25 %6 ; extracts bit 20 from %5
|
||||||
|
%101 = OpBitFieldUExtract %2 %6 %25 %6 ; extracts bit 20 from %6
|
||||||
|
%102 = OpBitwiseOr %2 %100 %101
|
||||||
|
|
||||||
|
%103 = OpBitFieldUExtract %2 %5 %26 %6 ; extracts bit 21 from %5
|
||||||
|
%104 = OpBitFieldUExtract %2 %6 %26 %6 ; extracts bit 21 from %6
|
||||||
|
%105 = OpBitwiseOr %2 %103 %104
|
||||||
|
|
||||||
|
%106 = OpBitFieldUExtract %2 %5 %27 %6 ; extracts bit 22 from %5
|
||||||
|
%107 = OpBitFieldUExtract %2 %6 %27 %6 ; extracts bit 22 from %6
|
||||||
|
%108 = OpBitwiseOr %2 %106 %107
|
||||||
|
|
||||||
|
%109 = OpBitFieldUExtract %2 %5 %28 %6 ; extracts bit 23 from %5
|
||||||
|
%110 = OpBitFieldUExtract %2 %6 %28 %6 ; extracts bit 23 from %6
|
||||||
|
%111 = OpBitwiseOr %2 %109 %110
|
||||||
|
|
||||||
|
%112 = OpBitFieldUExtract %2 %5 %29 %6 ; extracts bit 24 from %5
|
||||||
|
%113 = OpBitFieldUExtract %2 %6 %29 %6 ; extracts bit 24 from %6
|
||||||
|
%114 = OpBitwiseOr %2 %112 %113
|
||||||
|
|
||||||
|
%115 = OpBitFieldUExtract %2 %5 %30 %6 ; extracts bit 25 from %5
|
||||||
|
%116 = OpBitFieldUExtract %2 %6 %30 %6 ; extracts bit 25 from %6
|
||||||
|
%117 = OpBitwiseOr %2 %115 %116
|
||||||
|
|
||||||
|
%118 = OpBitFieldUExtract %2 %5 %31 %6 ; extracts bit 26 from %5
|
||||||
|
%119 = OpBitFieldUExtract %2 %6 %31 %6 ; extracts bit 26 from %6
|
||||||
|
%120 = OpBitwiseOr %2 %118 %119
|
||||||
|
|
||||||
|
%121 = OpBitFieldUExtract %2 %5 %32 %6 ; extracts bit 27 from %5
|
||||||
|
%122 = OpBitFieldUExtract %2 %6 %32 %6 ; extracts bit 27 from %6
|
||||||
|
%123 = OpBitwiseOr %2 %121 %122
|
||||||
|
|
||||||
|
%124 = OpBitFieldUExtract %2 %5 %33 %6 ; extracts bit 28 from %5
|
||||||
|
%125 = OpBitFieldUExtract %2 %6 %33 %6 ; extracts bit 28 from %6
|
||||||
|
%126 = OpBitwiseOr %2 %124 %125
|
||||||
|
|
||||||
|
%127 = OpBitFieldUExtract %2 %5 %34 %6 ; extracts bit 29 from %5
|
||||||
|
%128 = OpBitFieldUExtract %2 %6 %34 %6 ; extracts bit 29 from %6
|
||||||
|
%129 = OpBitwiseOr %2 %127 %128
|
||||||
|
|
||||||
|
%130 = OpBitFieldUExtract %2 %5 %35 %6 ; extracts bit 30 from %5
|
||||||
|
%131 = OpBitFieldUExtract %2 %6 %35 %6 ; extracts bit 30 from %6
|
||||||
|
%132 = OpBitwiseOr %2 %130 %131
|
||||||
|
|
||||||
|
%133 = OpBitFieldUExtract %2 %5 %36 %6 ; extracts bit 31 from %5
|
||||||
|
%134 = OpBitFieldUExtract %2 %6 %36 %6 ; extracts bit 31 from %6
|
||||||
|
%135 = OpBitwiseOr %2 %133 %134
|
||||||
|
|
||||||
|
%136 = OpBitFieldInsert %2 %42 %45 %6 %6 ; inserts bit 1
|
||||||
|
%137 = OpBitFieldInsert %2 %136 %48 %7 %6 ; inserts bit 2
|
||||||
|
%138 = OpBitFieldInsert %2 %137 %51 %8 %6 ; inserts bit 3
|
||||||
|
%139 = OpBitFieldInsert %2 %138 %54 %9 %6 ; inserts bit 4
|
||||||
|
%140 = OpBitFieldInsert %2 %139 %57 %10 %6 ; inserts bit 5
|
||||||
|
%141 = OpBitFieldInsert %2 %140 %60 %11 %6 ; inserts bit 6
|
||||||
|
%142 = OpBitFieldInsert %2 %141 %63 %12 %6 ; inserts bit 7
|
||||||
|
%143 = OpBitFieldInsert %2 %142 %66 %13 %6 ; inserts bit 8
|
||||||
|
%144 = OpBitFieldInsert %2 %143 %69 %14 %6 ; inserts bit 9
|
||||||
|
%145 = OpBitFieldInsert %2 %144 %72 %15 %6 ; inserts bit 10
|
||||||
|
%146 = OpBitFieldInsert %2 %145 %75 %16 %6 ; inserts bit 11
|
||||||
|
%147 = OpBitFieldInsert %2 %146 %78 %17 %6 ; inserts bit 12
|
||||||
|
%148 = OpBitFieldInsert %2 %147 %81 %18 %6 ; inserts bit 13
|
||||||
|
%149 = OpBitFieldInsert %2 %148 %84 %19 %6 ; inserts bit 14
|
||||||
|
%150 = OpBitFieldInsert %2 %149 %87 %20 %6 ; inserts bit 15
|
||||||
|
%151 = OpBitFieldInsert %2 %150 %90 %21 %6 ; inserts bit 16
|
||||||
|
%152 = OpBitFieldInsert %2 %151 %93 %22 %6 ; inserts bit 17
|
||||||
|
%153 = OpBitFieldInsert %2 %152 %96 %23 %6 ; inserts bit 18
|
||||||
|
%154 = OpBitFieldInsert %2 %153 %99 %24 %6 ; inserts bit 19
|
||||||
|
%155 = OpBitFieldInsert %2 %154 %102 %25 %6 ; inserts bit 20
|
||||||
|
%156 = OpBitFieldInsert %2 %155 %105 %26 %6 ; inserts bit 21
|
||||||
|
%157 = OpBitFieldInsert %2 %156 %108 %27 %6 ; inserts bit 22
|
||||||
|
%158 = OpBitFieldInsert %2 %157 %111 %28 %6 ; inserts bit 23
|
||||||
|
%159 = OpBitFieldInsert %2 %158 %114 %29 %6 ; inserts bit 24
|
||||||
|
%160 = OpBitFieldInsert %2 %159 %117 %30 %6 ; inserts bit 25
|
||||||
|
%161 = OpBitFieldInsert %2 %160 %120 %31 %6 ; inserts bit 26
|
||||||
|
%162 = OpBitFieldInsert %2 %161 %123 %32 %6 ; inserts bit 27
|
||||||
|
%163 = OpBitFieldInsert %2 %162 %126 %33 %6 ; inserts bit 28
|
||||||
|
%164 = OpBitFieldInsert %2 %163 %129 %34 %6 ; inserts bit 29
|
||||||
|
%165 = OpBitFieldInsert %2 %164 %132 %35 %6 ; inserts bit 30
|
||||||
|
%166 = OpBitFieldInsert %2 %165 %135 %36 %6 ; inserts bit 31
|
||||||
|
%39 = OpBitwiseOr %2 %5 %6
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
ASSERT_TRUE(IsValid(env, context.get()));
|
||||||
|
ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
|
||||||
|
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(166, {}),
|
||||||
|
MakeDataDescriptor(39, {})));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
Loading…
Reference in New Issue
Block a user