Skip to content

Commit

Permalink
Merge branch 'OpEntryPointValidation' of https://github.com/raunraun/…
Browse files Browse the repository at this point in the history
…SPIRV-Tools into OpEntryPointValidation
  • Loading branch information
Raun Krisch committed Sep 16, 2019
2 parents 6048e78 + b2e53e8 commit 2d77f9a
Show file tree
Hide file tree
Showing 80 changed files with 3,524 additions and 980 deletions.
1 change: 0 additions & 1 deletion Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ SPVTOOLS_OPT_SRC_FILES := \
source/opt/local_redundancy_elimination.cpp \
source/opt/local_single_block_elim_pass.cpp \
source/opt/local_single_store_elim_pass.cpp \
source/opt/local_ssa_elim_pass.cpp \
source/opt/loop_dependence.cpp \
source/opt/loop_dependence_helpers.cpp \
source/opt/loop_descriptor.cpp \
Expand Down
4 changes: 2 additions & 2 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,6 @@ static_library("spvtools_opt") {
"source/opt/local_single_block_elim_pass.h",
"source/opt/local_single_store_elim_pass.cpp",
"source/opt/local_single_store_elim_pass.h",
"source/opt/local_ssa_elim_pass.cpp",
"source/opt/local_ssa_elim_pass.h",
"source/opt/log.h",
"source/opt/loop_dependence.cpp",
"source/opt/loop_dependence.h",
Expand Down Expand Up @@ -850,6 +848,8 @@ if (build_with_chromium) {
"//testing/gmock",
"//testing/gtest",
"//testing/gtest:gtest_main",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]

if (is_clang) {
Expand Down
20 changes: 19 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
Revision history for SPIRV-Tools

v2019.5-dev 2019-08-08
- Start v2019.5-dev
- General:
- Optimizer
- Add descriptor array scalar replacement (#2742)
- Add pass to wrap OpKill in a function call (#2790)
- Fold FMix during constant folding. (#2818)
- Add pass to replace AMD shader ballot extension (#2811)
- Add pass to make Float32 operation relax precision (#2808)
- Add pass to make relax precision operation Float16 (#2808)
Fixes:
Instrument: Fix version 2 output record write for tess eval shaders. (#2782)
Instrument: Add support for Buffer Device Address extension (#2792)
Fix check for changed binary in API call. (#2798)
- Validator
Fixes:
Fix validation of constant matrices (#2794)
Update "remquor" validation
- Reduce
- Remove relaxed precision decorations (#2797)
Fixes:

v2019.4 2019-08-08
- General:
Expand Down
5 changes: 5 additions & 0 deletions include/spirv-tools/optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ class Optimizer {
// The constructed instance will have an empty message consumer, which just
// ignores all messages from the library. Use SetMessageConsumer() to supply
// one if messages are of concern.
//
// For collections of passes that are meant to transform the input into
// another execution environment, then the source environment should be
// supplied. e.g. for VulkanToWebGPUPasses the environment should be
// SPV_ENV_VULKAN_1_1 not SPV_ENV_WEBGPU_0.
explicit Optimizer(spv_target_env env);

// Disables copy/move constructor/assignment operations.
Expand Down
12 changes: 9 additions & 3 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ set(SPIRV_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_debug.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_decorations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_derivatives.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_entry_point.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_extensions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_execution_limitations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/val/validate_function.cpp
Expand Down Expand Up @@ -339,7 +340,9 @@ spvtools_pch(SPIRV_SOURCES pch_source)
add_library(${SPIRV_TOOLS} ${SPIRV_SOURCES})
spvtools_default_compile_options(${SPIRV_TOOLS})
target_include_directories(${SPIRV_TOOLS}
PUBLIC ${spirv-tools_SOURCE_DIR}/include
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/include>
PRIVATE ${spirv-tools_BINARY_DIR}
PRIVATE ${SPIRV_HEADER_INCLUDE_DIR}
)
Expand All @@ -350,7 +353,9 @@ add_dependencies( ${SPIRV_TOOLS} core_tables enum_string_mapping extinst_tables
add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
spvtools_default_compile_options(${SPIRV_TOOLS}-shared)
target_include_directories(${SPIRV_TOOLS}-shared
PUBLIC ${spirv-tools_SOURCE_DIR}/include
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/include>
PRIVATE ${spirv-tools_BINARY_DIR}
PRIVATE ${SPIRV_HEADER_INCLUDE_DIR}
)
Expand All @@ -372,10 +377,11 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
endif()

if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared
install(TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared EXPORT ${SPIRV_TOOLS}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT ${SPIRV_TOOLS}Targets DESTINATION lib/cmake)
endif(ENABLE_SPIRV_TOOLS_INSTALL)

if(MSVC)
Expand Down
11 changes: 8 additions & 3 deletions source/fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,12 @@ if(SPIRV_BUILD_FUZZER)
endif()

target_include_directories(SPIRV-Tools-fuzz
PUBLIC ${spirv-tools_SOURCE_DIR}/include
PUBLIC ${SPIRV_HEADER_INCLUDE_DIR}
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/include>
PUBLIC
$<BUILD_INTERFACE:${SPIRV_HEADER_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${spirv-tools_BINARY_DIR}
PRIVATE ${CMAKE_BINARY_DIR})

Expand All @@ -133,10 +137,11 @@ if(SPIRV_BUILD_FUZZER)
spvtools_check_symbol_exports(SPIRV-Tools-fuzz)

if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS SPIRV-Tools-fuzz
install(TARGETS SPIRV-Tools-fuzz EXPORT SPIRV-Tools-fuzzTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT SPIRV-Tools-fuzzTargets DESTINATION lib/cmake)
endif(ENABLE_SPIRV_TOOLS_INSTALL)

endif(SPIRV_BUILD_FUZZER)
7 changes: 5 additions & 2 deletions source/fuzz/fuzzer_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ FuzzerContext::~FuzzerContext() = default;

uint32_t FuzzerContext::GetFreshId() { return next_fresh_id_++; }

RandomGenerator* FuzzerContext::GetRandomGenerator() {
return random_generator_;
bool FuzzerContext::ChooseEven() { return random_generator_->RandomBool(); }

bool FuzzerContext::ChoosePercentage(uint32_t percentage_chance) {
assert(percentage_chance <= 100);
return random_generator_->RandomPercentage() < percentage_chance;
}

} // namespace fuzz
Expand Down
25 changes: 19 additions & 6 deletions source/fuzz/fuzzer_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,22 @@ class FuzzerContext {

~FuzzerContext();

// Provides the random generator used to control fuzzing.
RandomGenerator* GetRandomGenerator();
// Returns a random boolean.
bool ChooseEven();

// Returns true if and only if a randomly-chosen integer in the range [0, 100]
// is less than |percentage_chance|.
bool ChoosePercentage(uint32_t percentage_chance);

// Returns a random index into |sequence|, which is expected to have a 'size'
// method, and which must be non-empty. Typically 'HasSizeMethod' will be an
// std::vector.
template <typename HasSizeMethod>
uint32_t RandomIndex(HasSizeMethod sequence) {
assert(sequence.size() > 0);
return random_generator_->RandomUint32(
static_cast<uint32_t>(sequence.size()));
}

// Yields an id that is guaranteed not to be used in the module being fuzzed,
// or to have been issued before.
Expand All @@ -53,11 +67,10 @@ class FuzzerContext {
}
uint32_t GetChanceOfSplittingBlock() { return chance_of_splitting_block_; }

// Probability distributions to control how deeply to recurse.
// Functions to control how deeply to recurse.
// Keep them in alphabetical order.
const std::function<bool(uint32_t, RandomGenerator*)>&
GoDeeperInConstantObfuscation() {
return go_deeper_in_constant_obfuscation_;
bool GoDeeperInConstantObfuscation(uint32_t depth) {
return go_deeper_in_constant_obfuscation_(depth, random_generator_);
}

private:
Expand Down
10 changes: 4 additions & 6 deletions source/fuzz/fuzzer_pass_add_dead_breaks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ void FuzzerPassAddDeadBreaks::Apply() {
// merge blocks. This will lead to interesting opportunities being
// missed.
auto candidate_transformation = TransformationAddDeadBreak(
block.id(), merge_block_id,
GetFuzzerContext()->GetRandomGenerator()->RandomBool(), {});
block.id(), merge_block_id, GetFuzzerContext()->ChooseEven(), {});
if (candidate_transformation.IsApplicable(GetIRContext(),
*GetFactManager())) {
// Only consider a transformation as a candidate if it is applicable.
Expand All @@ -77,16 +76,15 @@ void FuzzerPassAddDeadBreaks::Apply() {
while (!candidate_transformations.empty()) {
// Choose a random index into the sequence of remaining candidate
// transformations.
auto index = GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(candidate_transformations.size()));
auto index = GetFuzzerContext()->RandomIndex(candidate_transformations);
// Remove the transformation at the chosen index from the sequence.
auto transformation = std::move(candidate_transformations[index]);
candidate_transformations.erase(candidate_transformations.begin() + index);
// Probabilistically decide whether to try to apply it vs. ignore it, in the
// case that it is applicable.
if (transformation.IsApplicable(GetIRContext(), *GetFactManager()) &&
GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfAddingDeadBreak()) {
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAddingDeadBreak())) {
transformation.Apply(GetIRContext(), GetFactManager());
*GetTransformations()->add_transformation() = transformation.ToMessage();
}
Expand Down
7 changes: 3 additions & 4 deletions source/fuzz/fuzzer_pass_add_dead_continues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,13 @@ void FuzzerPassAddDeadContinues::Apply() {
// merge blocks. This will lead to interesting opportunities being
// missed.
auto candidate_transformation = TransformationAddDeadContinue(
block.id(), GetFuzzerContext()->GetRandomGenerator()->RandomBool(),
{});
block.id(), GetFuzzerContext()->ChooseEven(), {});
// Probabilistically decide whether to apply the transformation in the
// case that it is applicable.
if (candidate_transformation.IsApplicable(GetIRContext(),
*GetFactManager()) &&
GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfAddingDeadContinue()) {
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAddingDeadContinue())) {
candidate_transformation.Apply(GetIRContext(), GetFactManager());
*GetTransformations()->add_transformation() =
candidate_transformation.ToMessage();
Expand Down
39 changes: 15 additions & 24 deletions source/fuzz/fuzzer_pass_obfuscate_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,12 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair(
// a 'greater than' or 'less than' kind of opcode, and then select a
// random opcode from the resulting subset.
SpvOp comparison_opcode;
if (GetFuzzerContext()->GetRandomGenerator()->RandomBool()) {
comparison_opcode = greater_than_opcodes
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(greater_than_opcodes.size()))];
if (GetFuzzerContext()->ChooseEven()) {
comparison_opcode = greater_than_opcodes[GetFuzzerContext()->RandomIndex(
greater_than_opcodes)];
} else {
comparison_opcode = less_than_opcodes
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(less_than_opcodes.size()))];
comparison_opcode =
less_than_opcodes[GetFuzzerContext()->RandomIndex(less_than_opcodes)];
}

// We now need to decide how to order constant_id_1 and constant_id_2 such
Expand Down Expand Up @@ -103,8 +101,7 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair(
for (uint32_t index : {0u, 1u}) {
// We randomly decide, based on the current depth of obfuscation, whether
// to further obfuscate this operand.
if (GetFuzzerContext()->GoDeeperInConstantObfuscation()(
depth, GetFuzzerContext()->GetRandomGenerator())) {
if (GetFuzzerContext()->GoDeeperInConstantObfuscation(depth)) {
auto in_operand_use = transformation::MakeIdUseDescriptor(
binary_operator_instruction->GetSingleWordInOperand(index),
binary_operator_instruction->opcode(), index,
Expand Down Expand Up @@ -252,9 +249,9 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstant(
// elements with known values.
return;
}
auto chosen_type_id = available_types_with_uniforms
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(available_types_with_uniforms.size()))];
auto chosen_type_id =
available_types_with_uniforms[GetFuzzerContext()->RandomIndex(
available_types_with_uniforms)];
auto available_constants =
GetFactManager()->GetConstantsAvailableFromUniformsForType(
GetIRContext(), chosen_type_id);
Expand All @@ -269,15 +266,12 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstant(

// We know we have at least two known-to-be-constant uniforms of the chosen
// type. Pick one of them at random.
auto constant_index_1 =
GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(available_constants.size()));
auto constant_index_1 = GetFuzzerContext()->RandomIndex(available_constants);
uint32_t constant_index_2;

// Now choose another one distinct from the first one.
do {
constant_index_2 = GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(available_constants.size()));
constant_index_2 = GetFuzzerContext()->RandomIndex(available_constants);
} while (constant_index_1 == constant_index_2);

auto constant_id_1 = available_constants[constant_index_1];
Expand Down Expand Up @@ -321,9 +315,7 @@ void FuzzerPassObfuscateConstants::ObfuscateScalarConstant(

// Choose a random available uniform known to be equal to the constant.
protobufs::UniformBufferElementDescriptor uniform_descriptor =
uniform_descriptors
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(uniform_descriptors.size()))];
uniform_descriptors[GetFuzzerContext()->RandomIndex(uniform_descriptors)];
// Create, apply and record a transformation to replace the constant use with
// the result of a load from the chosen uniform.
auto transformation = TransformationReplaceConstantWithUniform(
Expand Down Expand Up @@ -445,13 +437,12 @@ void FuzzerPassObfuscateConstants::Apply() {
// Go through the constant uses in a random order by repeatedly pulling out a
// constant use at a random index.
while (!constant_uses.empty()) {
auto index = GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(constant_uses.size()));
auto index = GetFuzzerContext()->RandomIndex(constant_uses);
auto constant_use = std::move(constant_uses[index]);
constant_uses.erase(constant_uses.begin() + index);
// Decide probabilistically whether to skip or obfuscate this constant use.
if (GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfObfuscatingConstant()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfObfuscatingConstant())) {
continue;
}
ObfuscateConstant(0, constant_use);
Expand Down
4 changes: 2 additions & 2 deletions source/fuzz/fuzzer_pass_permute_blocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ void FuzzerPassPermuteBlocks::Apply() {
// would provide more freedom for A to move.
for (auto id = block_ids.rbegin(); id != block_ids.rend(); ++id) {
// Randomly decide whether to ignore the block id.
if (GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfMovingBlockDown()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfMovingBlockDown())) {
continue;
}
// Keep pushing the block down, until pushing down fails.
Expand Down
10 changes: 5 additions & 5 deletions source/fuzz/fuzzer_pass_split_blocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ void FuzzerPassSplitBlocks::Apply() {
// Now go through all the block pointers that were gathered.
for (auto& block : blocks) {
// Probabilistically decide whether to try to split this block.
if (GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfSplittingBlock()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfSplittingBlock())) {
// We are not going to try to split this block.
continue;
}
// We are going to try to split this block. We now need to choose where
Expand Down Expand Up @@ -77,9 +78,8 @@ void FuzzerPassSplitBlocks::Apply() {
}
// Having identified all the places we might be able to split the block,
// we choose one of them.
auto base_offset = base_offset_pairs
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(base_offset_pairs.size()))];
auto base_offset =
base_offset_pairs[GetFuzzerContext()->RandomIndex(base_offset_pairs)];
auto transformation =
TransformationSplitBlock(base_offset.first, base_offset.second,
GetFuzzerContext()->GetFreshId());
Expand Down
Loading

0 comments on commit 2d77f9a

Please sign in to comment.