Introduce spirv-diff (#4611)

spirv-diff is a new tool that produces diff-style output comparing two
SPIR-V modules.  The instructions between the src and dst modules are
matched as best as the tool can, and output is produced (in src
id-space) that shows which instructions are removed in src, added in dst
or modified between them.  The order of instructions are not retained.

Matching instructions between two SPIR-V modules is not trivial, and
thus a number of heuristics are applied in this tool.  In particular,
without debug information, it's hard to match functions as they can be
reordered.  As such, this tool is primarily useful to produce the diff
of two SPIR-V modules derived from the same source.

This tool can be useful in a number of scenarios:

- Compare the SPIR-V before and after modifying a shader
- Compare the SPIR-V produced from a shader before and after compiler
  codegen changes.
- Compare the SPIR-V produced from a shader before and after some
  transformation or optimization.
- Compare the SPIR-V produced from a shader with different compilers.
This commit is contained in:
Shahbaz Youssefi 2022-02-02 10:33:18 -05:00 committed by GitHub
parent b846f8f1dc
commit 7fa9e746ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 19013 additions and 2 deletions

View File

@ -212,6 +212,24 @@ issue](https://github.com/KhronosGroup/SPIRV-Tools/issues]) with
"Fuzzer:" as the start of its title.
### Diff
*Note:* The diff tool is still under development.
The diff tool takes two SPIR-V files, either in binary or text format and
produces a diff-style comparison between the two. The instructions between the
src and dst modules are matched as best as the tool can, and output is produced
(in src id-space) that shows which instructions are removed in src, added in dst
or modified between them. The order of instructions are not retained.
Matching instructions between two SPIR-V modules is not trivial, and thus a
number of heuristics are applied in this tool. In particular, without debug
information, match functions is nontrivial as they can be reordered. As such,
this tool is primarily useful to produce the diff of two SPIR-V modules derived
from the same source, for example before and after a modification to the shader,
before and after a transformation, or SPIR-V produced from different tools.
### Extras
* [Utility filters](#utility-filters)
@ -624,6 +642,15 @@ This is experimental.
* `spirv-cfg` - the control flow graph dumper
* `<spirv-dir>/tools/cfg`
### Diff tool
*Warning:* This functionality is under development, and is incomplete.
The diff tool produces a diff-style comparison between two SPIR-V modules.
* `spirv-diff` - the standalone diff tool
* `<spirv-dir>`/tools/diff`
### Utility filters
* `spirv-lesspipe.sh` - Automatically disassembles `.spv` binary files for the

View File

@ -217,6 +217,7 @@ add_subdirectory(reduce)
add_subdirectory(fuzz)
add_subdirectory(link)
add_subdirectory(lint)
add_subdirectory(diff)
set(SPIRV_SOURCES
${spirv-tools_SOURCE_DIR}/include/spirv-tools/libspirv.h

View File

@ -0,0 +1,54 @@
# Copyright (c) 2022 Google LLC.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(SPIRV_TOOLS_DIFF_SOURCES
diff.h
lcs.h
diff.cpp
)
add_library(SPIRV-Tools-diff ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_DIFF_SOURCES})
spvtools_default_compile_options(SPIRV-Tools-diff)
target_include_directories(SPIRV-Tools-diff
PUBLIC
$<BUILD_INTERFACE:${spirv-tools_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${SPIRV_HEADER_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${spirv-tools_BINARY_DIR}
)
# We need the assembling and disassembling functionalities in the main library.
target_link_libraries(SPIRV-Tools-diff
PUBLIC ${SPIRV_TOOLS_FULL_VISIBILITY})
# We need the internals of spirv-opt.
target_link_libraries(SPIRV-Tools-diff
PUBLIC SPIRV-Tools-opt)
set_property(TARGET SPIRV-Tools-diff PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(SPIRV-Tools-diff)
if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS SPIRV-Tools-diff EXPORT SPIRV-Tools-diffTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
export(EXPORT SPIRV-Tools-diffTargets FILE SPIRV-Tools-diffTargets.cmake)
spvtools_config_package_dir(SPIRV-Tools-diff PACKAGE_DIR)
install(EXPORT SPIRV-Tools-diffTargets FILE SPIRV-Tools-diffTargets.cmake
DESTINATION ${PACKAGE_DIR})
spvtools_generate_config_file(SPIRV-Tools-diff)
install(FILES ${CMAKE_BINARY_DIR}/SPIRV-Tools-diffConfig.cmake DESTINATION ${PACKAGE_DIR})
endif(ENABLE_SPIRV_TOOLS_INSTALL)

2658
source/diff/diff.cpp Normal file

File diff suppressed because it is too large Load Diff

48
source/diff/diff.h Normal file
View File

@ -0,0 +1,48 @@
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SOURCE_DIFF_DIFF_H_
#define SOURCE_DIFF_DIFF_H_
#include "source/opt/ir_context.h"
namespace spvtools {
namespace diff {
struct Options {
bool ignore_set_binding = false;
bool ignore_location = false;
bool indent = false;
bool no_header = false;
bool color_output = false;
bool dump_id_map = false;
};
// Given two SPIR-V modules, this function outputs the textual diff of their
// assembly in `out`. The diff is *semantic*, so that the ordering of certain
// instructions wouldn't matter.
//
// The output is a disassembly of src, with diff(1)-style + and - lines that
// show how the src is changed into dst. To make this disassembly
// self-consistent, the ids that are output are all in the space of the src
// module; e.g. any + lines (showing instructions from the dst module) have
// their ids mapped to the matched instruction in the src module (or a new id
// allocated in the src module if unmatched).
spv_result_t Diff(opt::IRContext* src, opt::IRContext* dst, std::ostream& out,
Options options);
} // namespace diff
} // namespace spvtools
#endif // SOURCE_DIFF_DIFF_H_

195
source/diff/lcs.h Normal file
View File

@ -0,0 +1,195 @@
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SOURCE_DIFF_LCS_H_
#define SOURCE_DIFF_LCS_H_
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <functional>
#include <vector>
namespace spvtools {
namespace diff {
// The result of a diff.
using DiffMatch = std::vector<bool>;
// Helper class to find the longest common subsequence between two function
// bodies.
template <typename Sequence>
class LongestCommonSubsequence {
public:
LongestCommonSubsequence(const Sequence& src, const Sequence& dst)
: src_(src),
dst_(dst),
table_(src.size(), std::vector<DiffMatchEntry>(dst.size())) {}
// Given two sequences, it creates a matching between them. The elements are
// simply marked as matched in src and dst, with any unmatched element in src
// implying a removal and any unmatched element in dst implying an addition.
//
// Returns the length of the longest common subsequence.
template <typename T>
size_t Get(std::function<bool(T src_elem, T dst_elem)> match,
DiffMatch* src_match_result, DiffMatch* dst_match_result);
private:
template <typename T>
size_t CalculateLCS(size_t src_start, size_t dst_start,
std::function<bool(T src_elem, T dst_elem)> match);
void RetrieveMatch(DiffMatch* src_match_result, DiffMatch* dst_match_result);
bool IsInBound(size_t src_index, size_t dst_index) {
return src_index < src_.size() && dst_index < dst_.size();
}
bool IsCalculated(size_t src_index, size_t dst_index) {
assert(IsInBound(src_index, dst_index));
return table_[src_index][dst_index].valid;
}
size_t GetMemoizedLength(size_t src_index, size_t dst_index) {
if (!IsInBound(src_index, dst_index)) {
return 0;
}
assert(IsCalculated(src_index, dst_index));
return table_[src_index][dst_index].best_match_length;
}
bool IsMatched(size_t src_index, size_t dst_index) {
assert(IsCalculated(src_index, dst_index));
return table_[src_index][dst_index].matched;
}
const Sequence& src_;
const Sequence& dst_;
struct DiffMatchEntry {
size_t best_match_length = 0;
// Whether src[i] and dst[j] matched. This is an optimization to avoid
// calling the `match` function again when walking the LCS table.
bool matched = false;
// Use for the recursive algorithm to know if the contents of this entry are
// valid.
bool valid = false;
};
std::vector<std::vector<DiffMatchEntry>> table_;
};
template <typename Sequence>
template <typename T>
size_t LongestCommonSubsequence<Sequence>::Get(
std::function<bool(T src_elem, T dst_elem)> match,
DiffMatch* src_match_result, DiffMatch* dst_match_result) {
size_t best_match_length = CalculateLCS(0, 0, match);
RetrieveMatch(src_match_result, dst_match_result);
return best_match_length;
}
template <typename Sequence>
template <typename T>
size_t LongestCommonSubsequence<Sequence>::CalculateLCS(
size_t src_start, size_t dst_start,
std::function<bool(T src_elem, T dst_elem)> match) {
// The LCS algorithm is simple. Given sequences s and d, with a:b depicting a
// range in python syntax:
//
// lcs(s[i:], d[j:]) =
// lcs(s[i+1:], d[j+1:]) + 1 if s[i] == d[j]
// max(lcs(s[i+1:], d[j:]), lcs(s[i:], d[j+1:])) o.w.
//
// Once the LCS table is filled according to the above, it can be walked and
// the best match retrieved.
//
// This is a recursive function with memoization, which avoids filling table
// entries where unnecessary. This makes the best case O(N) instead of
// O(N^2).
// To avoid unnecessary recursion on long sequences, process a whole strip of
// matching elements in one go.
size_t src_cur = src_start;
size_t dst_cur = dst_start;
while (IsInBound(src_cur, dst_cur) && !IsCalculated(src_cur, dst_cur) &&
match(src_[src_cur], dst_[dst_cur])) {
++src_cur;
++dst_cur;
}
// We've reached a pair of elements that don't match. Recursively determine
// which one should be left unmatched.
size_t best_match_length = 0;
if (IsInBound(src_cur, dst_cur)) {
if (IsCalculated(src_cur, dst_cur)) {
best_match_length = GetMemoizedLength(src_cur, dst_cur);
} else {
best_match_length = std::max(CalculateLCS(src_cur + 1, dst_cur, match),
CalculateLCS(src_cur, dst_cur + 1, match));
// Fill the table with this information
DiffMatchEntry& entry = table_[src_cur][dst_cur];
assert(!entry.valid);
entry.best_match_length = best_match_length;
entry.valid = true;
}
}
// Go over the matched strip and update the table as well.
assert(src_cur - src_start == dst_cur - dst_start);
size_t contiguous_match_len = src_cur - src_start;
for (size_t i = 0; i < contiguous_match_len; ++i) {
--src_cur;
--dst_cur;
assert(IsInBound(src_cur, dst_cur));
DiffMatchEntry& entry = table_[src_cur][dst_cur];
assert(!entry.valid);
entry.best_match_length = ++best_match_length;
entry.matched = true;
entry.valid = true;
}
return best_match_length;
}
template <typename Sequence>
void LongestCommonSubsequence<Sequence>::RetrieveMatch(
DiffMatch* src_match_result, DiffMatch* dst_match_result) {
src_match_result->clear();
dst_match_result->clear();
src_match_result->resize(src_.size(), false);
dst_match_result->resize(dst_.size(), false);
size_t src_cur = 0;
size_t dst_cur = 0;
while (IsInBound(src_cur, dst_cur)) {
if (IsMatched(src_cur, dst_cur)) {
(*src_match_result)[src_cur++] = true;
(*dst_match_result)[dst_cur++] = true;
continue;
}
if (GetMemoizedLength(src_cur + 1, dst_cur) >=
GetMemoizedLength(src_cur, dst_cur + 1)) {
++src_cur;
} else {
++dst_cur;
}
}
}
} // namespace diff
} // namespace spvtools
#endif // SOURCE_DIFF_LCS_H_

View File

@ -87,6 +87,12 @@ struct Operand {
spv_operand_type_t type; // Type of this logical operand.
OperandData words; // Binary segments of this logical operand.
uint32_t AsId() const {
assert(spvIsIdType(type));
assert(words.size() == 1);
return words[0];
}
// Returns a string operand as a std::string.
std::string AsString() const {
assert(type == SPV_OPERAND_TYPE_LITERAL_STRING);
@ -95,7 +101,10 @@ struct Operand {
// Returns a literal integer operand as a uint64_t
uint64_t AsLiteralUint64() const {
assert(type == SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER);
assert(type == SPV_OPERAND_TYPE_LITERAL_INTEGER ||
type == SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER ||
type == SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER ||
type == SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
assert(1 <= words.size());
assert(words.size() <= 2);
uint64_t result = 0;
@ -294,6 +303,7 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
inline void SetInOperands(OperandList&& new_operands);
// Sets the result type id.
inline void SetResultType(uint32_t ty_id);
inline bool HasResultType() const { return has_type_id_; }
// Sets the result id
inline void SetResultId(uint32_t res_id);
inline bool HasResultId() const { return has_result_id_; }

View File

@ -24,7 +24,9 @@ namespace spvtools {
void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst,
const spv_parsed_operand_t& operand) {
if (operand.type != SPV_OPERAND_TYPE_LITERAL_INTEGER &&
operand.type != SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER)
operand.type != SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER &&
operand.type != SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER &&
operand.type != SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER)
return;
if (operand.num_words < 1) return;
// TODO(dneto): Support more than 64-bits at a time.

View File

@ -185,6 +185,7 @@ add_spvtools_unittest(
endif()
add_subdirectory(diff)
add_subdirectory(link)
add_subdirectory(lint)
add_subdirectory(opt)

26
test/diff/CMakeLists.txt Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 2022 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include(diff_files/diff_test_files_autogen.cmake)
add_spvtools_unittest(TARGET lcs
SRCS lcs_test.cpp
LIBS SPIRV-Tools-diff
)
add_spvtools_unittest(TARGET diff
SRCS diff_test.cpp diff_test_utils.h diff_test_utils.cpp
${DIFF_TEST_FILES} ${spirv-tools_SOURCE_DIR}/tools/util/cli_consumer.cpp
LIBS SPIRV-Tools-diff
)

3
test/diff/diff_files/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# To aid debugging no-dbg variants, the temporary files used to strip debug information are placed
# in a hidden directory and aren't removed after generation.
.no_dbg/

View File

@ -0,0 +1,242 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Tests a diff where the src shader doesn't have OpExtImport while the
// dst shader does (and uses OpExtInst). This test ensures that when matching,
// the OpExtImport instruction from the correct module is referenced.
constexpr char kSrc[] = R"( OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpExtInst %6 %1 Log2 %12
%14 = OpCompositeConstruct %7 %13 %13 %13 %13
OpStore %9 %14
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, OpextinstInDstOnly) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 14
+; Bound: 16
; Schema: 0
OpCapability Shader
+%14 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
+OpDecorate %15 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
+%15 = OpExtInst %6 %14 Log2 %12
-%13 = OpCompositeConstruct %7 %12 %12 %12 %12
+%13 = OpCompositeConstruct %7 %15 %15 %15 %15
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, OpextinstInDstOnlyNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpExtInst %6 %1 Log2 %12
%14 = OpCompositeConstruct %7 %13 %13 %13 %13
OpStore %9 %14
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 14
+; Bound: 16
; Schema: 0
OpCapability Shader
+%14 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
+OpDecorate %15 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
+%15 = OpExtInst %6 %14 Log2 %12
-%13 = OpCompositeConstruct %7 %12 %12 %12 %12
+%13 = OpCompositeConstruct %7 %15 %15 %15 %15
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,33 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpExtInst %6 %1 Log2 %12
%14 = OpCompositeConstruct %7 %13 %13 %13 %13
OpStore %9 %14
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,33 @@
;; Tests a diff where the src shader doesn't have OpExtImport while the
;; dst shader does (and uses OpExtInst). This test ensures that when matching,
;; the OpExtImport instruction from the correct module is referenced.
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,242 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Tests a diff where the dst shader doesn't have OpExtImport while the
// src shader does (and uses OpExtInst). This test ensures that when matching,
// the OpExtImport instruction from the correct module is referenced.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpExtInst %6 %1 Log2 %12
%14 = OpCompositeConstruct %7 %13 %13 %13 %13
OpStore %9 %14
OpReturn
OpFunctionEnd
)";
constexpr char kDst[] = R"( OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, OpextinstInSrcOnly) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 15
+; Bound: 16
; Schema: 0
OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
-OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
-%13 = OpExtInst %6 %1 Log2 %12
-%14 = OpCompositeConstruct %7 %13 %13 %13 %13
+%14 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %14
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, OpextinstInSrcOnlyNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpExtInst %6 %1 Log2 %12
%14 = OpCompositeConstruct %7 %13 %13 %13 %13
OpStore %9 %14
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 15
+; Bound: 16
; Schema: 0
OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
-OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
-%13 = OpExtInst %6 %1 Log2 %12
-%14 = OpCompositeConstruct %7 %13 %13 %13 %13
+%14 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %14
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,30 @@
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,36 @@
;; Tests a diff where the dst shader doesn't have OpExtImport while the
;; src shader does (and uses OpExtInst). This test ensures that when matching,
;; the OpExtImport instruction from the correct module is referenced.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpExtInst %6 %1 Log2 %12
%14 = OpCompositeConstruct %7 %13 %13 %13 %13
OpStore %9 %14
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,17 @@
# Diff tests
This directory contains files used to ensure correctness of the `spirv-diff` implementation. The
`generate_tests.py` script takes `name_src.spvasm` and `name_dst.spvasm` (for each `name`) and
produces unit test files in the form of `name_autogen.cpp`.
The unit test files test the diff between the src and dst inputs, as well as between debug-stripped
versions of those. Additionally, based on the `{variant}_TESTS` lists defined in
`generate_tests.py`, extra unit tests are added to exercise different options of spirv-diff.
New tests are added simply by placing a new `name_src.spvasm` and `name_dst.spvasm` pair in this
directory and running `generate_tests.py`. Note that this script needs the path to the spirv-diff
executable that is built.
The `generate_tests.py` script additionally expects `name_src.spvasm` to include a heading where the
purpose of the test is explained. This heading is parsed as a block of lines starting with `;;` at
the top of the file.

View File

@ -0,0 +1,407 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Basic test for spirv-diff
constexpr char kSrc[] = R"(; SPIR-V
; Version: 1.0
; Generator: Google ANGLE Shader Compiler; 0
; Bound: 27
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %14 %19
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %14 "ANGLEXfbPosition"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
OpDecorate %14 Location 0
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
%15 = OpConstant %5 8
%16 = OpTypeArray %1 %15
%17 = OpTypeStruct %2 %1 %16 %16
%20 = OpTypeVoid
%25 = OpConstant %6 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%14 = OpVariable %13 Output
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd)";
constexpr char kDst[] = R"(; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 28
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13 %17 %27
OpSource GLSL 450
OpName %4 "main"
OpName %11 "gl_PerVertex"
OpMemberName %11 0 "gl_Position"
OpMemberName %11 1 "gl_PointSize"
OpMemberName %11 2 "gl_ClipDistance"
OpMemberName %11 3 "gl_CullDistance"
OpName %13 ""
OpName %17 "_ua_position"
OpName %27 "ANGLEXfbPosition"
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %11 Block
OpDecorate %17 Location 0
OpDecorate %27 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
%16 = OpTypePointer Input %7
%17 = OpVariable %16 Input
%19 = OpTypePointer Output %7
%27 = OpVariable %19 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpLoad %7 %17
%20 = OpAccessChain %19 %13 %15
OpStore %20 %18
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, Basic) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
+; Bound: 36
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %22 "main" %4 %14 %19
+OpEntryPoint Vertex %22 "main" %19 %4 %14
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %14 "ANGLEXfbPosition"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
OpDecorate %14 Location 0
-OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-%17 = OpTypeStruct %2 %1 %16 %16
+%17 = OpTypeStruct %2 %1 %29 %29
+%28 = OpConstant %5 1
+%29 = OpTypeArray %1 %28
%20 = OpTypeVoid
%25 = OpConstant %6 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%14 = OpVariable %13 Output
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, BasicNoDebug) {
constexpr char kSrcNoDebug[] = R"(; SPIR-V
; Version: 1.0
; Generator: Google ANGLE Shader Compiler; 0
; Bound: 27
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %14 %19
OpSource GLSL 450
OpDecorate %4 Location 0
OpDecorate %14 Location 0
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
%15 = OpConstant %5 8
%16 = OpTypeArray %1 %15
%17 = OpTypeStruct %2 %1 %16 %16
%20 = OpTypeVoid
%25 = OpConstant %6 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%14 = OpVariable %13 Output
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"(; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 28
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13 %17 %27
OpSource GLSL 450
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %11 Block
OpDecorate %17 Location 0
OpDecorate %27 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
%16 = OpTypePointer Input %7
%17 = OpVariable %16 Input
%19 = OpTypePointer Output %7
%27 = OpVariable %19 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpLoad %7 %17
%20 = OpAccessChain %19 %13 %15
OpStore %20 %18
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
+; Bound: 36
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %22 "main" %4 %14 %19
+OpEntryPoint Vertex %22 "main" %19 %4 %14
OpSource GLSL 450
OpDecorate %4 Location 0
OpDecorate %14 Location 0
-OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-%17 = OpTypeStruct %2 %1 %16 %16
+%17 = OpTypeStruct %2 %1 %29 %29
+%28 = OpConstant %5 1
+%29 = OpTypeArray %1 %28
%20 = OpTypeVoid
%25 = OpConstant %6 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%14 = OpVariable %13 Output
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
TEST(DiffTest, BasicDumpIds) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
+; Bound: 36
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %22 "main" %4 %14 %19
+OpEntryPoint Vertex %22 "main" %19 %4 %14
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %14 "ANGLEXfbPosition"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
OpDecorate %14 Location 0
-OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-%17 = OpTypeStruct %2 %1 %16 %16
+%17 = OpTypeStruct %2 %1 %29 %29
+%28 = OpConstant %5 1
+%29 = OpTypeArray %1 %28
%20 = OpTypeVoid
%25 = OpConstant %6 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%14 = OpVariable %13 Output
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
Src -> Dst
1 -> 6 [TypeFloat]
2 -> 7 [TypeVector]
3 -> 16 [TypePointer]
4 -> 17 [Variable]
5 -> 8 [TypeInt]
6 -> 14 [TypeInt]
13 -> 19 [TypePointer]
14 -> 27 [Variable]
15 -> 34 [Constant]
16 -> 35 [TypeArray]
17 -> 11 [TypeStruct]
18 -> 12 [TypePointer]
19 -> 13 [Variable]
20 -> 2 [TypeVoid]
21 -> 3 [TypeFunction]
22 -> 4 [Function]
23 -> 5 [Label]
24 -> 18 [Load]
25 -> 15 [Constant]
26 -> 20 [AccessChain]
)";
Options options;
options.dump_id_map = true;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,49 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 28
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13 %17 %27
OpSource GLSL 450
OpName %4 "main"
OpName %11 "gl_PerVertex"
OpMemberName %11 0 "gl_Position"
OpMemberName %11 1 "gl_PointSize"
OpMemberName %11 2 "gl_ClipDistance"
OpMemberName %11 3 "gl_CullDistance"
OpName %13 ""
OpName %17 "_ua_position"
OpName %27 "ANGLEXfbPosition"
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %11 Block
OpDecorate %17 Location 0
OpDecorate %27 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
%16 = OpTypePointer Input %7
%17 = OpVariable %16 Input
%19 = OpTypePointer Output %7
%27 = OpVariable %19 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpLoad %7 %17
%20 = OpAccessChain %19 %13 %15
OpStore %20 %18
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,50 @@
;; Basic test for spirv-diff
; SPIR-V
; Version: 1.0
; Generator: Google ANGLE Shader Compiler; 0
; Bound: 27
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %14 %19
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %14 "ANGLEXfbPosition"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
OpDecorate %14 Location 0
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
%15 = OpConstant %5 8
%16 = OpTypeArray %1 %15
%17 = OpTypeStruct %2 %1 %16 %16
%20 = OpTypeVoid
%25 = OpConstant %6 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%14 = OpVariable %13 Output
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,35 @@
# GENERATED FILE - DO NOT EDIT.
# Generated by generate_tests.py
#
# Copyright (c) 2022 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
list(APPEND DIFF_TEST_FILES
"diff_files/OpExtInst_in_dst_only_autogen.cpp"
"diff_files/OpExtInst_in_src_only_autogen.cpp"
"diff_files/basic_autogen.cpp"
"diff_files/different_decorations_fragment_autogen.cpp"
"diff_files/different_decorations_vertex_autogen.cpp"
"diff_files/extra_if_block_autogen.cpp"
"diff_files/index_signedness_autogen.cpp"
"diff_files/int_vs_uint_constants_autogen.cpp"
"diff_files/large_functions_large_diffs_autogen.cpp"
"diff_files/large_functions_small_diffs_autogen.cpp"
"diff_files/multiple_different_entry_points_autogen.cpp"
"diff_files/multiple_same_entry_points_autogen.cpp"
"diff_files/reordered_if_blocks_autogen.cpp"
"diff_files/reordered_switch_blocks_autogen.cpp"
"diff_files/small_functions_small_diffs_autogen.cpp"
"diff_files/unrelated_shaders_autogen.cpp"
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %63 "main" %4 %22
OpExecutionMode %63 OriginUpperLeft
OpSource GLSL 450
OpName %4 "_ue"
OpName %8 "_uf"
OpName %11 "_ug"
OpName %12 "_uA"
OpMemberName %12 0 "_ux"
OpName %14 "_uc"
OpName %15 "_uB"
OpMemberName %15 0 "_ux"
OpName %20 "_ud"
OpName %22 "_ucol"
OpName %26 "ANGLEDepthRangeParams"
OpMemberName %26 0 "near"
OpMemberName %26 1 "far"
OpMemberName %26 2 "diff"
OpMemberName %26 3 "reserved"
OpName %27 "ANGLEUniformBlock"
OpMemberName %27 0 "viewport"
OpMemberName %27 1 "clipDistancesEnabled"
OpMemberName %27 2 "xfbActiveUnpaused"
OpMemberName %27 3 "xfbVerticesPerInstance"
OpMemberName %27 4 "numSamples"
OpMemberName %27 5 "xfbBufferOffsets"
OpMemberName %27 6 "acbBufferOffsets"
OpMemberName %27 7 "depthRange"
OpName %29 "ANGLEUniforms"
OpName %33 "_uc"
OpName %32 "_uh"
OpName %49 "_ux"
OpName %50 "_uy"
OpName %48 "_ui"
OpName %63 "main"
OpName %65 "param"
OpName %68 "param"
OpName %73 "param"
OpDecorate %4 Location 1
OpDecorate %8 RelaxedPrecision
OpDecorate %8 DescriptorSet 2
OpDecorate %8 Binding 0
OpDecorate %11 DescriptorSet 3
OpDecorate %11 Binding 0
OpMemberDecorate %12 0 Offset 0
OpMemberDecorate %12 0 RelaxedPrecision
OpDecorate %12 Block
OpDecorate %14 DescriptorSet 3
OpDecorate %14 Binding 1
OpMemberDecorate %15 0 Offset 0
OpMemberDecorate %15 0 RelaxedPrecision
OpDecorate %15 BufferBlock
OpDecorate %20 DescriptorSet 3
OpDecorate %20 Binding 2
OpDecorate %22 RelaxedPrecision
OpDecorate %22 Location 1
OpMemberDecorate %26 0 Offset 0
OpMemberDecorate %26 1 Offset 4
OpMemberDecorate %26 2 Offset 8
OpMemberDecorate %26 3 Offset 12
OpMemberDecorate %27 0 Offset 0
OpMemberDecorate %27 1 Offset 16
OpMemberDecorate %27 2 Offset 20
OpMemberDecorate %27 3 Offset 24
OpMemberDecorate %27 4 Offset 28
OpMemberDecorate %27 5 Offset 32
OpMemberDecorate %27 6 Offset 48
OpMemberDecorate %27 7 Offset 64
OpMemberDecorate %27 2 RelaxedPrecision
OpMemberDecorate %27 4 RelaxedPrecision
OpDecorate %27 Block
OpDecorate %29 DescriptorSet 0
OpDecorate %29 Binding 0
OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %49 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %52 RelaxedPrecision
OpDecorate %53 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %59 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %67 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %72 RelaxedPrecision
OpDecorate %73 RelaxedPrecision
OpDecorate %75 RelaxedPrecision
OpDecorate %76 RelaxedPrecision
OpDecorate %77 RelaxedPrecision
OpDecorate %80 RelaxedPrecision
OpDecorate %81 RelaxedPrecision
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeImage %1 2D 0 0 0 1 Unknown
%6 = OpTypeSampledImage %5
%9 = OpTypeImage %1 2D 0 0 0 2 Rgba8
%12 = OpTypeStruct %2
%15 = OpTypeStruct %2
%16 = OpTypeInt 32 0
%17 = OpConstant %16 2
%18 = OpTypeArray %15 %17
%23 = OpTypeInt 32 1
%24 = OpTypeVector %23 4
%25 = OpTypeVector %16 4
%26 = OpTypeStruct %1 %1 %1 %1
%27 = OpTypeStruct %2 %16 %16 %23 %23 %24 %25 %26
%35 = OpTypeVector %1 2
%40 = OpTypeVector %23 2
%61 = OpTypeVoid
%69 = OpConstant %16 0
%78 = OpConstant %16 1
%82 = OpTypePointer Private %2
%3 = OpTypePointer Input %2
%7 = OpTypePointer UniformConstant %6
%10 = OpTypePointer UniformConstant %9
%13 = OpTypePointer Uniform %12
%19 = OpTypePointer Uniform %18
%83 = OpTypePointer Private %2
%21 = OpTypePointer Output %2
%28 = OpTypePointer Uniform %27
%30 = OpTypePointer Function %2
%70 = OpTypePointer Uniform %2
%31 = OpTypeFunction %2 %30
%47 = OpTypeFunction %2 %30 %30
%62 = OpTypeFunction %61
%4 = OpVariable %3 Input
%8 = OpVariable %7 UniformConstant
%11 = OpVariable %10 UniformConstant
%14 = OpVariable %13 Uniform
%20 = OpVariable %19 Uniform
%22 = OpVariable %21 Output
%29 = OpVariable %28 Uniform
%84 = OpConstant %23 0
%85 = OpConstant %1 0.5
%32 = OpFunction %2 None %31
%33 = OpFunctionParameter %30
%34 = OpLabel
%36 = OpLoad %6 %8
%37 = OpLoad %2 %33
%38 = OpVectorShuffle %35 %37 %37 0 1
%39 = OpImageSampleImplicitLod %2 %36 %38
%41 = OpLoad %2 %33
%42 = OpVectorShuffle %35 %41 %41 2 3
%43 = OpConvertFToS %40 %42
%44 = OpLoad %9 %11
%45 = OpImageRead %2 %44 %43
%46 = OpFAdd %2 %39 %45
OpReturnValue %46
OpFunctionEnd
%48 = OpFunction %2 None %47
%49 = OpFunctionParameter %30
%50 = OpFunctionParameter %30
%51 = OpLabel
%52 = OpLoad %2 %49
%53 = OpVectorShuffle %35 %52 %52 0 1
%54 = OpLoad %2 %50
%55 = OpVectorShuffle %35 %54 %54 2 3
%56 = OpCompositeExtract %1 %53 0
%57 = OpCompositeExtract %1 %53 1
%58 = OpCompositeExtract %1 %55 0
%59 = OpCompositeExtract %1 %55 1
%60 = OpCompositeConstruct %2 %56 %57 %58 %59
OpReturnValue %60
OpFunctionEnd
%63 = OpFunction %61 None %62
%64 = OpLabel
%65 = OpVariable %30 Function
%68 = OpVariable %30 Function
%73 = OpVariable %30 Function
%66 = OpLoad %2 %4
OpStore %65 %66
%67 = OpFunctionCall %2 %32 %65
%71 = OpAccessChain %70 %14 %69
%72 = OpLoad %2 %71
OpStore %68 %72
%74 = OpAccessChain %70 %20 %69 %69
%75 = OpLoad %2 %74
OpStore %73 %75
%76 = OpFunctionCall %2 %48 %68 %73
%77 = OpFAdd %2 %67 %76
%79 = OpAccessChain %70 %20 %78 %69
%80 = OpLoad %2 %79
%81 = OpFAdd %2 %77 %80
OpStore %22 %81
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,198 @@
;; Test where variable set/binding/location decorations are different between
;; src and dst fragment shaders.
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %63 "main" %4 %22
OpExecutionMode %63 OriginUpperLeft
OpSource GLSL 450
OpName %4 "_ue"
OpName %8 "_uf"
OpName %11 "_ug"
OpName %12 "_uA"
OpMemberName %12 0 "_ux"
OpName %14 "_uc"
OpName %15 "_uB"
OpMemberName %15 0 "_ux"
OpName %20 "_ud"
OpName %22 "_ucol"
OpName %26 "ANGLEDepthRangeParams"
OpMemberName %26 0 "near"
OpMemberName %26 1 "far"
OpMemberName %26 2 "diff"
OpMemberName %26 3 "reserved"
OpName %27 "ANGLEUniformBlock"
OpMemberName %27 0 "viewport"
OpMemberName %27 1 "clipDistancesEnabled"
OpMemberName %27 2 "xfbActiveUnpaused"
OpMemberName %27 3 "xfbVerticesPerInstance"
OpMemberName %27 4 "numSamples"
OpMemberName %27 5 "xfbBufferOffsets"
OpMemberName %27 6 "acbBufferOffsets"
OpMemberName %27 7 "depthRange"
OpName %29 "ANGLEUniforms"
OpName %33 "_uc"
OpName %32 "_uh"
OpName %49 "_ux"
OpName %50 "_uy"
OpName %48 "_ui"
OpName %63 "main"
OpName %65 "param"
OpName %68 "param"
OpName %73 "param"
OpDecorate %4 Location 0
OpDecorate %8 RelaxedPrecision
OpDecorate %8 DescriptorSet 0
OpDecorate %8 Binding 0
OpDecorate %11 DescriptorSet 0
OpDecorate %11 Binding 1
OpMemberDecorate %12 0 Offset 0
OpMemberDecorate %12 0 RelaxedPrecision
OpDecorate %12 Block
OpDecorate %14 DescriptorSet 0
OpDecorate %14 Binding 2
OpMemberDecorate %15 0 Offset 0
OpMemberDecorate %15 0 RelaxedPrecision
OpDecorate %15 BufferBlock
OpDecorate %20 DescriptorSet 0
OpDecorate %20 Binding 3
OpDecorate %22 RelaxedPrecision
OpDecorate %22 Location 0
OpMemberDecorate %26 0 Offset 0
OpMemberDecorate %26 1 Offset 4
OpMemberDecorate %26 2 Offset 8
OpMemberDecorate %26 3 Offset 12
OpMemberDecorate %27 0 Offset 0
OpMemberDecorate %27 1 Offset 16
OpMemberDecorate %27 2 Offset 20
OpMemberDecorate %27 3 Offset 24
OpMemberDecorate %27 4 Offset 28
OpMemberDecorate %27 5 Offset 32
OpMemberDecorate %27 6 Offset 48
OpMemberDecorate %27 7 Offset 64
OpMemberDecorate %27 2 RelaxedPrecision
OpMemberDecorate %27 4 RelaxedPrecision
OpDecorate %27 Block
OpDecorate %29 DescriptorSet 0
OpDecorate %29 Binding 4
OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %49 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %52 RelaxedPrecision
OpDecorate %53 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %59 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %67 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %72 RelaxedPrecision
OpDecorate %73 RelaxedPrecision
OpDecorate %75 RelaxedPrecision
OpDecorate %76 RelaxedPrecision
OpDecorate %77 RelaxedPrecision
OpDecorate %80 RelaxedPrecision
OpDecorate %81 RelaxedPrecision
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeImage %1 2D 0 0 0 1 Unknown
%6 = OpTypeSampledImage %5
%9 = OpTypeImage %1 2D 0 0 0 2 Rgba8
%12 = OpTypeStruct %2
%15 = OpTypeStruct %2
%16 = OpTypeInt 32 0
%17 = OpConstant %16 2
%18 = OpTypeArray %15 %17
%23 = OpTypeInt 32 1
%24 = OpTypeVector %23 4
%25 = OpTypeVector %16 4
%26 = OpTypeStruct %1 %1 %1 %1
%27 = OpTypeStruct %2 %16 %16 %23 %23 %24 %25 %26
%35 = OpTypeVector %1 2
%40 = OpTypeVector %23 2
%61 = OpTypeVoid
%69 = OpConstant %16 0
%78 = OpConstant %16 1
%3 = OpTypePointer Input %2
%7 = OpTypePointer UniformConstant %6
%10 = OpTypePointer UniformConstant %9
%13 = OpTypePointer Uniform %12
%19 = OpTypePointer Uniform %18
%21 = OpTypePointer Output %2
%28 = OpTypePointer Uniform %27
%30 = OpTypePointer Function %2
%70 = OpTypePointer Uniform %2
%31 = OpTypeFunction %2 %30
%47 = OpTypeFunction %2 %30 %30
%62 = OpTypeFunction %61
%4 = OpVariable %3 Input
%8 = OpVariable %7 UniformConstant
%11 = OpVariable %10 UniformConstant
%14 = OpVariable %13 Uniform
%20 = OpVariable %19 Uniform
%22 = OpVariable %21 Output
%29 = OpVariable %28 Uniform
%32 = OpFunction %2 None %31
%33 = OpFunctionParameter %30
%34 = OpLabel
%36 = OpLoad %6 %8
%37 = OpLoad %2 %33
%38 = OpVectorShuffle %35 %37 %37 0 1
%39 = OpImageSampleImplicitLod %2 %36 %38
%41 = OpLoad %2 %33
%42 = OpVectorShuffle %35 %41 %41 2 3
%43 = OpConvertFToS %40 %42
%44 = OpLoad %9 %11
%45 = OpImageRead %2 %44 %43
%46 = OpFAdd %2 %39 %45
OpReturnValue %46
OpFunctionEnd
%48 = OpFunction %2 None %47
%49 = OpFunctionParameter %30
%50 = OpFunctionParameter %30
%51 = OpLabel
%52 = OpLoad %2 %49
%53 = OpVectorShuffle %35 %52 %52 0 1
%54 = OpLoad %2 %50
%55 = OpVectorShuffle %35 %54 %54 2 3
%56 = OpCompositeExtract %1 %53 0
%57 = OpCompositeExtract %1 %53 1
%58 = OpCompositeExtract %1 %55 0
%59 = OpCompositeExtract %1 %55 1
%60 = OpCompositeConstruct %2 %56 %57 %58 %59
OpReturnValue %60
OpFunctionEnd
%63 = OpFunction %61 None %62
%64 = OpLabel
%65 = OpVariable %30 Function
%68 = OpVariable %30 Function
%73 = OpVariable %30 Function
%66 = OpLoad %2 %4
OpStore %65 %66
%67 = OpFunctionCall %2 %32 %65
%71 = OpAccessChain %70 %14 %69
%72 = OpLoad %2 %71
OpStore %68 %72
%74 = OpAccessChain %70 %20 %69 %69
%75 = OpLoad %2 %74
OpStore %73 %75
%76 = OpFunctionCall %2 %48 %68 %73
%77 = OpFAdd %2 %67 %76
%79 = OpAccessChain %70 %20 %78 %69
%80 = OpLoad %2 %79
%81 = OpFAdd %2 %77 %80
OpStore %22 %81
OpReturn
OpFunctionEnd

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %40 "main" %4 %5 %6 %8 %25
OpSource GLSL 450
OpName %4 "_ub"
OpName %5 "_uc"
OpName %6 "_ud"
OpName %8 "_ue"
OpName %9 "defaultUniformsVS"
OpMemberName %9 0 "_ua"
OpName %11 ""
OpName %16 "ANGLEDepthRangeParams"
OpMemberName %16 0 "near"
OpMemberName %16 1 "far"
OpMemberName %16 2 "diff"
OpMemberName %16 3 "reserved"
OpName %17 "ANGLEUniformBlock"
OpMemberName %17 0 "viewport"
OpMemberName %17 1 "clipDistancesEnabled"
OpMemberName %17 2 "xfbActiveUnpaused"
OpMemberName %17 3 "xfbVerticesPerInstance"
OpMemberName %17 4 "numSamples"
OpMemberName %17 5 "xfbBufferOffsets"
OpMemberName %17 6 "acbBufferOffsets"
OpMemberName %17 7 "depthRange"
OpName %19 "ANGLEUniforms"
OpName %23 "gl_PerVertex"
OpMemberName %23 0 "gl_Position"
OpName %25 ""
OpName %29 "_ua"
OpName %28 "_uf"
OpName %33 "_uf"
OpName %32 "_ug"
OpName %40 "main"
OpName %42 "param"
OpName %50 "param"
OpName %53 "param"
OpDecorate %4 Location 1
OpDecorate %5 Location 2
OpDecorate %6 Location 0
OpDecorate %8 Location 1
OpMemberDecorate %9 0 Offset 0
OpDecorate %9 Block
OpDecorate %11 DescriptorSet 0
OpDecorate %11 Binding 1
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 Offset 4
OpMemberDecorate %16 2 Offset 8
OpMemberDecorate %16 3 Offset 12
OpMemberDecorate %17 0 Offset 0
OpMemberDecorate %17 1 Offset 16
OpMemberDecorate %17 2 Offset 20
OpMemberDecorate %17 3 Offset 24
OpMemberDecorate %17 4 Offset 28
OpMemberDecorate %17 5 Offset 32
OpMemberDecorate %17 6 Offset 48
OpMemberDecorate %17 7 Offset 64
OpMemberDecorate %17 2 RelaxedPrecision
OpMemberDecorate %17 4 RelaxedPrecision
OpDecorate %17 Block
OpDecorate %19 DescriptorSet 2
OpDecorate %19 Binding 0
OpMemberDecorate %23 0 BuiltIn Position
OpDecorate %23 Block
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %52 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%9 = OpTypeStruct %2
%12 = OpTypeInt 32 0
%13 = OpTypeInt 32 1
%14 = OpTypeVector %13 4
%15 = OpTypeVector %12 4
%16 = OpTypeStruct %1 %1 %1 %1
%17 = OpTypeStruct %2 %12 %12 %13 %13 %14 %15 %16
%21 = OpConstant %12 8
%22 = OpTypeArray %1 %21
%23 = OpTypeStruct %2
%38 = OpTypeVoid
%45 = OpConstant %12 0
%58 = OpTypePointer Private %2
%3 = OpTypePointer Input %2
%59 = OpTypePointer Private %2
%7 = OpTypePointer Output %2
%10 = OpTypePointer Uniform %9
%18 = OpTypePointer Uniform %17
%24 = OpTypePointer Output %23
%26 = OpTypePointer Function %2
%46 = OpTypePointer Uniform %2
%27 = OpTypeFunction %2 %26
%39 = OpTypeFunction %38
%4 = OpVariable %3 Input
%5 = OpVariable %3 Input
%6 = OpVariable %3 Input
%8 = OpVariable %7 Output
%11 = OpVariable %10 Uniform
%19 = OpVariable %18 Uniform
%20 = OpVariable %59 Private
%25 = OpVariable %24 Output
%60 = OpConstant %13 0
%61 = OpConstant %1 0.5
%28 = OpFunction %2 None %27
%29 = OpFunctionParameter %26
%30 = OpLabel
%31 = OpLoad %2 %29
OpReturnValue %31
OpFunctionEnd
%32 = OpFunction %2 None %27
%33 = OpFunctionParameter %26
%34 = OpLabel
%35 = OpLoad %2 %33
%36 = OpLoad %2 %33
%37 = OpFAdd %2 %35 %36
OpReturnValue %37
OpFunctionEnd
%40 = OpFunction %38 None %39
%41 = OpLabel
%42 = OpVariable %26 Function
%50 = OpVariable %26 Function
%53 = OpVariable %26 Function
%43 = OpLoad %2 %4
OpStore %42 %43
%44 = OpFunctionCall %2 %28 %42
%47 = OpAccessChain %46 %11 %45
%48 = OpLoad %2 %47
%49 = OpFAdd %2 %44 %48
OpStore %8 %49
%51 = OpLoad %2 %5
OpStore %50 %51
%52 = OpFunctionCall %2 %32 %50
%54 = OpLoad %2 %6
OpStore %53 %54
%55 = OpFunctionCall %2 %28 %53
%56 = OpFAdd %2 %52 %55
%57 = OpAccessChain %7 %25 %45
OpStore %57 %56
%62 = OpAccessChain %7 %25 %60
%63 = OpLoad %2 %62
%64 = OpCompositeExtract %1 %63 0
%65 = OpCompositeExtract %1 %63 1
%66 = OpCompositeExtract %1 %63 2
%67 = OpCompositeExtract %1 %63 3
%69 = OpFNegate %1 %64
%70 = OpFAdd %1 %66 %67
%71 = OpFMul %1 %70 %61
%68 = OpCompositeConstruct %2 %65 %69 %71 %67
OpStore %62 %68
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,155 @@
;; Test where variable set/binding/location decorations are different between
;; src and dst vertex shaders.
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %40 "main" %4 %5 %6 %8 %20 %25
OpSource GLSL 450
OpName %4 "_ub"
OpName %5 "_uc"
OpName %6 "_ud"
OpName %8 "_ue"
OpName %9 "defaultUniformsVS"
OpMemberName %9 0 "_ua"
OpName %11 ""
OpName %16 "ANGLEDepthRangeParams"
OpMemberName %16 0 "near"
OpMemberName %16 1 "far"
OpMemberName %16 2 "diff"
OpMemberName %16 3 "reserved"
OpName %17 "ANGLEUniformBlock"
OpMemberName %17 0 "viewport"
OpMemberName %17 1 "clipDistancesEnabled"
OpMemberName %17 2 "xfbActiveUnpaused"
OpMemberName %17 3 "xfbVerticesPerInstance"
OpMemberName %17 4 "numSamples"
OpMemberName %17 5 "xfbBufferOffsets"
OpMemberName %17 6 "acbBufferOffsets"
OpMemberName %17 7 "depthRange"
OpName %19 "ANGLEUniforms"
OpName %20 "ANGLEXfbPosition"
OpName %23 "gl_PerVertex"
OpMemberName %23 0 "gl_Position"
OpMemberName %23 1 "gl_PointSize"
OpMemberName %23 2 "gl_ClipDistance"
OpMemberName %23 3 "gl_CullDistance"
OpName %25 ""
OpName %29 "_ua"
OpName %28 "_uf"
OpName %33 "_uf"
OpName %32 "_ug"
OpName %40 "main"
OpName %42 "param"
OpName %50 "param"
OpName %53 "param"
OpDecorate %4 Location 0
OpDecorate %5 Location 1
OpDecorate %6 Location 2
OpDecorate %8 Location 0
OpMemberDecorate %9 0 Offset 0
OpDecorate %9 Block
OpDecorate %11 DescriptorSet 0
OpDecorate %11 Binding 0
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 Offset 4
OpMemberDecorate %16 2 Offset 8
OpMemberDecorate %16 3 Offset 12
OpMemberDecorate %17 0 Offset 0
OpMemberDecorate %17 1 Offset 16
OpMemberDecorate %17 2 Offset 20
OpMemberDecorate %17 3 Offset 24
OpMemberDecorate %17 4 Offset 28
OpMemberDecorate %17 5 Offset 32
OpMemberDecorate %17 6 Offset 48
OpMemberDecorate %17 7 Offset 64
OpMemberDecorate %17 2 RelaxedPrecision
OpMemberDecorate %17 4 RelaxedPrecision
OpDecorate %17 Block
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpDecorate %20 Location 1
OpMemberDecorate %23 0 BuiltIn Position
OpMemberDecorate %23 1 BuiltIn PointSize
OpMemberDecorate %23 2 BuiltIn ClipDistance
OpMemberDecorate %23 3 BuiltIn CullDistance
OpDecorate %23 Block
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %52 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%9 = OpTypeStruct %2
%12 = OpTypeInt 32 0
%13 = OpTypeInt 32 1
%14 = OpTypeVector %13 4
%15 = OpTypeVector %12 4
%16 = OpTypeStruct %1 %1 %1 %1
%17 = OpTypeStruct %2 %12 %12 %13 %13 %14 %15 %16
%21 = OpConstant %12 8
%22 = OpTypeArray %1 %21
%23 = OpTypeStruct %2 %1 %22 %22
%38 = OpTypeVoid
%45 = OpConstant %12 0
%3 = OpTypePointer Input %2
%7 = OpTypePointer Output %2
%10 = OpTypePointer Uniform %9
%18 = OpTypePointer Uniform %17
%24 = OpTypePointer Output %23
%26 = OpTypePointer Function %2
%46 = OpTypePointer Uniform %2
%27 = OpTypeFunction %2 %26
%39 = OpTypeFunction %38
%4 = OpVariable %3 Input
%5 = OpVariable %3 Input
%6 = OpVariable %3 Input
%8 = OpVariable %7 Output
%11 = OpVariable %10 Uniform
%19 = OpVariable %18 Uniform
%20 = OpVariable %7 Output
%25 = OpVariable %24 Output
%28 = OpFunction %2 None %27
%29 = OpFunctionParameter %26
%30 = OpLabel
%31 = OpLoad %2 %29
OpReturnValue %31
OpFunctionEnd
%32 = OpFunction %2 None %27
%33 = OpFunctionParameter %26
%34 = OpLabel
%35 = OpLoad %2 %33
%36 = OpLoad %2 %33
%37 = OpFAdd %2 %35 %36
OpReturnValue %37
OpFunctionEnd
%40 = OpFunction %38 None %39
%41 = OpLabel
%42 = OpVariable %26 Function
%50 = OpVariable %26 Function
%53 = OpVariable %26 Function
%43 = OpLoad %2 %4
OpStore %42 %43
%44 = OpFunctionCall %2 %28 %42
%47 = OpAccessChain %46 %11 %45
%48 = OpLoad %2 %47
%49 = OpFAdd %2 %44 %48
OpStore %8 %49
%51 = OpLoad %2 %5
OpStore %50 %51
%52 = OpFunctionCall %2 %32 %50
%54 = OpLoad %2 %6
OpStore %53 %54
%55 = OpFunctionCall %2 %28 %53
%56 = OpFAdd %2 %52 %55
%57 = OpAccessChain %7 %25 %45
OpStore %57 %56
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,867 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Test where src has an extra if block in one function, and dst has an extra
// if block in another function.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %68
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "f1("
OpName %10 "f2("
OpName %13 "v"
OpName %16 "Buffer"
OpMemberName %16 0 "flag1"
OpMemberName %16 1 "flag2"
OpName %18 ""
OpName %45 "v"
OpName %63 "color"
OpName %68 "v"
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
OpDecorate %23 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %66 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %68 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 0
%21 = OpTypePointer Uniform %15
%24 = OpConstant %15 0
%25 = OpTypeBool
%29 = OpConstant %6 1
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%67 = OpTypePointer Input %6
%68 = OpVariable %67 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%66 = OpCompositeConstruct %61 %64 %65 %14 %29
OpStore %63 %66
OpReturn
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
%22 = OpAccessChain %21 %18 %20
%23 = OpLoad %15 %22
%26 = OpINotEqual %25 %23 %24
OpSelectionMerge %28 None
OpBranchConditional %26 %27 %28
%27 = OpLabel
%30 = OpLoad %6 %13
%31 = OpFAdd %6 %30 %29
OpStore %13 %31
OpBranch %28
%28 = OpLabel
%33 = OpAccessChain %21 %18 %32
%34 = OpLoad %15 %33
%35 = OpConvertUToF %6 %34
%36 = OpExtInst %6 %1 Log2 %35
%37 = OpLoad %6 %13
%38 = OpFAdd %6 %37 %36
OpStore %13 %38
%39 = OpLoad %6 %13
%40 = OpLoad %6 %13
%41 = OpExtInst %6 %1 Sqrt %40
%42 = OpFSub %6 %39 %41
OpReturnValue %42
OpFunctionEnd
%10 = OpFunction %6 None %7
%11 = OpLabel
%45 = OpVariable %12 Function
%46 = OpAccessChain %21 %18 %20
%47 = OpLoad %15 %46
%48 = OpConvertUToF %6 %47
%50 = OpFDiv %6 %48 %49
OpStore %45 %50
%51 = OpLoad %6 %45
%54 = OpExtInst %6 %1 FClamp %51 %52 %53
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
%57 = OpLoad %6 %45
%58 = OpExtInst %6 %1 Exp %57
OpReturnValue %58
OpFunctionEnd
)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %69
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "f1("
OpName %10 "f2("
OpName %13 "v"
OpName %16 "Buffer"
OpMemberName %16 0 "flag1"
OpMemberName %16 1 "flag2"
OpName %18 ""
OpName %34 "v"
OpName %63 "color"
OpName %69 "v"
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %67 RelaxedPrecision
OpDecorate %69 RelaxedPrecision
OpDecorate %69 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 1
%21 = OpTypePointer Uniform %15
%35 = OpConstant %19 0
%39 = OpConstant %6 10
%42 = OpConstant %6 0.5
%43 = OpConstant %6 0.699999988
%49 = OpConstant %15 0
%50 = OpTypeBool
%54 = OpConstant %6 0.100000001
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%66 = OpConstant %6 1
%68 = OpTypePointer Input %6
%69 = OpVariable %68 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%67 = OpCompositeConstruct %61 %64 %65 %14 %66
OpStore %63 %67
OpReturn
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
%22 = OpAccessChain %21 %18 %20
%23 = OpLoad %15 %22
%24 = OpConvertUToF %6 %23
%25 = OpExtInst %6 %1 Log2 %24
%26 = OpLoad %6 %13
%27 = OpFAdd %6 %26 %25
OpStore %13 %27
%28 = OpLoad %6 %13
%29 = OpLoad %6 %13
%30 = OpExtInst %6 %1 Sqrt %29
%31 = OpFSub %6 %28 %30
OpReturnValue %31
OpFunctionEnd
%10 = OpFunction %6 None %7
%11 = OpLabel
%34 = OpVariable %12 Function
%36 = OpAccessChain %21 %18 %35
%37 = OpLoad %15 %36
%38 = OpConvertUToF %6 %37
%40 = OpFDiv %6 %38 %39
OpStore %34 %40
%41 = OpLoad %6 %34
%44 = OpExtInst %6 %1 FClamp %41 %42 %43
%45 = OpLoad %6 %34
%46 = OpFMul %6 %45 %44
OpStore %34 %46
%47 = OpAccessChain %21 %18 %20
%48 = OpLoad %15 %47
%51 = OpINotEqual %50 %48 %49
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpLoad %6 %34
%56 = OpFSub %6 %55 %54
OpStore %34 %56
OpBranch %53
%53 = OpLabel
%57 = OpLoad %6 %34
%58 = OpExtInst %6 %1 Exp %57
OpReturnValue %58
OpFunctionEnd
)";
TEST(DiffTest, ExtraIfBlock) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 69
+; Bound: 81
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %68
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "f1("
OpName %10 "f2("
OpName %13 "v"
OpName %16 "Buffer"
OpMemberName %16 0 "flag1"
OpMemberName %16 1 "flag2"
OpName %18 ""
OpName %45 "v"
OpName %63 "color"
OpName %68 "v"
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
-OpDecorate %23 RelaxedPrecision
-OpDecorate %30 RelaxedPrecision
-OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
+OpDecorate %77 RelaxedPrecision
+OpDecorate %78 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %66 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %68 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 0
%21 = OpTypePointer Uniform %15
%24 = OpConstant %15 0
%25 = OpTypeBool
%29 = OpConstant %6 1
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
+%76 = OpConstant %6 0.100000001
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%67 = OpTypePointer Input %6
%68 = OpVariable %67 Input
%10 = OpFunction %6 None %7
%11 = OpLabel
%45 = OpVariable %12 Function
%46 = OpAccessChain %21 %18 %20
%47 = OpLoad %15 %46
%48 = OpConvertUToF %6 %47
%50 = OpFDiv %6 %48 %49
OpStore %45 %50
%51 = OpLoad %6 %45
%54 = OpExtInst %6 %1 FClamp %51 %52 %53
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
+%71 = OpAccessChain %21 %18 %32
+%72 = OpLoad %15 %71
+%73 = OpINotEqual %25 %72 %24
+OpSelectionMerge %75 None
+OpBranchConditional %73 %74 %75
+%74 = OpLabel
%57 = OpLoad %6 %45
+%77 = OpFSub %6 %57 %76
+OpStore %45 %77
+OpBranch %75
+%75 = OpLabel
+%78 = OpLoad %6 %45
-%58 = OpExtInst %6 %1 Exp %57
+%58 = OpExtInst %6 %1 Exp %78
OpReturnValue %58
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
-%22 = OpAccessChain %21 %18 %20
-%23 = OpLoad %15 %22
-%26 = OpINotEqual %25 %23 %24
-OpSelectionMerge %28 None
-OpBranchConditional %26 %27 %28
-%27 = OpLabel
-%30 = OpLoad %6 %13
-%31 = OpFAdd %6 %30 %29
-OpStore %13 %31
-OpBranch %28
-%28 = OpLabel
%33 = OpAccessChain %21 %18 %32
%34 = OpLoad %15 %33
%35 = OpConvertUToF %6 %34
%36 = OpExtInst %6 %1 Log2 %35
%37 = OpLoad %6 %13
%38 = OpFAdd %6 %37 %36
OpStore %13 %38
%39 = OpLoad %6 %13
%40 = OpLoad %6 %13
%41 = OpExtInst %6 %1 Sqrt %40
%42 = OpFSub %6 %39 %41
OpReturnValue %42
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%66 = OpCompositeConstruct %61 %64 %65 %14 %29
OpStore %63 %66
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, ExtraIfBlockNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %68
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
OpDecorate %23 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %66 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %68 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 0
%21 = OpTypePointer Uniform %15
%24 = OpConstant %15 0
%25 = OpTypeBool
%29 = OpConstant %6 1
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%67 = OpTypePointer Input %6
%68 = OpVariable %67 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%66 = OpCompositeConstruct %61 %64 %65 %14 %29
OpStore %63 %66
OpReturn
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
%22 = OpAccessChain %21 %18 %20
%23 = OpLoad %15 %22
%26 = OpINotEqual %25 %23 %24
OpSelectionMerge %28 None
OpBranchConditional %26 %27 %28
%27 = OpLabel
%30 = OpLoad %6 %13
%31 = OpFAdd %6 %30 %29
OpStore %13 %31
OpBranch %28
%28 = OpLabel
%33 = OpAccessChain %21 %18 %32
%34 = OpLoad %15 %33
%35 = OpConvertUToF %6 %34
%36 = OpExtInst %6 %1 Log2 %35
%37 = OpLoad %6 %13
%38 = OpFAdd %6 %37 %36
OpStore %13 %38
%39 = OpLoad %6 %13
%40 = OpLoad %6 %13
%41 = OpExtInst %6 %1 Sqrt %40
%42 = OpFSub %6 %39 %41
OpReturnValue %42
OpFunctionEnd
%10 = OpFunction %6 None %7
%11 = OpLabel
%45 = OpVariable %12 Function
%46 = OpAccessChain %21 %18 %20
%47 = OpLoad %15 %46
%48 = OpConvertUToF %6 %47
%50 = OpFDiv %6 %48 %49
OpStore %45 %50
%51 = OpLoad %6 %45
%54 = OpExtInst %6 %1 FClamp %51 %52 %53
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
%57 = OpLoad %6 %45
%58 = OpExtInst %6 %1 Exp %57
OpReturnValue %58
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %69
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %67 RelaxedPrecision
OpDecorate %69 RelaxedPrecision
OpDecorate %69 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 1
%21 = OpTypePointer Uniform %15
%35 = OpConstant %19 0
%39 = OpConstant %6 10
%42 = OpConstant %6 0.5
%43 = OpConstant %6 0.699999988
%49 = OpConstant %15 0
%50 = OpTypeBool
%54 = OpConstant %6 0.100000001
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%66 = OpConstant %6 1
%68 = OpTypePointer Input %6
%69 = OpVariable %68 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%67 = OpCompositeConstruct %61 %64 %65 %14 %66
OpStore %63 %67
OpReturn
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
%22 = OpAccessChain %21 %18 %20
%23 = OpLoad %15 %22
%24 = OpConvertUToF %6 %23
%25 = OpExtInst %6 %1 Log2 %24
%26 = OpLoad %6 %13
%27 = OpFAdd %6 %26 %25
OpStore %13 %27
%28 = OpLoad %6 %13
%29 = OpLoad %6 %13
%30 = OpExtInst %6 %1 Sqrt %29
%31 = OpFSub %6 %28 %30
OpReturnValue %31
OpFunctionEnd
%10 = OpFunction %6 None %7
%11 = OpLabel
%34 = OpVariable %12 Function
%36 = OpAccessChain %21 %18 %35
%37 = OpLoad %15 %36
%38 = OpConvertUToF %6 %37
%40 = OpFDiv %6 %38 %39
OpStore %34 %40
%41 = OpLoad %6 %34
%44 = OpExtInst %6 %1 FClamp %41 %42 %43
%45 = OpLoad %6 %34
%46 = OpFMul %6 %45 %44
OpStore %34 %46
%47 = OpAccessChain %21 %18 %20
%48 = OpLoad %15 %47
%51 = OpINotEqual %50 %48 %49
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpLoad %6 %34
%56 = OpFSub %6 %55 %54
OpStore %34 %56
OpBranch %53
%53 = OpLabel
%57 = OpLoad %6 %34
%58 = OpExtInst %6 %1 Exp %57
OpReturnValue %58
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 69
+; Bound: 81
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %68
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
-OpDecorate %23 RelaxedPrecision
-OpDecorate %30 RelaxedPrecision
-OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
+OpDecorate %77 RelaxedPrecision
+OpDecorate %78 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %66 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %68 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 0
%21 = OpTypePointer Uniform %15
%24 = OpConstant %15 0
%25 = OpTypeBool
%29 = OpConstant %6 1
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
+%76 = OpConstant %6 0.100000001
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%67 = OpTypePointer Input %6
%68 = OpVariable %67 Input
%10 = OpFunction %6 None %7
%11 = OpLabel
%45 = OpVariable %12 Function
%46 = OpAccessChain %21 %18 %20
%47 = OpLoad %15 %46
%48 = OpConvertUToF %6 %47
%50 = OpFDiv %6 %48 %49
OpStore %45 %50
%51 = OpLoad %6 %45
%54 = OpExtInst %6 %1 FClamp %51 %52 %53
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
+%71 = OpAccessChain %21 %18 %32
+%72 = OpLoad %15 %71
+%73 = OpINotEqual %25 %72 %24
+OpSelectionMerge %75 None
+OpBranchConditional %73 %74 %75
+%74 = OpLabel
%57 = OpLoad %6 %45
+%77 = OpFSub %6 %57 %76
+OpStore %45 %77
+OpBranch %75
+%75 = OpLabel
+%78 = OpLoad %6 %45
-%58 = OpExtInst %6 %1 Exp %57
+%58 = OpExtInst %6 %1 Exp %78
OpReturnValue %58
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
-%22 = OpAccessChain %21 %18 %20
-%23 = OpLoad %15 %22
-%26 = OpINotEqual %25 %23 %24
-OpSelectionMerge %28 None
-OpBranchConditional %26 %27 %28
-%27 = OpLabel
-%30 = OpLoad %6 %13
-%31 = OpFAdd %6 %30 %29
-OpStore %13 %31
-OpBranch %28
-%28 = OpLabel
%33 = OpAccessChain %21 %18 %32
%34 = OpLoad %15 %33
%35 = OpConvertUToF %6 %34
%36 = OpExtInst %6 %1 Log2 %35
%37 = OpLoad %6 %13
%38 = OpFAdd %6 %37 %36
OpStore %13 %38
%39 = OpLoad %6 %13
%40 = OpLoad %6 %13
%41 = OpExtInst %6 %1 Sqrt %40
%42 = OpFSub %6 %39 %41
OpReturnValue %42
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%66 = OpCompositeConstruct %61 %64 %65 %14 %29
OpStore %63 %66
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,136 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %69
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "f1("
OpName %10 "f2("
OpName %13 "v"
OpName %16 "Buffer"
OpMemberName %16 0 "flag1"
OpMemberName %16 1 "flag2"
OpName %18 ""
OpName %34 "v"
OpName %63 "color"
OpName %69 "v"
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %67 RelaxedPrecision
OpDecorate %69 RelaxedPrecision
OpDecorate %69 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 1
%21 = OpTypePointer Uniform %15
%35 = OpConstant %19 0
%39 = OpConstant %6 10
%42 = OpConstant %6 0.5
%43 = OpConstant %6 0.699999988
%49 = OpConstant %15 0
%50 = OpTypeBool
%54 = OpConstant %6 0.100000001
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%66 = OpConstant %6 1
%68 = OpTypePointer Input %6
%69 = OpVariable %68 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%67 = OpCompositeConstruct %61 %64 %65 %14 %66
OpStore %63 %67
OpReturn
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
%22 = OpAccessChain %21 %18 %20
%23 = OpLoad %15 %22
%24 = OpConvertUToF %6 %23
%25 = OpExtInst %6 %1 Log2 %24
%26 = OpLoad %6 %13
%27 = OpFAdd %6 %26 %25
OpStore %13 %27
%28 = OpLoad %6 %13
%29 = OpLoad %6 %13
%30 = OpExtInst %6 %1 Sqrt %29
%31 = OpFSub %6 %28 %30
OpReturnValue %31
OpFunctionEnd
%10 = OpFunction %6 None %7
%11 = OpLabel
%34 = OpVariable %12 Function
%36 = OpAccessChain %21 %18 %35
%37 = OpLoad %15 %36
%38 = OpConvertUToF %6 %37
%40 = OpFDiv %6 %38 %39
OpStore %34 %40
%41 = OpLoad %6 %34
%44 = OpExtInst %6 %1 FClamp %41 %42 %43
%45 = OpLoad %6 %34
%46 = OpFMul %6 %45 %44
OpStore %34 %46
%47 = OpAccessChain %21 %18 %20
%48 = OpLoad %15 %47
%51 = OpINotEqual %50 %48 %49
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpLoad %6 %34
%56 = OpFSub %6 %55 %54
OpStore %34 %56
OpBranch %53
%53 = OpLabel
%57 = OpLoad %6 %34
%58 = OpExtInst %6 %1 Exp %57
OpReturnValue %58
OpFunctionEnd

View File

@ -0,0 +1,137 @@
;; Test where src has an extra if block in one function, and dst has an extra
;; if block in another function.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %63 %68
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "f1("
OpName %10 "f2("
OpName %13 "v"
OpName %16 "Buffer"
OpMemberName %16 0 "flag1"
OpMemberName %16 1 "flag2"
OpName %18 ""
OpName %45 "v"
OpName %63 "color"
OpName %68 "v"
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
OpMemberDecorate %16 0 RelaxedPrecision
OpMemberDecorate %16 0 Offset 0
OpMemberDecorate %16 1 RelaxedPrecision
OpMemberDecorate %16 1 Offset 4
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 0
OpDecorate %23 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %45 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
OpDecorate %64 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %66 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %68 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeFunction %6
%12 = OpTypePointer Function %6
%14 = OpConstant %6 0
%15 = OpTypeInt 32 0
%16 = OpTypeStruct %15 %15
%17 = OpTypePointer Uniform %16
%18 = OpVariable %17 Uniform
%19 = OpTypeInt 32 1
%20 = OpConstant %19 0
%21 = OpTypePointer Uniform %15
%24 = OpConstant %15 0
%25 = OpTypeBool
%29 = OpConstant %6 1
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
%63 = OpVariable %62 Output
%67 = OpTypePointer Input %6
%68 = OpVariable %67 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%64 = OpFunctionCall %6 %8
%65 = OpFunctionCall %6 %10
%66 = OpCompositeConstruct %61 %64 %65 %14 %29
OpStore %63 %66
OpReturn
OpFunctionEnd
%8 = OpFunction %6 None %7
%9 = OpLabel
%13 = OpVariable %12 Function
OpStore %13 %14
%22 = OpAccessChain %21 %18 %20
%23 = OpLoad %15 %22
%26 = OpINotEqual %25 %23 %24
OpSelectionMerge %28 None
OpBranchConditional %26 %27 %28
%27 = OpLabel
%30 = OpLoad %6 %13
%31 = OpFAdd %6 %30 %29
OpStore %13 %31
OpBranch %28
%28 = OpLabel
%33 = OpAccessChain %21 %18 %32
%34 = OpLoad %15 %33
%35 = OpConvertUToF %6 %34
%36 = OpExtInst %6 %1 Log2 %35
%37 = OpLoad %6 %13
%38 = OpFAdd %6 %37 %36
OpStore %13 %38
%39 = OpLoad %6 %13
%40 = OpLoad %6 %13
%41 = OpExtInst %6 %1 Sqrt %40
%42 = OpFSub %6 %39 %41
OpReturnValue %42
OpFunctionEnd
%10 = OpFunction %6 None %7
%11 = OpLabel
%45 = OpVariable %12 Function
%46 = OpAccessChain %21 %18 %20
%47 = OpLoad %15 %46
%48 = OpConvertUToF %6 %47
%50 = OpFDiv %6 %48 %49
OpStore %45 %50
%51 = OpLoad %6 %45
%54 = OpExtInst %6 %1 FClamp %51 %52 %53
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
%57 = OpLoad %6 %45
%58 = OpExtInst %6 %1 Exp %57
OpReturnValue %58
OpFunctionEnd

View File

@ -0,0 +1,304 @@
#! /usr/bin/python3
#
# Copyright (c) 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import glob
import os
import subprocess
import sys
# A handful of relevant tests are hand-picked to generate extra unit tests with
# specific options of spirv-diff.
IGNORE_SET_BINDING_TESTS = ['different_decorations_vertex']
IGNORE_LOCATION_TESTS = ['different_decorations_fragment']
IGNORE_DECORATIONS_TESTS = ['different_decorations_vertex', 'different_decorations_fragment']
DUMP_IDS_TESTS = ['basic', 'int_vs_uint_constants', 'multiple_same_entry_points', 'small_functions_small_diffs']
LICENSE = u"""Copyright (c) 2022 Google LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
TEMPLATE_TEST_FILE = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name}
//
{license}
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {{
namespace diff {{
namespace {{
{test_comment}
constexpr char kSrc[] = R"({src_spirv})";
constexpr char kDst[] = R"({dst_spirv})";
TEST(DiffTest, {test_name}) {{
constexpr char kDiff[] = R"({diff_spirv})";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}}
TEST(DiffTest, {test_name}NoDebug) {{
constexpr char kSrcNoDebug[] = R"({src_spirv_no_debug})";
constexpr char kDstNoDebug[] = R"({dst_spirv_no_debug})";
constexpr char kDiff[] = R"({diff_spirv_no_debug})";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}}
{extra_tests}
}} // namespace
}} // namespace diff
}} // namespace spvtools
"""
TEMPLATE_TEST_FUNC = u"""
TEST(DiffTest, {test_name}{test_tag}) {{
constexpr char kDiff[] = R"({diff_spirv})";
Options options;
{test_options}
DoStringDiffTest(kSrc, kDst, kDiff, options);
}}
"""
TEMPLATE_TEST_FILES_CMAKE = u"""# GENERATED FILE - DO NOT EDIT.
# Generated by {script_name}
#
{license}
list(APPEND DIFF_TEST_FILES
{test_files}
)
"""
VARIANT_NONE = 0
VARIANT_IGNORE_SET_BINDING = 1
VARIANT_IGNORE_LOCATION = 2
VARIANT_IGNORE_DECORATIONS = 3
VARIANT_DUMP_IDS = 4
def print_usage():
print("Usage: {} <path-to-spirv-diff>".format(sys.argv[0]))
def remove_debug_info(in_path):
tmp_dir = '.no_dbg'
if not os.path.exists(tmp_dir):
os.makedirs(tmp_dir)
(in_basename, in_ext) = os.path.splitext(in_path)
out_name = in_basename + '_no_dbg' + in_ext
out_path = os.path.join(tmp_dir, out_name)
with open(in_path, 'r') as fin:
with open(out_path, 'w') as fout:
for line in fin:
ops = line.strip().split()
op = ops[0] if len(ops) > 0 else ''
if (op != ';;' and op != 'OpName' and op != 'OpMemberName' and op != 'OpString' and
op != 'OpLine' and op != 'OpNoLine' and op != 'OpModuleProcessed'):
fout.write(line)
return out_path
def make_src_file(test_name):
return '{}_src.spvasm'.format(test_name)
def make_dst_file(test_name):
return '{}_dst.spvasm'.format(test_name)
def make_cpp_file(test_name):
return '{}_autogen.cpp'.format(test_name)
def make_camel_case(test_name):
return test_name.replace('_', ' ').title().replace(' ', '')
def make_comment(text, comment_prefix):
return '\n'.join([comment_prefix + (' ' if line.strip() else '') + line for line in text.splitlines()])
def read_file(file_name):
with open(file_name, 'r') as f:
content = f.read()
# Use unix line endings.
content = content.replace('\r\n', '\n')
return content
def parse_test_comment(src_spirv_file_name, src_spirv):
src_spirv_lines = src_spirv.splitlines()
comment_line_count = 0
while comment_line_count < len(src_spirv_lines):
if not src_spirv_lines[comment_line_count].strip().startswith(';;'):
break
comment_line_count += 1
if comment_line_count == 0:
print("Expected comment on test file '{}'. See README.md next to this file.".format(src_spirv_file_name))
sys.exit(1)
comment_block = src_spirv_lines[:comment_line_count]
spirv_block = src_spirv_lines[comment_line_count:]
comment_block = ['// ' + line.replace(';;', '').strip() for line in comment_block]
return '\n'.join(spirv_block), '\n'.join(comment_block)
def run_diff_tool(diff_tool, src_file, dst_file, variant):
args = [diff_tool]
if variant == VARIANT_IGNORE_SET_BINDING or variant == VARIANT_IGNORE_DECORATIONS:
args.append('--ignore-set-binding')
if variant == VARIANT_IGNORE_LOCATION or variant == VARIANT_IGNORE_DECORATIONS:
args.append('--ignore-location')
if variant == VARIANT_DUMP_IDS:
args.append('--with-id-map')
args.append('--no-color')
args.append('--no-indent')
args.append(src_file)
args.append(dst_file)
success = True
print(' '.join(args))
process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
out, err = process.communicate()
if process.returncode != 0:
print(err)
sys.exit(process.returncode)
# Use unix line endings.
out = out.replace('\r\n', '\n')
return out
def generate_extra_test(diff_tool, src_file, dst_file, variant, test_name_camel_case, test_tag, test_options):
diff = run_diff_tool(diff_tool, src_file, dst_file, variant)
return TEMPLATE_TEST_FUNC.format(
test_name = test_name_camel_case,
test_tag = test_tag,
test_options = test_options,
diff_spirv = diff)
def generate_test(diff_tool, test_name):
src_file = make_src_file(test_name)
dst_file = make_dst_file(test_name)
src_file_no_debug = remove_debug_info(src_file)
dst_file_no_debug = remove_debug_info(dst_file)
src_spirv = read_file(src_file)
dst_spirv = read_file(dst_file)
src_spirv_no_debug = read_file(src_file_no_debug)
dst_spirv_no_debug = read_file(dst_file_no_debug)
test_name_camel_case = make_camel_case(test_name)
diff_spirv = run_diff_tool(diff_tool, src_file, dst_file, VARIANT_NONE)
diff_spirv_no_debug = run_diff_tool(diff_tool, src_file_no_debug, dst_file_no_debug, VARIANT_NONE)
extra_tests = []
if test_name in IGNORE_SET_BINDING_TESTS:
extra_tests.append(generate_extra_test(diff_tool, src_file, dst_file, VARIANT_IGNORE_SET_BINDING,
test_name_camel_case, 'IgnoreSetBinding', 'options.ignore_set_binding = true;'))
if test_name in IGNORE_LOCATION_TESTS:
extra_tests.append(generate_extra_test(diff_tool, src_file, dst_file, VARIANT_IGNORE_LOCATION,
test_name_camel_case, 'IgnoreLocation', 'options.ignore_location = true;'))
if test_name in IGNORE_DECORATIONS_TESTS:
extra_tests.append(generate_extra_test(diff_tool, src_file, dst_file, VARIANT_IGNORE_DECORATIONS,
test_name_camel_case, 'IgnoreSetBindingLocation',
'\n '.join(['options.ignore_set_binding = true;', 'options.ignore_location = true;'])))
if test_name in DUMP_IDS_TESTS:
extra_tests.append(generate_extra_test(diff_tool, src_file, dst_file, VARIANT_DUMP_IDS,
test_name_camel_case, 'DumpIds', 'options.dump_id_map = true;'))
src_spirv, test_comment = parse_test_comment(src_file, src_spirv)
test_file = TEMPLATE_TEST_FILE.format(
script_name = os.path.basename(__file__),
license = make_comment(LICENSE, '//'),
test_comment = test_comment,
test_name = test_name_camel_case,
src_spirv = src_spirv,
dst_spirv = dst_spirv,
diff_spirv = diff_spirv,
src_spirv_no_debug = src_spirv_no_debug,
dst_spirv_no_debug = dst_spirv_no_debug,
diff_spirv_no_debug = diff_spirv_no_debug,
extra_tests = ''.join(extra_tests))
test_file_name = make_cpp_file(test_name)
with open(test_file_name, 'wb') as fout:
fout.write(str.encode(test_file))
return test_file_name
def generate_tests(diff_tool, test_names):
return [generate_test(diff_tool, test_name) for test_name in test_names]
def generate_cmake(test_files):
cmake = TEMPLATE_TEST_FILES_CMAKE.format(
script_name = os.path.basename(__file__),
license = make_comment(LICENSE, '#'),
test_files = '\n'.join(['"diff_files/{}"'.format(f) for f in test_files]))
with open('diff_test_files_autogen.cmake', 'wb') as fout:
fout.write(str.encode(cmake))
def main():
if len(sys.argv) != 2:
print_usage()
return 1
diff_tool = sys.argv[1]
if not os.path.exists(diff_tool):
print("No such file: {}".format(diff_tool))
print_usage()
return 1
diff_tool = os.path.realpath(diff_tool)
os.chdir(os.path.dirname(__file__))
test_names = sorted([f[:-11] for f in glob.glob("*_src.spvasm")])
test_files = generate_tests(diff_tool, test_names)
generate_cmake(test_files)
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,733 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Test where signedness of indices are different between src and dst.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %13 "BufferOut"
OpMemberName %13 0 "o1"
OpMemberName %13 1 "o2"
OpMemberName %13 2 "o3"
OpName %15 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i1"
OpMemberName %22 1 "i2"
OpName %24 ""
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpConstant %6 3
%8 = OpTypeArray %6 %7
%9 = OpTypeArray %6 %7
%10 = OpConstant %6 2
%11 = OpTypeArray %6 %10
%12 = OpTypeArray %11 %10
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%16 = OpTypeInt 32 1
%17 = OpConstant %16 0
%18 = OpTypeArray %6 %7
%19 = OpTypeArray %18 %10
%20 = OpConstant %6 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%28 = OpConstant %6 1
%31 = OpConstant %16 1
%34 = OpConstant %6 0
%37 = OpConstant %16 2
%61 = OpConstant %16 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
%32 = OpAccessChain %25 %24 %17 %31 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
%36 = OpAccessChain %25 %15 %17 %31
OpStore %36 %35
%38 = OpAccessChain %25 %24 %17 %31 %31
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %10
%41 = OpAccessChain %25 %15 %17 %37
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %37
%43 = OpLoad %6 %42
%44 = OpAccessChain %25 %15 %31 %17
OpStore %44 %43
%45 = OpAccessChain %25 %24 %17 %17 %31
%46 = OpLoad %6 %45
%47 = OpIMul %6 %46 %7
%48 = OpAccessChain %25 %15 %31 %31
OpStore %48 %47
%49 = OpAccessChain %25 %24 %17 %31 %37
%50 = OpLoad %6 %49
%51 = OpAccessChain %25 %15 %31 %37
OpStore %51 %50
%52 = OpAccessChain %25 %24 %31 %17
%53 = OpLoad %6 %52
%54 = OpAccessChain %25 %15 %37 %17 %17
OpStore %54 %53
%55 = OpAccessChain %25 %24 %31 %31
%56 = OpLoad %6 %55
%57 = OpAccessChain %25 %15 %37 %17 %31
OpStore %57 %56
%58 = OpAccessChain %25 %24 %31 %37
%59 = OpLoad %6 %58
%60 = OpAccessChain %25 %15 %37 %31 %17
OpStore %60 %59
%62 = OpAccessChain %25 %24 %31 %61
%63 = OpLoad %6 %62
%64 = OpAccessChain %25 %15 %37 %31 %31
OpStore %64 %63
OpReturn
OpFunctionEnd
)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %13 "BufferOut"
OpMemberName %13 0 "o1"
OpMemberName %13 1 "o2"
OpMemberName %13 2 "o3"
OpName %15 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i1"
OpMemberName %22 1 "i2"
OpName %24 ""
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%16 = OpTypeInt 32 1
%7 = OpConstant %16 3
%8 = OpTypeArray %6 %7
%9 = OpTypeArray %6 %7
%10 = OpConstant %16 2
%11 = OpTypeArray %6 %10
%12 = OpTypeArray %11 %10
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%18 = OpTypeArray %6 %7
%19 = OpTypeArray %18 %10
%20 = OpConstant %16 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%17 = OpConstant %16 0
%28 = OpConstant %16 1
%31 = OpConstant %6 1
%34 = OpConstant %6 0
%37 = OpConstant %6 2
%61 = OpConstant %6 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
%32 = OpAccessChain %25 %24 %17 %31 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
%36 = OpAccessChain %25 %15 %17 %31
OpStore %36 %35
%38 = OpAccessChain %25 %24 %17 %31 %31
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %37
%41 = OpAccessChain %25 %15 %17 %10
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %10
%43 = OpLoad %6 %42
%44 = OpAccessChain %25 %15 %31 %17
OpStore %44 %43
%45 = OpAccessChain %25 %24 %17 %17 %31
%46 = OpLoad %6 %45
%47 = OpIMul %6 %46 %7
%48 = OpAccessChain %25 %15 %31 %31
OpStore %48 %47
%49 = OpAccessChain %25 %24 %17 %31 %10
%50 = OpLoad %6 %49
%51 = OpAccessChain %25 %15 %31 %10
OpStore %51 %50
%52 = OpAccessChain %25 %24 %31 %17
%53 = OpLoad %6 %52
%54 = OpAccessChain %25 %15 %37 %17 %17
OpStore %54 %53
%55 = OpAccessChain %25 %24 %31 %31
%56 = OpLoad %6 %55
%57 = OpAccessChain %25 %15 %37 %17 %31
OpStore %57 %56
%58 = OpAccessChain %25 %24 %31 %37
%59 = OpLoad %6 %58
%60 = OpAccessChain %25 %15 %37 %31 %17
OpStore %60 %59
%62 = OpAccessChain %25 %24 %31 %61
%63 = OpLoad %6 %62
%64 = OpAccessChain %25 %15 %37 %31 %31
OpStore %64 %63
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, IndexSignedness) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 65
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %13 "BufferOut"
OpMemberName %13 0 "o1"
OpMemberName %13 1 "o2"
OpMemberName %13 2 "o3"
OpName %15 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i1"
OpMemberName %22 1 "i2"
OpName %24 ""
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpConstant %6 3
-%8 = OpTypeArray %6 %7
+%8 = OpTypeArray %6 %61
-%9 = OpTypeArray %6 %7
+%9 = OpTypeArray %6 %61
%10 = OpConstant %6 2
-%11 = OpTypeArray %6 %10
+%11 = OpTypeArray %6 %37
-%12 = OpTypeArray %11 %10
+%12 = OpTypeArray %11 %37
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%16 = OpTypeInt 32 1
%17 = OpConstant %16 0
-%18 = OpTypeArray %6 %7
+%18 = OpTypeArray %6 %61
-%19 = OpTypeArray %18 %10
+%19 = OpTypeArray %18 %37
-%20 = OpConstant %6 4
+%20 = OpConstant %16 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%28 = OpConstant %6 1
%31 = OpConstant %16 1
%34 = OpConstant %6 0
%37 = OpConstant %16 2
%61 = OpConstant %16 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
-%29 = OpIAdd %6 %27 %28
+%29 = OpIAdd %6 %27 %31
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
-%32 = OpAccessChain %25 %24 %17 %31 %17
+%32 = OpAccessChain %25 %24 %17 %28 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
-%36 = OpAccessChain %25 %15 %17 %31
+%36 = OpAccessChain %25 %15 %17 %28
OpStore %36 %35
-%38 = OpAccessChain %25 %24 %17 %31 %31
+%38 = OpAccessChain %25 %24 %17 %28 %28
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %10
%41 = OpAccessChain %25 %15 %17 %37
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %37
%43 = OpLoad %6 %42
-%44 = OpAccessChain %25 %15 %31 %17
+%44 = OpAccessChain %25 %15 %28 %17
OpStore %44 %43
-%45 = OpAccessChain %25 %24 %17 %17 %31
+%45 = OpAccessChain %25 %24 %17 %17 %28
%46 = OpLoad %6 %45
-%47 = OpIMul %6 %46 %7
+%47 = OpIMul %6 %46 %61
-%48 = OpAccessChain %25 %15 %31 %31
+%48 = OpAccessChain %25 %15 %28 %28
OpStore %48 %47
-%49 = OpAccessChain %25 %24 %17 %31 %37
+%49 = OpAccessChain %25 %24 %17 %28 %37
%50 = OpLoad %6 %49
-%51 = OpAccessChain %25 %15 %31 %37
+%51 = OpAccessChain %25 %15 %28 %37
OpStore %51 %50
-%52 = OpAccessChain %25 %24 %31 %17
+%52 = OpAccessChain %25 %24 %28 %17
%53 = OpLoad %6 %52
-%54 = OpAccessChain %25 %15 %37 %17 %17
+%54 = OpAccessChain %25 %15 %10 %17 %17
OpStore %54 %53
-%55 = OpAccessChain %25 %24 %31 %31
+%55 = OpAccessChain %25 %24 %28 %28
%56 = OpLoad %6 %55
-%57 = OpAccessChain %25 %15 %37 %17 %31
+%57 = OpAccessChain %25 %15 %10 %17 %28
OpStore %57 %56
-%58 = OpAccessChain %25 %24 %31 %37
+%58 = OpAccessChain %25 %24 %28 %10
%59 = OpLoad %6 %58
-%60 = OpAccessChain %25 %15 %37 %31 %17
+%60 = OpAccessChain %25 %15 %10 %28 %17
OpStore %60 %59
-%62 = OpAccessChain %25 %24 %31 %61
+%62 = OpAccessChain %25 %24 %28 %7
%63 = OpLoad %6 %62
-%64 = OpAccessChain %25 %15 %37 %31 %31
+%64 = OpAccessChain %25 %15 %10 %28 %28
OpStore %64 %63
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, IndexSignednessNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpConstant %6 3
%8 = OpTypeArray %6 %7
%9 = OpTypeArray %6 %7
%10 = OpConstant %6 2
%11 = OpTypeArray %6 %10
%12 = OpTypeArray %11 %10
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%16 = OpTypeInt 32 1
%17 = OpConstant %16 0
%18 = OpTypeArray %6 %7
%19 = OpTypeArray %18 %10
%20 = OpConstant %6 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%28 = OpConstant %6 1
%31 = OpConstant %16 1
%34 = OpConstant %6 0
%37 = OpConstant %16 2
%61 = OpConstant %16 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
%32 = OpAccessChain %25 %24 %17 %31 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
%36 = OpAccessChain %25 %15 %17 %31
OpStore %36 %35
%38 = OpAccessChain %25 %24 %17 %31 %31
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %10
%41 = OpAccessChain %25 %15 %17 %37
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %37
%43 = OpLoad %6 %42
%44 = OpAccessChain %25 %15 %31 %17
OpStore %44 %43
%45 = OpAccessChain %25 %24 %17 %17 %31
%46 = OpLoad %6 %45
%47 = OpIMul %6 %46 %7
%48 = OpAccessChain %25 %15 %31 %31
OpStore %48 %47
%49 = OpAccessChain %25 %24 %17 %31 %37
%50 = OpLoad %6 %49
%51 = OpAccessChain %25 %15 %31 %37
OpStore %51 %50
%52 = OpAccessChain %25 %24 %31 %17
%53 = OpLoad %6 %52
%54 = OpAccessChain %25 %15 %37 %17 %17
OpStore %54 %53
%55 = OpAccessChain %25 %24 %31 %31
%56 = OpLoad %6 %55
%57 = OpAccessChain %25 %15 %37 %17 %31
OpStore %57 %56
%58 = OpAccessChain %25 %24 %31 %37
%59 = OpLoad %6 %58
%60 = OpAccessChain %25 %15 %37 %31 %17
OpStore %60 %59
%62 = OpAccessChain %25 %24 %31 %61
%63 = OpLoad %6 %62
%64 = OpAccessChain %25 %15 %37 %31 %31
OpStore %64 %63
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%16 = OpTypeInt 32 1
%7 = OpConstant %16 3
%8 = OpTypeArray %6 %7
%9 = OpTypeArray %6 %7
%10 = OpConstant %16 2
%11 = OpTypeArray %6 %10
%12 = OpTypeArray %11 %10
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%18 = OpTypeArray %6 %7
%19 = OpTypeArray %18 %10
%20 = OpConstant %16 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%17 = OpConstant %16 0
%28 = OpConstant %16 1
%31 = OpConstant %6 1
%34 = OpConstant %6 0
%37 = OpConstant %6 2
%61 = OpConstant %6 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
%32 = OpAccessChain %25 %24 %17 %31 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
%36 = OpAccessChain %25 %15 %17 %31
OpStore %36 %35
%38 = OpAccessChain %25 %24 %17 %31 %31
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %37
%41 = OpAccessChain %25 %15 %17 %10
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %10
%43 = OpLoad %6 %42
%44 = OpAccessChain %25 %15 %31 %17
OpStore %44 %43
%45 = OpAccessChain %25 %24 %17 %17 %31
%46 = OpLoad %6 %45
%47 = OpIMul %6 %46 %7
%48 = OpAccessChain %25 %15 %31 %31
OpStore %48 %47
%49 = OpAccessChain %25 %24 %17 %31 %10
%50 = OpLoad %6 %49
%51 = OpAccessChain %25 %15 %31 %10
OpStore %51 %50
%52 = OpAccessChain %25 %24 %31 %17
%53 = OpLoad %6 %52
%54 = OpAccessChain %25 %15 %37 %17 %17
OpStore %54 %53
%55 = OpAccessChain %25 %24 %31 %31
%56 = OpLoad %6 %55
%57 = OpAccessChain %25 %15 %37 %17 %31
OpStore %57 %56
%58 = OpAccessChain %25 %24 %31 %37
%59 = OpLoad %6 %58
%60 = OpAccessChain %25 %15 %37 %31 %17
OpStore %60 %59
%62 = OpAccessChain %25 %24 %31 %61
%63 = OpLoad %6 %62
%64 = OpAccessChain %25 %15 %37 %31 %31
OpStore %64 %63
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 65
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpConstant %6 3
-%8 = OpTypeArray %6 %7
+%8 = OpTypeArray %6 %61
-%9 = OpTypeArray %6 %7
+%9 = OpTypeArray %6 %61
%10 = OpConstant %6 2
-%11 = OpTypeArray %6 %10
+%11 = OpTypeArray %6 %37
-%12 = OpTypeArray %11 %10
+%12 = OpTypeArray %11 %37
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%16 = OpTypeInt 32 1
%17 = OpConstant %16 0
-%18 = OpTypeArray %6 %7
+%18 = OpTypeArray %6 %61
-%19 = OpTypeArray %18 %10
+%19 = OpTypeArray %18 %37
-%20 = OpConstant %6 4
+%20 = OpConstant %16 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%28 = OpConstant %6 1
%31 = OpConstant %16 1
%34 = OpConstant %6 0
%37 = OpConstant %16 2
%61 = OpConstant %16 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
-%29 = OpIAdd %6 %27 %28
+%29 = OpIAdd %6 %27 %31
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
-%32 = OpAccessChain %25 %24 %17 %31 %17
+%32 = OpAccessChain %25 %24 %17 %28 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
-%36 = OpAccessChain %25 %15 %17 %31
+%36 = OpAccessChain %25 %15 %17 %28
OpStore %36 %35
-%38 = OpAccessChain %25 %24 %17 %31 %31
+%38 = OpAccessChain %25 %24 %17 %28 %28
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %10
%41 = OpAccessChain %25 %15 %17 %37
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %37
%43 = OpLoad %6 %42
-%44 = OpAccessChain %25 %15 %31 %17
+%44 = OpAccessChain %25 %15 %28 %17
OpStore %44 %43
-%45 = OpAccessChain %25 %24 %17 %17 %31
+%45 = OpAccessChain %25 %24 %17 %17 %28
%46 = OpLoad %6 %45
-%47 = OpIMul %6 %46 %7
+%47 = OpIMul %6 %46 %61
-%48 = OpAccessChain %25 %15 %31 %31
+%48 = OpAccessChain %25 %15 %28 %28
OpStore %48 %47
-%49 = OpAccessChain %25 %24 %17 %31 %37
+%49 = OpAccessChain %25 %24 %17 %28 %37
%50 = OpLoad %6 %49
-%51 = OpAccessChain %25 %15 %31 %37
+%51 = OpAccessChain %25 %15 %28 %37
OpStore %51 %50
-%52 = OpAccessChain %25 %24 %31 %17
+%52 = OpAccessChain %25 %24 %28 %17
%53 = OpLoad %6 %52
-%54 = OpAccessChain %25 %15 %37 %17 %17
+%54 = OpAccessChain %25 %15 %10 %17 %17
OpStore %54 %53
-%55 = OpAccessChain %25 %24 %31 %31
+%55 = OpAccessChain %25 %24 %28 %28
%56 = OpLoad %6 %55
-%57 = OpAccessChain %25 %15 %37 %17 %31
+%57 = OpAccessChain %25 %15 %10 %17 %28
OpStore %57 %56
-%58 = OpAccessChain %25 %24 %31 %37
+%58 = OpAccessChain %25 %24 %28 %10
%59 = OpLoad %6 %58
-%60 = OpAccessChain %25 %15 %37 %31 %17
+%60 = OpAccessChain %25 %15 %10 %28 %17
OpStore %60 %59
-%62 = OpAccessChain %25 %24 %31 %61
+%62 = OpAccessChain %25 %24 %28 %7
%63 = OpLoad %6 %62
-%64 = OpAccessChain %25 %15 %37 %31 %31
+%64 = OpAccessChain %25 %15 %10 %28 %28
OpStore %64 %63
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,110 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %13 "BufferOut"
OpMemberName %13 0 "o1"
OpMemberName %13 1 "o2"
OpMemberName %13 2 "o3"
OpName %15 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i1"
OpMemberName %22 1 "i2"
OpName %24 ""
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%16 = OpTypeInt 32 1
%7 = OpConstant %16 3
%8 = OpTypeArray %6 %7
%9 = OpTypeArray %6 %7
%10 = OpConstant %16 2
%11 = OpTypeArray %6 %10
%12 = OpTypeArray %11 %10
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%18 = OpTypeArray %6 %7
%19 = OpTypeArray %18 %10
%20 = OpConstant %16 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%17 = OpConstant %16 0
%28 = OpConstant %16 1
%31 = OpConstant %6 1
%34 = OpConstant %6 0
%37 = OpConstant %6 2
%61 = OpConstant %6 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
%32 = OpAccessChain %25 %24 %17 %31 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
%36 = OpAccessChain %25 %15 %17 %31
OpStore %36 %35
%38 = OpAccessChain %25 %24 %17 %31 %31
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %37
%41 = OpAccessChain %25 %15 %17 %10
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %10
%43 = OpLoad %6 %42
%44 = OpAccessChain %25 %15 %31 %17
OpStore %44 %43
%45 = OpAccessChain %25 %24 %17 %17 %31
%46 = OpLoad %6 %45
%47 = OpIMul %6 %46 %7
%48 = OpAccessChain %25 %15 %31 %31
OpStore %48 %47
%49 = OpAccessChain %25 %24 %17 %31 %10
%50 = OpLoad %6 %49
%51 = OpAccessChain %25 %15 %31 %10
OpStore %51 %50
%52 = OpAccessChain %25 %24 %31 %17
%53 = OpLoad %6 %52
%54 = OpAccessChain %25 %15 %37 %17 %17
OpStore %54 %53
%55 = OpAccessChain %25 %24 %31 %31
%56 = OpLoad %6 %55
%57 = OpAccessChain %25 %15 %37 %17 %31
OpStore %57 %56
%58 = OpAccessChain %25 %24 %31 %37
%59 = OpLoad %6 %58
%60 = OpAccessChain %25 %15 %37 %31 %17
OpStore %60 %59
%62 = OpAccessChain %25 %24 %31 %61
%63 = OpLoad %6 %62
%64 = OpAccessChain %25 %15 %37 %31 %31
OpStore %64 %63
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,111 @@
;; Test where signedness of indices are different between src and dst.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %13 "BufferOut"
OpMemberName %13 0 "o1"
OpMemberName %13 1 "o2"
OpMemberName %13 2 "o3"
OpName %15 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i1"
OpMemberName %22 1 "i2"
OpName %24 ""
OpDecorate %8 ArrayStride 4
OpDecorate %9 ArrayStride 4
OpDecorate %11 ArrayStride 4
OpDecorate %12 ArrayStride 8
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 12
OpMemberDecorate %13 2 Offset 24
OpDecorate %13 BufferBlock
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %18 ArrayStride 16
OpDecorate %19 ArrayStride 48
OpDecorate %21 ArrayStride 16
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 96
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpConstant %6 3
%8 = OpTypeArray %6 %7
%9 = OpTypeArray %6 %7
%10 = OpConstant %6 2
%11 = OpTypeArray %6 %10
%12 = OpTypeArray %11 %10
%13 = OpTypeStruct %8 %9 %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable %14 Uniform
%16 = OpTypeInt 32 1
%17 = OpConstant %16 0
%18 = OpTypeArray %6 %7
%19 = OpTypeArray %18 %10
%20 = OpConstant %6 4
%21 = OpTypeArray %6 %20
%22 = OpTypeStruct %19 %21
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %6
%28 = OpConstant %6 1
%31 = OpConstant %16 1
%34 = OpConstant %6 0
%37 = OpConstant %16 2
%61 = OpConstant %16 3
%4 = OpFunction %2 None %3
%5 = OpLabel
%26 = OpAccessChain %25 %24 %17 %17 %17
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
%30 = OpAccessChain %25 %15 %17 %17
OpStore %30 %29
%32 = OpAccessChain %25 %24 %17 %31 %17
%33 = OpLoad %6 %32
%35 = OpIAdd %6 %33 %34
%36 = OpAccessChain %25 %15 %17 %31
OpStore %36 %35
%38 = OpAccessChain %25 %24 %17 %31 %31
%39 = OpLoad %6 %38
%40 = OpIAdd %6 %39 %10
%41 = OpAccessChain %25 %15 %17 %37
OpStore %41 %40
%42 = OpAccessChain %25 %24 %17 %17 %37
%43 = OpLoad %6 %42
%44 = OpAccessChain %25 %15 %31 %17
OpStore %44 %43
%45 = OpAccessChain %25 %24 %17 %17 %31
%46 = OpLoad %6 %45
%47 = OpIMul %6 %46 %7
%48 = OpAccessChain %25 %15 %31 %31
OpStore %48 %47
%49 = OpAccessChain %25 %24 %17 %31 %37
%50 = OpLoad %6 %49
%51 = OpAccessChain %25 %15 %31 %37
OpStore %51 %50
%52 = OpAccessChain %25 %24 %31 %17
%53 = OpLoad %6 %52
%54 = OpAccessChain %25 %15 %37 %17 %17
OpStore %54 %53
%55 = OpAccessChain %25 %24 %31 %31
%56 = OpLoad %6 %55
%57 = OpAccessChain %25 %15 %37 %17 %31
OpStore %57 %56
%58 = OpAccessChain %25 %24 %31 %37
%59 = OpLoad %6 %58
%60 = OpAccessChain %25 %15 %37 %31 %17
OpStore %60 %59
%62 = OpAccessChain %25 %24 %31 %61
%63 = OpLoad %6 %62
%64 = OpAccessChain %25 %15 %37 %31 %31
OpStore %64 %63
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,396 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Tests that identical integer constants are matched, regardless of int or
// uint. This helps compare output from different generators that default to
// int or uint for constants such as those passed to OpAccessChain.
constexpr char kSrc[] = R"(; SPIR-V
; Version: 1.0
; Generator: Google ANGLE Shader Compiler; 0
; Bound: 27
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %19
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%8 = OpTypeVector %5 4
%15 = OpConstant %5 8
%16 = OpTypeArray %1 %15
%17 = OpTypeStruct %2 %1 %16 %16
%20 = OpTypeVoid
%25 = OpConstant %5 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd)";
constexpr char kDst[] = R"(; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 28
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13 %17
OpSource GLSL 450
OpName %4 "main"
OpName %11 "gl_PerVertex"
OpMemberName %11 0 "gl_Position"
OpMemberName %11 1 "gl_PointSize"
OpMemberName %11 2 "gl_ClipDistance"
OpMemberName %11 3 "gl_CullDistance"
OpName %13 ""
OpName %17 "_ua_position"
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %11 Block
OpDecorate %17 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
%16 = OpTypePointer Input %7
%17 = OpVariable %16 Input
%19 = OpTypePointer Output %7
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpLoad %7 %17
%20 = OpAccessChain %19 %13 %15
OpStore %20 %18
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, IntVsUintConstants) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
+; Bound: 31
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %22 "main" %4 %19
+OpEntryPoint Vertex %22 "main" %19 %4
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
-OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
-%8 = OpTypeVector %5 4
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-%17 = OpTypeStruct %2 %1 %16 %16
+%17 = OpTypeStruct %2 %1 %29 %29
%20 = OpTypeVoid
+%28 = OpConstant %5 1
+%29 = OpTypeArray %1 %28
-%25 = OpConstant %5 0
+%25 = OpConstant %30 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
+%30 = OpTypeInt 32 1
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, IntVsUintConstantsNoDebug) {
constexpr char kSrcNoDebug[] = R"(; SPIR-V
; Version: 1.0
; Generator: Google ANGLE Shader Compiler; 0
; Bound: 27
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %19
OpSource GLSL 450
OpDecorate %4 Location 0
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%8 = OpTypeVector %5 4
%15 = OpConstant %5 8
%16 = OpTypeArray %1 %15
%17 = OpTypeStruct %2 %1 %16 %16
%20 = OpTypeVoid
%25 = OpConstant %5 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"(; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 28
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13 %17
OpSource GLSL 450
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %11 Block
OpDecorate %17 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
%16 = OpTypePointer Input %7
%17 = OpVariable %16 Input
%19 = OpTypePointer Output %7
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpLoad %7 %17
%20 = OpAccessChain %19 %13 %15
OpStore %20 %18
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
+; Bound: 31
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %22 "main" %4 %19
+OpEntryPoint Vertex %22 "main" %19 %4
OpSource GLSL 450
OpDecorate %4 Location 0
-OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
-%8 = OpTypeVector %5 4
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-%17 = OpTypeStruct %2 %1 %16 %16
+%17 = OpTypeStruct %2 %1 %29 %29
%20 = OpTypeVoid
+%28 = OpConstant %5 1
+%29 = OpTypeArray %1 %28
-%25 = OpConstant %5 0
+%25 = OpConstant %30 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
+%30 = OpTypeInt 32 1
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
TEST(DiffTest, IntVsUintConstantsDumpIds) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
+; Bound: 31
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %22 "main" %4 %19
+OpEntryPoint Vertex %22 "main" %19 %4
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
-OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
-%8 = OpTypeVector %5 4
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-%17 = OpTypeStruct %2 %1 %16 %16
+%17 = OpTypeStruct %2 %1 %29 %29
%20 = OpTypeVoid
+%28 = OpConstant %5 1
+%29 = OpTypeArray %1 %28
-%25 = OpConstant %5 0
+%25 = OpConstant %30 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
+%30 = OpTypeInt 32 1
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd
Src -> Dst
1 -> 6 [TypeFloat]
2 -> 7 [TypeVector]
3 -> 16 [TypePointer]
4 -> 17 [Variable]
5 -> 8 [TypeInt]
8 -> 23 [TypeVector]
13 -> 19 [TypePointer]
15 -> 29 [Constant]
16 -> 30 [TypeArray]
17 -> 11 [TypeStruct]
18 -> 12 [TypePointer]
19 -> 13 [Variable]
20 -> 2 [TypeVoid]
21 -> 3 [TypeFunction]
22 -> 4 [Function]
23 -> 5 [Label]
24 -> 18 [Load]
25 -> 15 [Constant]
26 -> 20 [AccessChain]
)";
Options options;
options.dump_id_map = true;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,46 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 28
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13 %17
OpSource GLSL 450
OpName %4 "main"
OpName %11 "gl_PerVertex"
OpMemberName %11 0 "gl_Position"
OpMemberName %11 1 "gl_PointSize"
OpMemberName %11 2 "gl_ClipDistance"
OpMemberName %11 3 "gl_CullDistance"
OpName %13 ""
OpName %17 "_ua_position"
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %11 Block
OpDecorate %17 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
%16 = OpTypePointer Input %7
%17 = OpVariable %16 Input
%19 = OpTypePointer Output %7
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpLoad %7 %17
%20 = OpAccessChain %19 %13 %15
OpStore %20 %18
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,49 @@
;; Tests that identical integer constants are matched, regardless of int or
;; uint. This helps compare output from different generators that default to
;; int or uint for constants such as those passed to OpAccessChain.
; SPIR-V
; Version: 1.0
; Generator: Google ANGLE Shader Compiler; 0
; Bound: 27
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %19
OpSource GLSL 450
OpName %4 "_ua_position"
OpName %17 "gl_PerVertex"
OpMemberName %17 0 "gl_Position"
OpMemberName %17 1 "gl_PointSize"
OpMemberName %17 2 "gl_ClipDistance"
OpMemberName %17 3 "gl_CullDistance"
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
OpMemberDecorate %17 2 BuiltIn ClipDistance
OpMemberDecorate %17 3 BuiltIn CullDistance
OpDecorate %17 Block
%1 = OpTypeFloat 32
%2 = OpTypeVector %1 4
%5 = OpTypeInt 32 0
%8 = OpTypeVector %5 4
%15 = OpConstant %5 8
%16 = OpTypeArray %1 %15
%17 = OpTypeStruct %2 %1 %16 %16
%20 = OpTypeVoid
%25 = OpConstant %5 0
%3 = OpTypePointer Input %2
%13 = OpTypePointer Output %2
%18 = OpTypePointer Output %17
%21 = OpTypeFunction %20
%4 = OpVariable %3 Input
%19 = OpVariable %18 Output
%22 = OpFunction %20 None %21
%23 = OpLabel
%24 = OpLoad %2 %4
%26 = OpAccessChain %13 %19 %25
OpStore %26 %24
OpReturn
OpFunctionEnd

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,213 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main" %15 %110
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %12 "x"
OpName %15 "gl_GlobalInvocationID"
OpName %20 "z"
OpName %26 "i"
OpName %40 "BufferOut"
OpMemberName %40 0 "o_uv4"
OpMemberName %40 1 "o_v3"
OpMemberName %40 2 "o_i"
OpName %42 ""
OpName %63 "image2"
OpName %79 "image"
OpName %89 "i"
OpName %110 "gl_LocalInvocationID"
OpName %127 "BufferIn"
OpMemberName %127 0 "i_u"
OpMemberName %127 1 "i_v4"
OpMemberName %127 2 "i_f"
OpName %129 ""
OpDecorate %15 BuiltIn GlobalInvocationId
OpMemberDecorate %40 0 Offset 0
OpMemberDecorate %40 1 Offset 16
OpMemberDecorate %40 2 Offset 28
OpDecorate %40 BufferBlock
OpDecorate %42 DescriptorSet 0
OpDecorate %42 Binding 1
OpDecorate %63 DescriptorSet 0
OpDecorate %63 Binding 3
OpDecorate %79 DescriptorSet 0
OpDecorate %79 Binding 2
OpDecorate %110 BuiltIn LocalInvocationId
OpMemberDecorate %127 0 Offset 0
OpMemberDecorate %127 1 RowMajor
OpMemberDecorate %127 1 Offset 16
OpMemberDecorate %127 1 MatrixStride 16
OpMemberDecorate %127 2 Offset 80
OpDecorate %127 Block
OpDecorate %129 DescriptorSet 0
OpDecorate %129 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeInt 32 0
%11 = OpTypePointer Function %10
%13 = OpTypeVector %10 3
%14 = OpTypePointer Input %13
%15 = OpVariable %14 Input
%16 = OpConstant %10 0
%17 = OpTypePointer Input %10
%21 = OpConstant %10 1
%24 = OpTypeInt 32 1
%25 = OpTypePointer Function %24
%27 = OpConstant %24 0
%34 = OpConstant %24 2
%35 = OpTypeBool
%37 = OpTypeVector %10 4
%38 = OpTypeFloat 32
%39 = OpTypeVector %38 3
%40 = OpTypeStruct %37 %39 %24
%41 = OpTypePointer Uniform %40
%42 = OpVariable %41 Uniform
%46 = OpTypeVector %10 2
%48 = OpTypePointer Uniform %37
%53 = OpTypePointer Uniform %10
%59 = OpConstant %24 1
%61 = OpTypeImage %24 2D 0 0 0 2 R32i
%62 = OpTypePointer UniformConstant %61
%63 = OpVariable %62 UniformConstant
%69 = OpTypeVector %24 2
%71 = OpTypeVector %24 4
%74 = OpTypePointer Uniform %24
%76 = OpConstant %10 2
%77 = OpConstant %10 3400
%78 = OpConstant %10 264
%79 = OpVariable %62 UniformConstant
%96 = OpConstant %24 3
%103 = OpConstantComposite %69 %27 %27
%107 = OpTypePointer Uniform %38
%110 = OpVariable %14 Input
%113 = OpTypeVector %38 2
%125 = OpTypeVector %38 4
%126 = OpTypeMatrix %125 4
%127 = OpTypeStruct %10 %126 %38
%128 = OpTypePointer Uniform %127
%129 = OpVariable %128 Uniform
%4 = OpFunction %2 None %3
%5 = OpLabel
%123 = OpFunctionCall %2 %8
%124 = OpFunctionCall %2 %6
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%12 = OpVariable %11 Function
%20 = OpVariable %11 Function
%26 = OpVariable %25 Function
%18 = OpAccessChain %17 %15 %16
%19 = OpLoad %10 %18
OpStore %12 %19
%22 = OpAccessChain %17 %15 %21
%23 = OpLoad %10 %22
OpStore %20 %23
OpStore %26 %27
OpBranch %28
%28 = OpLabel
OpLoopMerge %30 %31 None
OpBranch %32
%32 = OpLabel
%33 = OpLoad %24 %26
%36 = OpSLessThan %35 %33 %34
OpBranchConditional %36 %29 %30
%29 = OpLabel
%43 = OpLoad %10 %12
%44 = OpLoad %10 %20
%45 = OpIAdd %10 %43 %44
%47 = OpCompositeConstruct %46 %45 %45
%49 = OpAccessChain %48 %42 %27
%50 = OpLoad %37 %49
%51 = OpVectorShuffle %46 %50 %50 0 1
%52 = OpIAdd %46 %51 %47
%54 = OpAccessChain %53 %42 %27 %16
%55 = OpCompositeExtract %10 %52 0
OpStore %54 %55
%56 = OpAccessChain %53 %42 %27 %21
%57 = OpCompositeExtract %10 %52 1
OpStore %56 %57
OpBranch %31
%31 = OpLabel
%58 = OpLoad %24 %26
%60 = OpIAdd %24 %58 %59
OpStore %26 %60
OpBranch %28
%30 = OpLabel
%64 = OpLoad %61 %63
%65 = OpLoad %10 %12
%66 = OpBitcast %24 %65
%67 = OpLoad %10 %20
%68 = OpBitcast %24 %67
%70 = OpCompositeConstruct %69 %66 %68
%72 = OpImageRead %71 %64 %70
%73 = OpCompositeExtract %24 %72 1
%75 = OpAccessChain %74 %42 %34
OpStore %75 %73
OpMemoryBarrier %76 %77
OpControlBarrier %76 %76 %78
%80 = OpLoad %61 %79
%81 = OpLoad %10 %20
%82 = OpBitcast %24 %81
%83 = OpLoad %10 %12
%84 = OpBitcast %24 %83
%85 = OpCompositeConstruct %69 %82 %84
%86 = OpAccessChain %74 %42 %34
%87 = OpLoad %24 %86
%88 = OpCompositeConstruct %71 %87 %27 %27 %27
OpImageWrite %80 %85 %88
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%89 = OpVariable %25 Function
OpStore %89 %27
OpBranch %90
%90 = OpLabel
OpLoopMerge %92 %93 None
OpBranch %94
%94 = OpLabel
%95 = OpLoad %24 %89
%97 = OpSLessThan %35 %95 %96
OpBranchConditional %97 %91 %92
%91 = OpLabel
%98 = OpLoad %24 %89
%99 = OpIEqual %35 %98 %27
OpSelectionMerge %101 None
OpBranchConditional %99 %100 %109
%100 = OpLabel
%102 = OpLoad %61 %63
%104 = OpImageRead %71 %102 %103
%105 = OpCompositeExtract %24 %104 0
%106 = OpConvertSToF %38 %105
%108 = OpAccessChain %107 %42 %59 %16
OpStore %108 %106
OpBranch %101
%109 = OpLabel
%111 = OpLoad %13 %110
%112 = OpConvertUToF %39 %111
%114 = OpCompositeExtract %38 %112 0
%115 = OpCompositeExtract %38 %112 1
%116 = OpCompositeConstruct %113 %114 %115
%117 = OpAccessChain %107 %42 %59 %21
%118 = OpCompositeExtract %38 %116 0
OpStore %117 %118
%119 = OpAccessChain %107 %42 %59 %76
%120 = OpCompositeExtract %38 %116 1
OpStore %119 %120
OpBranch %101
%101 = OpLabel
OpBranch %93
%93 = OpLabel
%121 = OpLoad %24 %89
%122 = OpIAdd %24 %121 %59
OpStore %89 %122
OpBranch %90
%92 = OpLabel
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,230 @@
;; Test where src and dst have a few large functions with large differences.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main" %15
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %12 "x"
OpName %15 "gl_LocalInvocationID"
OpName %20 "y"
OpName %27 "image"
OpName %44 "sum"
OpName %46 "i"
OpName %56 "j"
OpName %80 "BufferOut"
OpMemberName %80 0 "o_uv4"
OpMemberName %80 1 "o_v3"
OpMemberName %80 2 "o_i"
OpName %82 ""
OpName %88 "BufferIn"
OpMemberName %88 0 "i_u"
OpMemberName %88 1 "i_v4"
OpMemberName %88 2 "i_f"
OpName %90 ""
OpName %101 "i"
OpName %128 "image2"
OpDecorate %15 BuiltIn LocalInvocationId
OpDecorate %27 DescriptorSet 0
OpDecorate %27 Binding 2
OpMemberDecorate %80 0 Offset 0
OpMemberDecorate %80 1 Offset 16
OpMemberDecorate %80 2 Offset 28
OpDecorate %80 BufferBlock
OpDecorate %82 DescriptorSet 0
OpDecorate %82 Binding 1
OpMemberDecorate %88 0 Offset 0
OpMemberDecorate %88 1 RowMajor
OpMemberDecorate %88 1 Offset 16
OpMemberDecorate %88 1 MatrixStride 16
OpMemberDecorate %88 2 Offset 80
OpDecorate %88 Block
OpDecorate %90 DescriptorSet 0
OpDecorate %90 Binding 0
OpDecorate %128 DescriptorSet 0
OpDecorate %128 Binding 3
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeInt 32 0
%11 = OpTypePointer Function %10
%13 = OpTypeVector %10 3
%14 = OpTypePointer Input %13
%15 = OpVariable %14 Input
%16 = OpConstant %10 0
%17 = OpTypePointer Input %10
%21 = OpConstant %10 1
%24 = OpTypeInt 32 1
%25 = OpTypeImage %24 2D 0 0 0 2 R32i
%26 = OpTypePointer UniformConstant %25
%27 = OpVariable %26 UniformConstant
%29 = OpTypeVector %10 2
%32 = OpTypeVector %24 2
%38 = OpTypeVector %24 4
%40 = OpConstant %10 2
%41 = OpConstant %10 3400
%42 = OpConstant %10 264
%43 = OpTypePointer Function %24
%45 = OpConstant %24 0
%53 = OpConstant %24 2
%54 = OpTypeBool
%73 = OpConstant %24 1
%77 = OpTypeVector %10 4
%78 = OpTypeFloat 32
%79 = OpTypeVector %78 3
%80 = OpTypeStruct %77 %79 %24
%81 = OpTypePointer Uniform %80
%82 = OpVariable %81 Uniform
%84 = OpTypePointer Uniform %24
%86 = OpTypeVector %78 4
%87 = OpTypeMatrix %86 4
%88 = OpTypeStruct %10 %87 %78
%89 = OpTypePointer Uniform %88
%90 = OpVariable %89 Uniform
%91 = OpTypePointer Uniform %87
%94 = OpTypePointer Uniform %77
%108 = OpConstant %24 3
%110 = OpTypePointer Uniform %79
%113 = OpTypePointer Uniform %78
%128 = OpVariable %26 UniformConstant
%130 = OpConstantComposite %32 %45 %45
%4 = OpFunction %2 None %3
%5 = OpLabel
%136 = OpFunctionCall %2 %6
%137 = OpFunctionCall %2 %8
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%12 = OpVariable %11 Function
%20 = OpVariable %11 Function
%44 = OpVariable %43 Function
%46 = OpVariable %43 Function
%56 = OpVariable %43 Function
%18 = OpAccessChain %17 %15 %16
%19 = OpLoad %10 %18
OpStore %12 %19
%22 = OpAccessChain %17 %15 %21
%23 = OpLoad %10 %22
OpStore %20 %23
%28 = OpLoad %25 %27
%30 = OpLoad %13 %15
%31 = OpVectorShuffle %29 %30 %30 0 1
%33 = OpBitcast %32 %31
%34 = OpLoad %10 %12
%35 = OpLoad %10 %20
%36 = OpIAdd %10 %34 %35
%37 = OpBitcast %24 %36
%39 = OpCompositeConstruct %38 %37 %37 %37 %37
OpImageWrite %28 %33 %39
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
OpStore %44 %45
OpStore %46 %45
OpBranch %47
%47 = OpLabel
OpLoopMerge %49 %50 None
OpBranch %51
%51 = OpLabel
%52 = OpLoad %24 %46
%55 = OpSLessThan %54 %52 %53
OpBranchConditional %55 %48 %49
%48 = OpLabel
OpStore %56 %45
OpBranch %57
%57 = OpLabel
OpLoopMerge %59 %60 None
OpBranch %61
%61 = OpLabel
%62 = OpLoad %24 %56
%63 = OpSLessThan %54 %62 %53
OpBranchConditional %63 %58 %59
%58 = OpLabel
%64 = OpLoad %25 %27
%65 = OpLoad %24 %46
%66 = OpLoad %24 %56
%67 = OpCompositeConstruct %32 %65 %66
%68 = OpImageRead %38 %64 %67
%69 = OpCompositeExtract %24 %68 0
%70 = OpLoad %24 %44
%71 = OpIMul %24 %70 %69
OpStore %44 %71
OpBranch %60
%60 = OpLabel
%72 = OpLoad %24 %56
%74 = OpIAdd %24 %72 %73
OpStore %56 %74
OpBranch %57
%59 = OpLabel
OpBranch %50
%50 = OpLabel
%75 = OpLoad %24 %46
%76 = OpIAdd %24 %75 %73
OpStore %46 %76
OpBranch %47
%49 = OpLabel
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
%83 = OpLoad %24 %44
%85 = OpAccessChain %84 %82 %53
OpStore %85 %83
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%101 = OpVariable %43 Function
%92 = OpAccessChain %91 %90 %73
%93 = OpLoad %87 %92
%95 = OpAccessChain %94 %82 %45
%96 = OpLoad %77 %95
%97 = OpConvertUToF %86 %96
%98 = OpMatrixTimesVector %86 %93 %97
%99 = OpConvertFToU %77 %98
%100 = OpAccessChain %94 %82 %45
OpStore %100 %99
OpStore %101 %45
OpBranch %102
%102 = OpLabel
OpLoopMerge %104 %105 None
OpBranch %106
%106 = OpLabel
%107 = OpLoad %24 %101
%109 = OpSLessThan %54 %107 %108
OpBranchConditional %109 %103 %104
%103 = OpLabel
%111 = OpAccessChain %110 %82 %73
%112 = OpLoad %79 %111
%114 = OpAccessChain %113 %90 %53
%115 = OpLoad %78 %114
%116 = OpVectorTimesScalar %79 %112 %115
%117 = OpConvertFToU %13 %116
%118 = OpCompositeExtract %10 %117 0
%119 = OpCompositeExtract %10 %117 1
%120 = OpCompositeExtract %10 %117 2
%121 = OpCompositeConstruct %77 %118 %119 %120 %16
%122 = OpAccessChain %94 %82 %45
%123 = OpLoad %77 %122
%124 = OpIAdd %77 %123 %121
%125 = OpAccessChain %94 %82 %45
OpStore %125 %124
OpBranch %105
%105 = OpLabel
%126 = OpLoad %24 %101
%127 = OpIAdd %24 %126 %73
OpStore %101 %127
OpBranch %102
%104 = OpLabel
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
%129 = OpLoad %25 %128
%131 = OpImageRead %38 %129 %130
%132 = OpCompositeExtract %24 %131 0
%133 = OpConvertSToF %78 %132
%134 = OpCompositeConstruct %79 %133 %133 %133
%135 = OpAccessChain %110 %82 %73
OpStore %135 %134
OpReturn
OpFunctionEnd

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main" %15
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %12 "x"
OpName %15 "gl_LocalInvocationID"
OpName %20 "y"
OpName %27 "image"
OpName %44 "sum"
OpName %46 "i"
OpName %56 "j"
OpName %80 "BufferOut"
OpMemberName %80 0 "o_uv4"
OpMemberName %80 1 "o_v3"
OpMemberName %80 2 "o_i"
OpName %82 ""
OpName %88 "BufferIn"
OpMemberName %88 0 "i_u"
OpMemberName %88 1 "i_v4"
OpMemberName %88 2 "i_f"
OpName %90 ""
OpName %101 "i"
OpName %128 "image2"
OpDecorate %15 BuiltIn LocalInvocationId
OpDecorate %27 DescriptorSet 0
OpDecorate %27 Binding 2
OpMemberDecorate %80 0 Offset 0
OpMemberDecorate %80 1 Offset 16
OpMemberDecorate %80 2 Offset 28
OpDecorate %80 BufferBlock
OpDecorate %82 DescriptorSet 0
OpDecorate %82 Binding 1
OpMemberDecorate %88 0 Offset 0
OpMemberDecorate %88 1 RowMajor
OpMemberDecorate %88 1 Offset 16
OpMemberDecorate %88 1 MatrixStride 16
OpMemberDecorate %88 2 Offset 80
OpDecorate %88 Block
OpDecorate %90 DescriptorSet 0
OpDecorate %90 Binding 0
OpDecorate %128 DescriptorSet 0
OpDecorate %128 Binding 3
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeInt 32 0
%11 = OpTypePointer Function %10
%13 = OpTypeVector %10 3
%14 = OpTypePointer Input %13
%15 = OpVariable %14 Input
%16 = OpConstant %10 0
%17 = OpTypePointer Input %10
%21 = OpConstant %10 1
%24 = OpTypeInt 32 1
%25 = OpTypeImage %24 2D 0 0 0 2 R32i
%26 = OpTypePointer UniformConstant %25
%27 = OpVariable %26 UniformConstant
%29 = OpTypeVector %10 2
%32 = OpTypeVector %24 2
%38 = OpTypeVector %24 4
%40 = OpConstant %10 2
%41 = OpConstant %10 3400
%42 = OpConstant %10 264
%43 = OpTypePointer Function %24
%45 = OpConstant %24 0
%53 = OpConstant %24 2
%54 = OpTypeBool
%73 = OpConstant %24 1
%77 = OpTypeVector %10 4
%78 = OpTypeFloat 32
%79 = OpTypeVector %78 3
%80 = OpTypeStruct %77 %79 %24
%81 = OpTypePointer Uniform %80
%82 = OpVariable %81 Uniform
%84 = OpTypePointer Uniform %24
%86 = OpTypeVector %78 4
%87 = OpTypeMatrix %86 4
%88 = OpTypeStruct %10 %87 %78
%89 = OpTypePointer Uniform %88
%90 = OpVariable %89 Uniform
%91 = OpTypePointer Uniform %87
%94 = OpTypePointer Uniform %77
%108 = OpConstant %24 3
%110 = OpTypePointer Uniform %79
%113 = OpTypePointer Uniform %78
%128 = OpVariable %26 UniformConstant
%130 = OpConstantComposite %32 %45 %45
%4 = OpFunction %2 None %3
%5 = OpLabel
%136 = OpFunctionCall %2 %6
%137 = OpFunctionCall %2 %8
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%12 = OpVariable %11 Function
%20 = OpVariable %11 Function
%44 = OpVariable %43 Function
%46 = OpVariable %43 Function
%56 = OpVariable %43 Function
%18 = OpAccessChain %17 %15 %16
%19 = OpLoad %10 %18
OpStore %12 %19
%22 = OpAccessChain %17 %15 %21
%23 = OpLoad %10 %22
OpStore %20 %23
%28 = OpLoad %25 %27
%30 = OpLoad %13 %15
%31 = OpVectorShuffle %29 %30 %30 0 1
%33 = OpBitcast %32 %31
%34 = OpLoad %10 %12
%35 = OpLoad %10 %20
%36 = OpIAdd %10 %34 %35
%37 = OpBitcast %24 %36
%39 = OpCompositeConstruct %38 %37 %37 %37 %37
OpImageWrite %28 %33 %39
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
OpStore %44 %45
OpStore %46 %45
OpBranch %47
%47 = OpLabel
OpLoopMerge %49 %50 None
OpBranch %51
%51 = OpLabel
%52 = OpLoad %24 %46
%55 = OpSLessThan %54 %52 %53
OpBranchConditional %55 %48 %49
%48 = OpLabel
OpStore %56 %45
OpBranch %57
%57 = OpLabel
OpLoopMerge %59 %60 None
OpBranch %61
%61 = OpLabel
%62 = OpLoad %24 %56
%63 = OpSLessThan %54 %62 %53
OpBranchConditional %63 %58 %59
%58 = OpLabel
%64 = OpLoad %25 %27
%65 = OpLoad %24 %46
%66 = OpLoad %24 %56
%67 = OpCompositeConstruct %32 %65 %66
%68 = OpImageRead %38 %64 %67
%69 = OpCompositeExtract %24 %68 0
%70 = OpLoad %24 %44
%71 = OpIMul %24 %70 %69
OpStore %44 %71
OpBranch %60
%60 = OpLabel
%72 = OpLoad %24 %56
%74 = OpIAdd %24 %72 %73
OpStore %56 %74
OpBranch %57
%59 = OpLabel
OpBranch %50
%50 = OpLabel
%75 = OpLoad %24 %46
%76 = OpIAdd %24 %75 %73
OpStore %46 %76
OpBranch %47
%49 = OpLabel
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
%83 = OpLoad %24 %44
%85 = OpAccessChain %84 %82 %53
OpStore %85 %83
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%101 = OpVariable %43 Function
%92 = OpAccessChain %91 %90 %73
%93 = OpLoad %87 %92
%95 = OpAccessChain %94 %82 %45
%96 = OpLoad %77 %95
%97 = OpConvertUToF %86 %96
%98 = OpMatrixTimesVector %86 %93 %97
%99 = OpConvertFToU %77 %98
%100 = OpAccessChain %94 %82 %45
OpStore %100 %99
OpStore %101 %45
OpBranch %102
%102 = OpLabel
OpLoopMerge %104 %105 None
OpBranch %106
%106 = OpLabel
%107 = OpLoad %24 %101
%109 = OpSLessThan %54 %107 %108
OpBranchConditional %109 %103 %104
%103 = OpLabel
%111 = OpAccessChain %110 %82 %73
%112 = OpLoad %79 %111
%114 = OpAccessChain %113 %90 %53
%115 = OpLoad %78 %114
%116 = OpVectorTimesScalar %79 %112 %115
%117 = OpConvertFToU %13 %116
%118 = OpCompositeExtract %10 %117 0
%119 = OpCompositeExtract %10 %117 1
%120 = OpCompositeExtract %10 %117 2
%121 = OpCompositeConstruct %77 %118 %119 %120 %16
%122 = OpAccessChain %94 %82 %45
%123 = OpLoad %77 %122
%124 = OpIAdd %77 %123 %121
%125 = OpAccessChain %94 %82 %45
OpStore %125 %124
OpBranch %105
%105 = OpLabel
%126 = OpLoad %24 %101
%127 = OpIAdd %24 %126 %73
OpStore %101 %127
OpBranch %102
%104 = OpLabel
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
%129 = OpLoad %25 %128
%131 = OpImageRead %38 %129 %130
%132 = OpCompositeExtract %24 %131 0
%133 = OpConvertSToF %78 %132
%134 = OpCompositeConstruct %79 %133 %133 %133
%135 = OpAccessChain %110 %82 %73
OpStore %135 %134
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,226 @@
;; Test where src and dst have a few large functions with small differences.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main" %15
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %12 "x"
OpName %15 "gl_LocalInvocationID"
OpName %20 "y"
OpName %27 "image"
OpName %44 "sum"
OpName %46 "i"
OpName %56 "j"
OpName %80 "BufferOut"
OpMemberName %80 0 "o_uv4"
OpMemberName %80 1 "o_v3"
OpMemberName %80 2 "o_i"
OpName %82 ""
OpName %88 "BufferIn"
OpMemberName %88 0 "i_u"
OpMemberName %88 1 "i_v4"
OpMemberName %88 2 "i_f"
OpName %90 ""
OpName %101 "i"
OpDecorate %15 BuiltIn LocalInvocationId
OpDecorate %27 DescriptorSet 0
OpDecorate %27 Binding 2
OpMemberDecorate %80 0 Offset 0
OpMemberDecorate %80 1 Offset 16
OpMemberDecorate %80 2 Offset 28
OpDecorate %80 BufferBlock
OpDecorate %82 DescriptorSet 0
OpDecorate %82 Binding 1
OpMemberDecorate %88 0 Offset 0
OpMemberDecorate %88 1 RowMajor
OpMemberDecorate %88 1 Offset 16
OpMemberDecorate %88 1 MatrixStride 16
OpMemberDecorate %88 2 Offset 80
OpDecorate %88 Block
OpDecorate %90 DescriptorSet 0
OpDecorate %90 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeInt 32 0
%11 = OpTypePointer Function %10
%13 = OpTypeVector %10 3
%14 = OpTypePointer Input %13
%15 = OpVariable %14 Input
%16 = OpConstant %10 0
%17 = OpTypePointer Input %10
%21 = OpConstant %10 1
%24 = OpTypeInt 32 1
%25 = OpTypeImage %24 2D 0 0 0 2 R32i
%26 = OpTypePointer UniformConstant %25
%27 = OpVariable %26 UniformConstant
%29 = OpTypeVector %10 2
%32 = OpTypeVector %24 2
%38 = OpTypeVector %24 4
%40 = OpConstant %10 2
%41 = OpConstant %10 3400
%42 = OpConstant %10 264
%43 = OpTypePointer Function %24
%45 = OpConstant %24 0
%53 = OpConstant %24 2
%54 = OpTypeBool
%73 = OpConstant %24 1
%77 = OpTypeVector %10 4
%78 = OpTypeFloat 32
%79 = OpTypeVector %78 3
%80 = OpTypeStruct %77 %79 %24
%81 = OpTypePointer Uniform %80
%82 = OpVariable %81 Uniform
%84 = OpTypePointer Uniform %24
%86 = OpTypeVector %78 4
%87 = OpTypeMatrix %86 4
%88 = OpTypeStruct %10 %87 %78
%89 = OpTypePointer Uniform %88
%90 = OpVariable %89 Uniform
%91 = OpTypePointer Uniform %87
%94 = OpTypePointer Uniform %77
%108 = OpConstant %24 3
%110 = OpTypePointer Uniform %79
%113 = OpTypePointer Uniform %78
%129 = OpConstantComposite %32 %45 %45
%4 = OpFunction %2 None %3
%5 = OpLabel
%135 = OpFunctionCall %2 %6
%136 = OpFunctionCall %2 %8
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%12 = OpVariable %11 Function
%20 = OpVariable %11 Function
%44 = OpVariable %43 Function
%46 = OpVariable %43 Function
%56 = OpVariable %43 Function
%18 = OpAccessChain %17 %15 %16
%19 = OpLoad %10 %18
OpStore %12 %19
%22 = OpAccessChain %17 %15 %21
%23 = OpLoad %10 %22
OpStore %20 %23
%28 = OpLoad %25 %27
%30 = OpLoad %13 %15
%31 = OpVectorShuffle %29 %30 %30 0 1
%33 = OpBitcast %32 %31
%34 = OpLoad %10 %12
%35 = OpLoad %10 %20
%36 = OpIAdd %10 %34 %35
%37 = OpBitcast %24 %36
%39 = OpCompositeConstruct %38 %37 %37 %37 %37
OpImageWrite %28 %33 %39
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
OpStore %44 %45
OpStore %46 %45
OpBranch %47
%47 = OpLabel
OpLoopMerge %49 %50 None
OpBranch %51
%51 = OpLabel
%52 = OpLoad %24 %46
%55 = OpSLessThan %54 %52 %53
OpBranchConditional %55 %48 %49
%48 = OpLabel
OpStore %56 %45
OpBranch %57
%57 = OpLabel
OpLoopMerge %59 %60 None
OpBranch %61
%61 = OpLabel
%62 = OpLoad %24 %56
%63 = OpSLessThan %54 %62 %53
OpBranchConditional %63 %58 %59
%58 = OpLabel
%64 = OpLoad %25 %27
%65 = OpLoad %24 %46
%66 = OpLoad %24 %56
%67 = OpCompositeConstruct %32 %65 %66
%68 = OpImageRead %38 %64 %67
%69 = OpCompositeExtract %24 %68 0
%70 = OpLoad %24 %44
%71 = OpIAdd %24 %70 %69
OpStore %44 %71
OpBranch %60
%60 = OpLabel
%72 = OpLoad %24 %56
%74 = OpIAdd %24 %72 %73
OpStore %56 %74
OpBranch %57
%59 = OpLabel
OpBranch %50
%50 = OpLabel
%75 = OpLoad %24 %46
%76 = OpIAdd %24 %75 %73
OpStore %46 %76
OpBranch %47
%49 = OpLabel
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
%83 = OpLoad %24 %44
%85 = OpAccessChain %84 %82 %53
OpStore %85 %83
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%101 = OpVariable %43 Function
%92 = OpAccessChain %91 %90 %73
%93 = OpLoad %87 %92
%95 = OpAccessChain %94 %82 %45
%96 = OpLoad %77 %95
%97 = OpConvertUToF %86 %96
%98 = OpMatrixTimesVector %86 %93 %97
%99 = OpConvertFToU %77 %98
%100 = OpAccessChain %94 %82 %45
OpStore %100 %99
OpStore %101 %45
OpBranch %102
%102 = OpLabel
OpLoopMerge %104 %105 None
OpBranch %106
%106 = OpLabel
%107 = OpLoad %24 %101
%109 = OpSLessThan %54 %107 %108
OpBranchConditional %109 %103 %104
%103 = OpLabel
%111 = OpAccessChain %110 %82 %73
%112 = OpLoad %79 %111
%114 = OpAccessChain %113 %90 %53
%115 = OpLoad %78 %114
%116 = OpVectorTimesScalar %79 %112 %115
%117 = OpConvertFToU %13 %116
%118 = OpCompositeExtract %10 %117 0
%119 = OpCompositeExtract %10 %117 1
%120 = OpCompositeExtract %10 %117 2
%121 = OpCompositeConstruct %77 %118 %119 %120 %16
%122 = OpAccessChain %94 %82 %45
%123 = OpLoad %77 %122
%124 = OpIAdd %77 %123 %121
%125 = OpAccessChain %94 %82 %45
OpStore %125 %124
OpBranch %105
%105 = OpLabel
%126 = OpLoad %24 %101
%127 = OpIAdd %24 %126 %73
OpStore %101 %127
OpBranch %102
%104 = OpLabel
OpMemoryBarrier %40 %41
OpControlBarrier %40 %40 %42
%128 = OpLoad %25 %27
%130 = OpImageRead %38 %128 %129
%131 = OpCompositeExtract %24 %130 0
%132 = OpConvertSToF %78 %131
%133 = OpCompositeConstruct %79 %132 %132 %132
%134 = OpAccessChain %110 %82 %73
OpStore %134 %133
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,330 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Basic test for multiple entry points. The entry points have different
// execution models and so can be trivially matched.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %mainv "mainv" %vo %a
OpEntryPoint Fragment %mainf "mainf" %color %vi
OpExecutionMode %mainf OriginUpperLeft
OpSource ESSL 310
OpName %mainv "mainv"
OpName %mainf "mainf"
OpName %a "a"
OpName %vo "v"
OpName %vi "v"
OpName %color "color"
OpDecorate %a Location 0
OpDecorate %vo Location 0
OpDecorate %vi Location 0
OpDecorate %color Location 0
OpDecorate %color RelaxedPrecision
OpDecorate %vi RelaxedPrecision
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Input_float = OpTypePointer Input %float
%a = OpVariable %_ptr_Input_float Input
%_ptr_Output_float = OpTypePointer Output %float
%vo = OpVariable %_ptr_Output_float Output
%vi = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%mainv = OpFunction %void None %3
%5 = OpLabel
%11 = OpLoad %float %a
OpStore %vo %11
OpReturn
OpFunctionEnd
%mainf = OpFunction %void None %3
%6 = OpLabel
%12 = OpLoad %float %vi
%13 = OpCompositeConstruct %v4float %12 %12 %12 %12
OpStore %color %13
OpReturn
OpFunctionEnd)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %frag "frag" %vi %color
OpEntryPoint Vertex %vert "vert" %a %vo
OpExecutionMode %frag OriginUpperLeft
OpSource ESSL 310
OpName %frag "frag"
OpName %vert "vert"
OpName %vo "v"
OpName %a "a"
OpName %color "color"
OpName %vi "v"
OpDecorate %vi Location 0
OpDecorate %color Location 0
OpDecorate %a Location 0
OpDecorate %vo Location 0
OpDecorate %color RelaxedPrecision
OpDecorate %vi RelaxedPrecision
OpDecorate %14 RelaxedPrecision
OpDecorate %17 RelaxedPrecision
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%void = OpTypeVoid
%3 = OpTypeFunction %void
%_ptr_Output_float = OpTypePointer Output %float
%vo = OpVariable %_ptr_Output_float Output
%_ptr_Input_float = OpTypePointer Input %float
%a = OpVariable %_ptr_Input_float Input
%vi = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%frag = OpFunction %void None %3
%7 = OpLabel
%14 = OpLoad %float %vi
%17 = OpCompositeConstruct %v4float %14 %14 %14 %14
OpStore %color %17
OpReturn
OpFunctionEnd
%vert = OpFunction %void None %3
%8 = OpLabel
%13 = OpLoad %float %a
OpStore %vo %13
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, MultipleDifferentEntryPoints) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 20
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %2 "mainv" %4 %7
+OpEntryPoint Vertex %2 "vert" %7 %4
-OpEntryPoint Fragment %8 "mainf" %9 %10
+OpEntryPoint Fragment %8 "frag" %10 %9
OpExecutionMode %8 OriginUpperLeft
OpSource ESSL 310
-OpName %2 "mainv"
+OpName %2 "vert"
-OpName %8 "mainf"
+OpName %8 "frag"
OpName %7 "a"
OpName %4 "v"
OpName %10 "v"
OpName %9 "color"
OpDecorate %7 Location 0
OpDecorate %4 Location 0
OpDecorate %10 Location 0
OpDecorate %9 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%14 = OpTypeVoid
%3 = OpTypeFunction %14
%15 = OpTypeFloat 32
%16 = OpTypeVector %15 4
%17 = OpTypePointer Input %15
%7 = OpVariable %17 Input
%18 = OpTypePointer Output %15
%4 = OpVariable %18 Output
%10 = OpVariable %17 Input
%19 = OpTypePointer Output %16
%9 = OpVariable %19 Output
%8 = OpFunction %14 None %3
%6 = OpLabel
%12 = OpLoad %15 %10
%13 = OpCompositeConstruct %16 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
%2 = OpFunction %14 None %3
%5 = OpLabel
%11 = OpLoad %15 %7
OpStore %4 %11
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, MultipleDifferentEntryPointsNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %mainv "mainv" %vo %a
OpEntryPoint Fragment %mainf "mainf" %color %vi
OpExecutionMode %mainf OriginUpperLeft
OpSource ESSL 310
OpDecorate %a Location 0
OpDecorate %vo Location 0
OpDecorate %vi Location 0
OpDecorate %color Location 0
OpDecorate %color RelaxedPrecision
OpDecorate %vi RelaxedPrecision
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Input_float = OpTypePointer Input %float
%a = OpVariable %_ptr_Input_float Input
%_ptr_Output_float = OpTypePointer Output %float
%vo = OpVariable %_ptr_Output_float Output
%vi = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%mainv = OpFunction %void None %3
%5 = OpLabel
%11 = OpLoad %float %a
OpStore %vo %11
OpReturn
OpFunctionEnd
%mainf = OpFunction %void None %3
%6 = OpLabel
%12 = OpLoad %float %vi
%13 = OpCompositeConstruct %v4float %12 %12 %12 %12
OpStore %color %13
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %frag "frag" %vi %color
OpEntryPoint Vertex %vert "vert" %a %vo
OpExecutionMode %frag OriginUpperLeft
OpSource ESSL 310
OpDecorate %vi Location 0
OpDecorate %color Location 0
OpDecorate %a Location 0
OpDecorate %vo Location 0
OpDecorate %color RelaxedPrecision
OpDecorate %vi RelaxedPrecision
OpDecorate %14 RelaxedPrecision
OpDecorate %17 RelaxedPrecision
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%void = OpTypeVoid
%3 = OpTypeFunction %void
%_ptr_Output_float = OpTypePointer Output %float
%vo = OpVariable %_ptr_Output_float Output
%_ptr_Input_float = OpTypePointer Input %float
%a = OpVariable %_ptr_Input_float Input
%vi = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%frag = OpFunction %void None %3
%7 = OpLabel
%14 = OpLoad %float %vi
%17 = OpCompositeConstruct %v4float %14 %14 %14 %14
OpStore %color %17
OpReturn
OpFunctionEnd
%vert = OpFunction %void None %3
%8 = OpLabel
%13 = OpLoad %float %a
OpStore %vo %13
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 20
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %2 "mainv" %4 %7
+OpEntryPoint Vertex %2 "vert" %7 %4
-OpEntryPoint Fragment %8 "mainf" %9 %10
+OpEntryPoint Fragment %8 "frag" %10 %9
OpExecutionMode %8 OriginUpperLeft
OpSource ESSL 310
OpDecorate %7 Location 0
OpDecorate %4 Location 0
OpDecorate %10 Location 0
OpDecorate %9 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%14 = OpTypeVoid
%3 = OpTypeFunction %14
%15 = OpTypeFloat 32
%16 = OpTypeVector %15 4
%17 = OpTypePointer Input %15
%7 = OpVariable %17 Input
%18 = OpTypePointer Output %15
%4 = OpVariable %18 Output
%10 = OpVariable %17 Input
%19 = OpTypePointer Output %16
%9 = OpVariable %19 Output
%8 = OpFunction %14 None %3
%6 = OpLabel
%12 = OpLoad %15 %10
%13 = OpCompositeConstruct %16 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
%2 = OpFunction %14 None %3
%5 = OpLabel
%11 = OpLoad %15 %7
OpStore %4 %11
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,49 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %frag "frag" %vi %color
OpEntryPoint Vertex %vert "vert" %a %vo
OpExecutionMode %frag OriginUpperLeft
OpSource ESSL 310
OpName %frag "frag"
OpName %vert "vert"
OpName %vo "v"
OpName %a "a"
OpName %color "color"
OpName %vi "v"
OpDecorate %vi Location 0
OpDecorate %color Location 0
OpDecorate %a Location 0
OpDecorate %vo Location 0
OpDecorate %color RelaxedPrecision
OpDecorate %vi RelaxedPrecision
OpDecorate %14 RelaxedPrecision
OpDecorate %17 RelaxedPrecision
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%void = OpTypeVoid
%3 = OpTypeFunction %void
%_ptr_Output_float = OpTypePointer Output %float
%vo = OpVariable %_ptr_Output_float Output
%_ptr_Input_float = OpTypePointer Input %float
%a = OpVariable %_ptr_Input_float Input
%vi = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%frag = OpFunction %void None %3
%7 = OpLabel
%14 = OpLoad %float %vi
%17 = OpCompositeConstruct %v4float %14 %14 %14 %14
OpStore %color %17
OpReturn
OpFunctionEnd
%vert = OpFunction %void None %3
%8 = OpLabel
%13 = OpLoad %float %a
OpStore %vo %13
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,51 @@
;; Basic test for multiple entry points. The entry points have different
;; execution models and so can be trivially matched.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %mainv "mainv" %vo %a
OpEntryPoint Fragment %mainf "mainf" %color %vi
OpExecutionMode %mainf OriginUpperLeft
OpSource ESSL 310
OpName %mainv "mainv"
OpName %mainf "mainf"
OpName %a "a"
OpName %vo "v"
OpName %vi "v"
OpName %color "color"
OpDecorate %a Location 0
OpDecorate %vo Location 0
OpDecorate %vi Location 0
OpDecorate %color Location 0
OpDecorate %color RelaxedPrecision
OpDecorate %vi RelaxedPrecision
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Input_float = OpTypePointer Input %float
%a = OpVariable %_ptr_Input_float Input
%_ptr_Output_float = OpTypePointer Output %float
%vo = OpVariable %_ptr_Output_float Output
%vi = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%mainv = OpFunction %void None %3
%5 = OpLabel
%11 = OpLoad %float %a
OpStore %vo %11
OpReturn
OpFunctionEnd
%mainf = OpFunction %void None %3
%6 = OpLabel
%12 = OpLoad %float %vi
%13 = OpCompositeConstruct %v4float %12 %12 %12 %12
OpStore %color %13
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,375 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Test for multiple entry points with the same execution model.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main1" %8 %10
OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpName %4 "main1"
OpName %12 "main2"
OpName %8 "v"
OpName %10 "a"
OpName %13 "v"
OpName %14 "a"
OpName %15 "b"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main2" %13 %14 %15
OpEntryPoint Vertex %12 "main1" %8 %10
OpSource ESSL 310
OpName %12 "main1"
OpName %4 "main2"
OpName %8 "v"
OpName %10 "a"
OpName %13 "v"
OpName %14 "a"
OpName %15 "b"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, MultipleSameEntryPoints) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 20
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpEntryPoint Vertex %4 "main1" %8 %10
-OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpName %4 "main1"
OpName %12 "main2"
OpName %8 "v"
OpName %10 "a"
OpName %13 "v"
OpName %14 "a"
OpName %15 "b"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%12 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, MultipleSameEntryPointsNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main1" %8 %10
OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main2" %13 %14 %15
OpEntryPoint Vertex %12 "main1" %8 %10
OpSource ESSL 310
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 20
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpEntryPoint Vertex %4 "main1" %8 %10
-OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%12 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
TEST(DiffTest, MultipleSameEntryPointsDumpIds) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 20
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpEntryPoint Vertex %4 "main1" %8 %10
-OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpName %4 "main1"
OpName %12 "main2"
OpName %8 "v"
OpName %10 "a"
OpName %13 "v"
OpName %14 "a"
OpName %15 "b"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%12 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
Src -> Dst
1 -> 1 [ExtInstImport]
2 -> 2 [TypeVoid]
3 -> 3 [TypeFunction]
4 -> 12 [Function]
5 -> 5 [Label]
6 -> 6 [TypeFloat]
7 -> 7 [TypePointer]
8 -> 8 [Variable]
9 -> 9 [TypePointer]
10 -> 10 [Variable]
11 -> 11 [Load]
12 -> 4 [Function]
13 -> 13 [Variable]
14 -> 14 [Variable]
15 -> 15 [Variable]
16 -> 16 [Label]
17 -> 17 [Load]
18 -> 18 [Load]
19 -> 19 [FAdd]
)";
Options options;
options.dump_id_map = true;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,45 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main2" %13 %14 %15
OpEntryPoint Vertex %12 "main1" %8 %10
OpSource ESSL 310
OpName %12 "main1"
OpName %4 "main2"
OpName %8 "v"
OpName %10 "a"
OpName %13 "v"
OpName %14 "a"
OpName %15 "b"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,46 @@
;; Test for multiple entry points with the same execution model.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main1" %8 %10
OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpName %4 "main1"
OpName %12 "main2"
OpName %8 "v"
OpName %10 "a"
OpName %13 "v"
OpName %14 "a"
OpName %15 "b"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
OpDecorate %13 Location 0
OpDecorate %14 Location 0
OpDecorate %15 Location 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%9 = OpTypePointer Input %6
%8 = OpVariable %7 Output
%10 = OpVariable %9 Input
%13 = OpVariable %7 Output
%14 = OpVariable %9 Input
%15 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%16 = OpLabel
%17 = OpLoad %6 %14
%18 = OpLoad %6 %15
%19 = OpFAdd %6 %17 %18
OpStore %13 %19
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,568 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Test where src and dst have the true and false blocks of an if reordered.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %44 "color"
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%21 = OpConstant %6 -0.5
%22 = OpConstant %6 -0.300000012
%38 = OpConstant %6 0.5
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %13 %32
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Log %18
%20 = OpLoad %6 %8
%23 = OpExtInst %6 %1 FClamp %20 %21 %22
%24 = OpFMul %6 %19 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Sin %25
%27 = OpLoad %6 %8
%28 = OpExtInst %6 %1 Cos %27
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Exp %29
%31 = OpCompositeConstruct %15 %24 %26 %28 %30
OpBranch %14
%32 = OpLabel
%33 = OpLoad %6 %8
%34 = OpExtInst %6 %1 Sqrt %33
%35 = OpLoad %6 %8
%36 = OpExtInst %6 %1 FSign %35
%37 = OpLoad %6 %8
%39 = OpExtInst %6 %1 FMax %37 %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Floor %40
%42 = OpCompositeConstruct %15 %34 %36 %39 %41
OpBranch %14
%14 = OpLabel
%45 = OpPhi %15 %31 %13 %42 %32
OpStore %44 %45
OpReturn
OpFunctionEnd)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %44 "color"
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %21 RelaxedPrecision
OpDecorate %22 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%23 = OpConstant %6 0.5
%32 = OpConstant %6 -0.5
%33 = OpConstant %6 -0.300000012
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %28 %13
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Sqrt %18
%20 = OpLoad %6 %8
%21 = OpExtInst %6 %1 FSign %20
%22 = OpLoad %6 %8
%24 = OpExtInst %6 %1 FMax %22 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Floor %25
%27 = OpCompositeConstruct %15 %19 %21 %24 %26
OpBranch %14
%28 = OpLabel
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Log %29
%31 = OpLoad %6 %8
%34 = OpExtInst %6 %1 FClamp %31 %32 %33
%35 = OpFMul %6 %30 %34
%36 = OpLoad %6 %8
%37 = OpExtInst %6 %1 Sin %36
%38 = OpLoad %6 %8
%39 = OpExtInst %6 %1 Cos %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Exp %40
%42 = OpCompositeConstruct %15 %35 %37 %39 %41
OpBranch %14
%14 = OpLabel
%45 = OpPhi %15 %27 %13 %42 %28
OpStore %44 %45
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, ReorderedIfBlocks) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 46
+; Bound: 47
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %44 "color"
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%21 = OpConstant %6 -0.5
%22 = OpConstant %6 -0.300000012
%38 = OpConstant %6 0.5
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %13 %32
%32 = OpLabel
%33 = OpLoad %6 %8
%34 = OpExtInst %6 %1 Sqrt %33
%35 = OpLoad %6 %8
%36 = OpExtInst %6 %1 FSign %35
%37 = OpLoad %6 %8
%39 = OpExtInst %6 %1 FMax %37 %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Floor %40
%42 = OpCompositeConstruct %15 %34 %36 %39 %41
OpBranch %14
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Log %18
%20 = OpLoad %6 %8
%23 = OpExtInst %6 %1 FClamp %20 %21 %22
%24 = OpFMul %6 %19 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Sin %25
%27 = OpLoad %6 %8
%28 = OpExtInst %6 %1 Cos %27
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Exp %29
%31 = OpCompositeConstruct %15 %24 %26 %28 %30
OpBranch %14
%14 = OpLabel
-%45 = OpPhi %15 %31 %13 %42 %32
+%45 = OpPhi %15 %42 %32 %31 %13
OpStore %44 %45
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, ReorderedIfBlocksNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%21 = OpConstant %6 -0.5
%22 = OpConstant %6 -0.300000012
%38 = OpConstant %6 0.5
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %13 %32
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Log %18
%20 = OpLoad %6 %8
%23 = OpExtInst %6 %1 FClamp %20 %21 %22
%24 = OpFMul %6 %19 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Sin %25
%27 = OpLoad %6 %8
%28 = OpExtInst %6 %1 Cos %27
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Exp %29
%31 = OpCompositeConstruct %15 %24 %26 %28 %30
OpBranch %14
%32 = OpLabel
%33 = OpLoad %6 %8
%34 = OpExtInst %6 %1 Sqrt %33
%35 = OpLoad %6 %8
%36 = OpExtInst %6 %1 FSign %35
%37 = OpLoad %6 %8
%39 = OpExtInst %6 %1 FMax %37 %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Floor %40
%42 = OpCompositeConstruct %15 %34 %36 %39 %41
OpBranch %14
%14 = OpLabel
%45 = OpPhi %15 %31 %13 %42 %32
OpStore %44 %45
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %21 RelaxedPrecision
OpDecorate %22 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%23 = OpConstant %6 0.5
%32 = OpConstant %6 -0.5
%33 = OpConstant %6 -0.300000012
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %28 %13
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Sqrt %18
%20 = OpLoad %6 %8
%21 = OpExtInst %6 %1 FSign %20
%22 = OpLoad %6 %8
%24 = OpExtInst %6 %1 FMax %22 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Floor %25
%27 = OpCompositeConstruct %15 %19 %21 %24 %26
OpBranch %14
%28 = OpLabel
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Log %29
%31 = OpLoad %6 %8
%34 = OpExtInst %6 %1 FClamp %31 %32 %33
%35 = OpFMul %6 %30 %34
%36 = OpLoad %6 %8
%37 = OpExtInst %6 %1 Sin %36
%38 = OpLoad %6 %8
%39 = OpExtInst %6 %1 Cos %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Exp %40
%42 = OpCompositeConstruct %15 %35 %37 %39 %41
OpBranch %14
%14 = OpLabel
%45 = OpPhi %15 %27 %13 %42 %28
OpStore %44 %45
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 46
+; Bound: 47
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%21 = OpConstant %6 -0.5
%22 = OpConstant %6 -0.300000012
%38 = OpConstant %6 0.5
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %13 %32
%32 = OpLabel
%33 = OpLoad %6 %8
%34 = OpExtInst %6 %1 Sqrt %33
%35 = OpLoad %6 %8
%36 = OpExtInst %6 %1 FSign %35
%37 = OpLoad %6 %8
%39 = OpExtInst %6 %1 FMax %37 %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Floor %40
%42 = OpCompositeConstruct %15 %34 %36 %39 %41
OpBranch %14
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Log %18
%20 = OpLoad %6 %8
%23 = OpExtInst %6 %1 FClamp %20 %21 %22
%24 = OpFMul %6 %19 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Sin %25
%27 = OpLoad %6 %8
%28 = OpExtInst %6 %1 Cos %27
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Exp %29
%31 = OpCompositeConstruct %15 %24 %26 %28 %30
OpBranch %14
%14 = OpLabel
-%45 = OpPhi %15 %31 %13 %42 %32
+%45 = OpPhi %15 %42 %32 %31 %13
OpStore %44 %45
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,87 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %44 "color"
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %21 RelaxedPrecision
OpDecorate %22 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%23 = OpConstant %6 0.5
%32 = OpConstant %6 -0.5
%33 = OpConstant %6 -0.300000012
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %28 %13
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Sqrt %18
%20 = OpLoad %6 %8
%21 = OpExtInst %6 %1 FSign %20
%22 = OpLoad %6 %8
%24 = OpExtInst %6 %1 FMax %22 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Floor %25
%27 = OpCompositeConstruct %15 %19 %21 %24 %26
OpBranch %14
%28 = OpLabel
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Log %29
%31 = OpLoad %6 %8
%34 = OpExtInst %6 %1 FClamp %31 %32 %33
%35 = OpFMul %6 %30 %34
%36 = OpLoad %6 %8
%37 = OpExtInst %6 %1 Sin %36
%38 = OpLoad %6 %8
%39 = OpExtInst %6 %1 Cos %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Exp %40
%42 = OpCompositeConstruct %15 %35 %37 %39 %41
OpBranch %14
%14 = OpLabel
%45 = OpPhi %15 %27 %13 %42 %28
OpStore %44 %45
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,87 @@
;; Test where src and dst have the true and false blocks of an if reordered.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %8 %44
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %44 "color"
OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
OpDecorate %9 RelaxedPrecision
OpDecorate %18 RelaxedPrecision
OpDecorate %19 RelaxedPrecision
OpDecorate %20 RelaxedPrecision
OpDecorate %23 RelaxedPrecision
OpDecorate %24 RelaxedPrecision
OpDecorate %25 RelaxedPrecision
OpDecorate %26 RelaxedPrecision
OpDecorate %27 RelaxedPrecision
OpDecorate %28 RelaxedPrecision
OpDecorate %29 RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %42 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %44 Location 0
OpDecorate %45 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Input %6
%8 = OpVariable %7 Input
%10 = OpConstant %6 0
%11 = OpTypeBool
%15 = OpTypeVector %6 4
%16 = OpTypePointer Function %15
%21 = OpConstant %6 -0.5
%22 = OpConstant %6 -0.300000012
%38 = OpConstant %6 0.5
%43 = OpTypePointer Output %15
%44 = OpVariable %43 Output
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpLoad %6 %8
%12 = OpFOrdLessThanEqual %11 %9 %10
OpSelectionMerge %14 None
OpBranchConditional %12 %13 %32
%13 = OpLabel
%18 = OpLoad %6 %8
%19 = OpExtInst %6 %1 Log %18
%20 = OpLoad %6 %8
%23 = OpExtInst %6 %1 FClamp %20 %21 %22
%24 = OpFMul %6 %19 %23
%25 = OpLoad %6 %8
%26 = OpExtInst %6 %1 Sin %25
%27 = OpLoad %6 %8
%28 = OpExtInst %6 %1 Cos %27
%29 = OpLoad %6 %8
%30 = OpExtInst %6 %1 Exp %29
%31 = OpCompositeConstruct %15 %24 %26 %28 %30
OpBranch %14
%32 = OpLabel
%33 = OpLoad %6 %8
%34 = OpExtInst %6 %1 Sqrt %33
%35 = OpLoad %6 %8
%36 = OpExtInst %6 %1 FSign %35
%37 = OpLoad %6 %8
%39 = OpExtInst %6 %1 FMax %37 %38
%40 = OpLoad %6 %8
%41 = OpExtInst %6 %1 Floor %40
%42 = OpCompositeConstruct %15 %34 %36 %39 %41
OpBranch %14
%14 = OpLabel
%45 = OpPhi %15 %31 %13 %42 %32
OpStore %44 %45
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,582 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Test where src and dst have cases of a switch in different order.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %7 "BufferIn"
OpMemberName %7 0 "i"
OpName %9 ""
OpName %23 "BufferOut"
OpMemberName %23 0 "o"
OpName %25 ""
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%22 = OpLabel
OpReturn
OpFunctionEnd)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %7 "BufferIn"
OpMemberName %7 0 "i"
OpName %9 ""
OpName %23 "BufferOut"
OpMemberName %23 0 "o"
OpName %25 ""
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%22 = OpLabel
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, ReorderedSwitchBlocks) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 58
+; Bound: 62
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %7 "BufferIn"
OpMemberName %7 0 "i"
OpName %9 ""
OpName %23 "BufferOut"
OpMemberName %23 0 "o"
OpName %25 ""
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%22 = OpLabel
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, ReorderedSwitchBlocksNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%22 = OpLabel
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%22 = OpLabel
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 58
+; Bound: 62
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%22 = OpLabel
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,91 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %7 "BufferIn"
OpMemberName %7 0 "i"
OpName %9 ""
OpName %23 "BufferOut"
OpMemberName %23 0 "o"
OpName %25 ""
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%22 = OpLabel
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,92 @@
;; Test where src and dst have cases of a switch in different order.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %7 "BufferIn"
OpMemberName %7 0 "i"
OpName %9 ""
OpName %23 "BufferOut"
OpMemberName %23 0 "o"
OpName %25 ""
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 BufferBlock
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 1
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 0
%7 = OpTypeStruct %6
%8 = OpTypePointer Uniform %7
%9 = OpVariable %8 Uniform
%10 = OpTypeInt 32 1
%11 = OpConstant %10 0
%12 = OpTypePointer Uniform %6
%23 = OpTypeStruct %6
%24 = OpTypePointer Uniform %23
%25 = OpVariable %24 Uniform
%28 = OpConstant %10 1
%34 = OpConstant %6 2
%52 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%13 = OpAccessChain %12 %9 %11
%14 = OpLoad %6 %13
OpSelectionMerge %22 None
OpSwitch %14 %21 0 %15 1 %16 2 %17 3 %18 4 %19 5 %20
%21 = OpLabel
%54 = OpAccessChain %12 %25 %11
%55 = OpLoad %6 %54
%56 = OpIAdd %6 %55 %34
%57 = OpAccessChain %12 %25 %11
OpStore %57 %56
OpBranch %22
%15 = OpLabel
%26 = OpAccessChain %12 %25 %11
%27 = OpLoad %6 %26
%29 = OpIAdd %6 %27 %28
OpStore %26 %29
OpBranch %22
%16 = OpLabel
%31 = OpAccessChain %12 %25 %11
%32 = OpLoad %6 %31
%33 = OpISub %6 %32 %28
OpStore %31 %33
OpBranch %17
%17 = OpLabel
%35 = OpAccessChain %12 %25 %11
%36 = OpLoad %6 %35
%37 = OpIMul %6 %36 %34
%38 = OpAccessChain %12 %25 %11
OpStore %38 %37
OpBranch %22
%18 = OpLabel
%40 = OpAccessChain %12 %25 %11
%41 = OpLoad %6 %40
%42 = OpUDiv %6 %41 %34
%43 = OpAccessChain %12 %25 %11
OpStore %43 %42
OpBranch %22
%19 = OpLabel
%45 = OpAccessChain %12 %25 %11
%46 = OpLoad %6 %45
%47 = OpAccessChain %12 %25 %11
%48 = OpLoad %6 %47
%49 = OpIMul %6 %46 %48
%50 = OpAccessChain %12 %25 %11
OpStore %50 %49
OpBranch %22
%20 = OpLabel
%53 = OpAccessChain %12 %25 %11
OpStore %53 %52
OpBranch %21
%22 = OpLabel
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,747 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Test where src and dst have many small functions with small differences.
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %10 "f3("
OpName %12 "f4("
OpName %14 "f5("
OpName %17 "BufferOut"
OpMemberName %17 0 "o"
OpName %19 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i"
OpName %24 ""
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpIAdd %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpISub %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
%39 = OpIMul %16 %38 %36
%40 = OpAccessChain %25 %19 %21
OpStore %40 %39
OpReturn
OpFunctionEnd
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
%43 = OpUDiv %16 %42 %36
%44 = OpAccessChain %25 %19 %21
OpStore %44 %43
OpReturn
OpFunctionEnd
)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %10 "f3("
OpName %12 "f4("
OpName %14 "f5("
OpName %17 "BufferOut"
OpMemberName %17 0 "o"
OpName %19 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i"
OpName %24 ""
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
%43 = OpIAdd %16 %42 %36
%44 = OpAccessChain %25 %19 %21
OpStore %44 %43
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpISub %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpIAdd %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
%39 = OpISub %16 %38 %36
%40 = OpAccessChain %25 %19 %21
OpStore %40 %39
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, SmallFunctionsSmallDiffs) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 50
+; Bound: 54
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %10 "f3("
OpName %12 "f4("
OpName %14 "f5("
OpName %17 "BufferOut"
OpMemberName %17 0 "o"
OpName %19 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i"
OpName %24 ""
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
-%43 = OpUDiv %16 %42 %36
+%53 = OpIAdd %16 %42 %36
%44 = OpAccessChain %25 %19 %21
-OpStore %44 %43
+OpStore %44 %53
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
-%39 = OpIMul %16 %38 %36
+%52 = OpISub %16 %38 %36
%40 = OpAccessChain %25 %19 %21
-OpStore %40 %39
+OpStore %40 %52
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
-%35 = OpISub %16 %34 %31
+%51 = OpIAdd %16 %34 %31
-OpStore %33 %35
+OpStore %33 %51
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
-%32 = OpIAdd %16 %30 %31
+%50 = OpISub %16 %30 %31
-OpStore %29 %32
+OpStore %29 %50
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, SmallFunctionsSmallDiffsNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpIAdd %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpISub %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
%39 = OpIMul %16 %38 %36
%40 = OpAccessChain %25 %19 %21
OpStore %40 %39
OpReturn
OpFunctionEnd
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
%43 = OpUDiv %16 %42 %36
%44 = OpAccessChain %25 %19 %21
OpStore %44 %43
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
%43 = OpIAdd %16 %42 %36
%44 = OpAccessChain %25 %19 %21
OpStore %44 %43
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpISub %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpIAdd %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
%39 = OpISub %16 %38 %36
%40 = OpAccessChain %25 %19 %21
OpStore %40 %39
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 50
+; Bound: 52
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
-%43 = OpUDiv %16 %42 %36
+%51 = OpIAdd %16 %42 %36
%44 = OpAccessChain %25 %19 %21
-OpStore %44 %43
+OpStore %44 %51
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
-%39 = OpIMul %16 %38 %36
+%50 = OpISub %16 %38 %36
%40 = OpAccessChain %25 %19 %21
-OpStore %40 %39
+OpStore %40 %50
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpISub %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpIAdd %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
-%46 = OpFunctionCall %2 %8
+%46 = OpFunctionCall %2 %10
-%47 = OpFunctionCall %2 %10
+%47 = OpFunctionCall %2 %8
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
TEST(DiffTest, SmallFunctionsSmallDiffsDumpIds) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 50
+; Bound: 54
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %10 "f3("
OpName %12 "f4("
OpName %14 "f5("
OpName %17 "BufferOut"
OpMemberName %17 0 "o"
OpName %19 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i"
OpName %24 ""
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
-%43 = OpUDiv %16 %42 %36
+%53 = OpIAdd %16 %42 %36
%44 = OpAccessChain %25 %19 %21
-OpStore %44 %43
+OpStore %44 %53
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
-%39 = OpIMul %16 %38 %36
+%52 = OpISub %16 %38 %36
%40 = OpAccessChain %25 %19 %21
-OpStore %40 %39
+OpStore %40 %52
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
-%35 = OpISub %16 %34 %31
+%51 = OpIAdd %16 %34 %31
-OpStore %33 %35
+OpStore %33 %51
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
-%32 = OpIAdd %16 %30 %31
+%50 = OpISub %16 %30 %31
-OpStore %29 %32
+OpStore %29 %50
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
Src -> Dst
1 -> 1 [ExtInstImport]
2 -> 2 [TypeVoid]
3 -> 3 [TypeFunction]
4 -> 4 [Function]
5 -> 5 [Label]
6 -> 6 [Function]
7 -> 7 [Label]
8 -> 8 [Function]
9 -> 9 [Label]
10 -> 10 [Function]
11 -> 11 [Label]
12 -> 12 [Function]
13 -> 13 [Label]
14 -> 14 [Function]
15 -> 15 [Label]
16 -> 16 [TypeInt]
17 -> 17 [TypeStruct]
18 -> 18 [TypePointer]
19 -> 19 [Variable]
20 -> 20 [TypeInt]
21 -> 21 [Constant]
22 -> 22 [TypeStruct]
23 -> 23 [TypePointer]
24 -> 24 [Variable]
25 -> 25 [TypePointer]
26 -> 26 [AccessChain]
27 -> 27 [Load]
28 -> 28 [AccessChain]
29 -> 29 [AccessChain]
30 -> 30 [Load]
31 -> 31 [Constant]
32 -> 50 [IAdd]
33 -> 33 [AccessChain]
34 -> 34 [Load]
35 -> 51 [ISub]
36 -> 36 [Constant]
37 -> 37 [AccessChain]
38 -> 38 [Load]
39 -> 52 [IMul]
40 -> 40 [AccessChain]
41 -> 41 [AccessChain]
42 -> 42 [Load]
43 -> 53 [UDiv]
44 -> 44 [AccessChain]
45 -> 45 [FunctionCall]
46 -> 46 [FunctionCall]
47 -> 47 [FunctionCall]
48 -> 48 [FunctionCall]
49 -> 49 [FunctionCall]
)";
Options options;
options.dump_id_map = true;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,92 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %10 "f3("
OpName %12 "f4("
OpName %14 "f5("
OpName %17 "BufferOut"
OpMemberName %17 0 "o"
OpName %19 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i"
OpName %24 ""
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
%43 = OpIAdd %16 %42 %36
%44 = OpAccessChain %25 %19 %21
OpStore %44 %43
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpISub %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpIAdd %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
%39 = OpISub %16 %38 %36
%40 = OpAccessChain %25 %19 %21
OpStore %40 %39
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,93 @@
;; Test where src and dst have many small functions with small differences.
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 310
OpName %4 "main"
OpName %6 "f1("
OpName %8 "f2("
OpName %10 "f3("
OpName %12 "f4("
OpName %14 "f5("
OpName %17 "BufferOut"
OpMemberName %17 0 "o"
OpName %19 ""
OpName %22 "BufferIn"
OpMemberName %22 0 "i"
OpName %24 ""
OpMemberDecorate %17 0 Offset 0
OpDecorate %17 BufferBlock
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%16 = OpTypeInt 32 0
%17 = OpTypeStruct %16
%18 = OpTypePointer Uniform %17
%19 = OpVariable %18 Uniform
%20 = OpTypeInt 32 1
%21 = OpConstant %20 0
%22 = OpTypeStruct %16
%23 = OpTypePointer Uniform %22
%24 = OpVariable %23 Uniform
%25 = OpTypePointer Uniform %16
%31 = OpConstant %20 1
%36 = OpConstant %16 2
%4 = OpFunction %2 None %3
%5 = OpLabel
%45 = OpFunctionCall %2 %6
%46 = OpFunctionCall %2 %8
%47 = OpFunctionCall %2 %10
%48 = OpFunctionCall %2 %12
%49 = OpFunctionCall %2 %14
OpReturn
OpFunctionEnd
%6 = OpFunction %2 None %3
%7 = OpLabel
%26 = OpAccessChain %25 %24 %21
%27 = OpLoad %16 %26
%28 = OpAccessChain %25 %19 %21
OpStore %28 %27
OpReturn
OpFunctionEnd
%8 = OpFunction %2 None %3
%9 = OpLabel
%29 = OpAccessChain %25 %19 %21
%30 = OpLoad %16 %29
%32 = OpIAdd %16 %30 %31
OpStore %29 %32
OpReturn
OpFunctionEnd
%10 = OpFunction %2 None %3
%11 = OpLabel
%33 = OpAccessChain %25 %19 %21
%34 = OpLoad %16 %33
%35 = OpISub %16 %34 %31
OpStore %33 %35
OpReturn
OpFunctionEnd
%12 = OpFunction %2 None %3
%13 = OpLabel
%37 = OpAccessChain %25 %19 %21
%38 = OpLoad %16 %37
%39 = OpIMul %16 %38 %36
%40 = OpAccessChain %25 %19 %21
OpStore %40 %39
OpReturn
OpFunctionEnd
%14 = OpFunction %2 None %3
%15 = OpLabel
%41 = OpAccessChain %25 %19 %21
%42 = OpLoad %16 %41
%43 = OpUDiv %16 %42 %36
%44 = OpAccessChain %25 %19 %21
OpStore %44 %43
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,230 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_tests.py
//
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../diff_test_utils.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
// Tests diff of unrelated shaders (with different execution models).
constexpr char kSrc[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %8 %10
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %10 "a"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%8 = OpVariable %7 Output
%9 = OpTypePointer Input %6
%10 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
)";
constexpr char kDst[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
TEST(DiffTest, UnrelatedShaders) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 12
+; Bound: 16
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %4 "main" %8 %10
+OpEntryPoint Fragment %4 "main" %14 %8
+OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
+OpName %14 "color"
OpName %8 "v"
-OpName %10 "a"
+OpDecorate %14 RelaxedPrecision
+OpDecorate %14 Location 0
+OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
-OpDecorate %10 Location 0
+OpDecorate %11 RelaxedPrecision
+OpDecorate %15 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
-%7 = OpTypePointer Output %6
+%12 = OpTypeVector %6 4
+%13 = OpTypePointer Output %12
+%14 = OpVariable %13 Output
-%8 = OpVariable %7 Output
+%8 = OpVariable %9 Input
%9 = OpTypePointer Input %6
-%10 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
-%11 = OpLoad %6 %10
+%11 = OpLoad %6 %8
-OpStore %8 %11
+%15 = OpCompositeConstruct %12 %11 %11 %11 %11
+OpStore %14 %15
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrc, kDst, kDiff, options);
}
TEST(DiffTest, UnrelatedShadersNoDebug) {
constexpr char kSrcNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %8 %10
OpSource ESSL 310
OpDecorate %8 Location 0
OpDecorate %10 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%8 = OpVariable %7 Output
%9 = OpTypePointer Input %6
%10 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd
)";
constexpr char kDstNoDebug[] = R"( OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd
)";
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 12
+; Bound: 15
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-OpEntryPoint Vertex %4 "main" %8 %10
+OpEntryPoint Fragment %4 "main" %8 %10
+OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
+OpDecorate %8 RelaxedPrecision
OpDecorate %8 Location 0
+OpDecorate %10 RelaxedPrecision
OpDecorate %10 Location 0
+OpDecorate %11 RelaxedPrecision
+OpDecorate %14 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
-%7 = OpTypePointer Output %6
+%12 = OpTypeVector %6 4
+%13 = OpTypePointer Output %12
-%8 = OpVariable %7 Output
+%8 = OpVariable %13 Output
%9 = OpTypePointer Input %6
%10 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
+%14 = OpCompositeConstruct %12 %11 %11 %11 %11
-OpStore %8 %11
+OpStore %8 %14
OpReturn
OpFunctionEnd
)";
Options options;
DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,31 @@
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %9 %11
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %9 "color"
OpName %11 "v"
OpDecorate %9 RelaxedPrecision
OpDecorate %9 Location 0
OpDecorate %11 RelaxedPrecision
OpDecorate %11 Location 0
OpDecorate %12 RelaxedPrecision
OpDecorate %13 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Output %7
%9 = OpVariable %8 Output
%10 = OpTypePointer Input %6
%11 = OpVariable %10 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpLoad %6 %11
%13 = OpCompositeConstruct %7 %12 %12 %12 %12
OpStore %9 %13
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,25 @@
;; Tests diff of unrelated shaders (with different execution models).
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %8 %10
OpSource ESSL 310
OpName %4 "main"
OpName %8 "v"
OpName %10 "a"
OpDecorate %8 Location 0
OpDecorate %10 Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypePointer Output %6
%8 = OpVariable %7 Output
%9 = OpTypePointer Input %6
%10 = OpVariable %9 Input
%4 = OpFunction %2 None %3
%5 = OpLabel
%11 = OpLoad %6 %10
OpStore %8 %11
OpReturn
OpFunctionEnd

228
test/diff/diff_test.cpp Normal file
View File

@ -0,0 +1,228 @@
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/diff/diff.h"
#include "diff_test_utils.h"
#include "source/opt/build_module.h"
#include "source/opt/ir_context.h"
#include "source/spirv_constant.h"
#include "spirv-tools/libspirv.hpp"
#include "tools/io.h"
#include "tools/util/cli_consumer.h"
#include <fstream>
#include <string>
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;
std::unique_ptr<spvtools::opt::IRContext> Assemble(const std::string& spirv) {
spvtools::SpirvTools t(kDefaultEnvironment);
t.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
std::vector<uint32_t> binary;
if (!t.Assemble(spirv, &binary,
spvtools::SpirvTools::kDefaultAssembleOption |
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS))
return nullptr;
return spvtools::BuildModule(kDefaultEnvironment,
spvtools::utils::CLIMessageConsumer,
binary.data(), binary.size());
}
TEST(DiffIndentTest, Diff) {
const std::string src = R"(OpCapability Shader
%ext_inst = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%func = OpTypeFunction %void
%main = OpFunction %void None %func
%main_entry = OpLabel
OpReturn
OpFunctionEnd;)";
const std::string dst = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%func = OpTypeFunction %void
%main = OpFunction %void None %func
%main_entry = OpLabel
OpReturn
OpFunctionEnd;)";
const std::string diff = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 6
; Schema: 0
OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
OpExecutionMode %2 OriginUpperLeft
%3 = OpTypeVoid
%4 = OpTypeFunction %3
%2 = OpFunction %3 None %4
%5 = OpLabel
OpReturn
OpFunctionEnd
)";
Options options;
options.indent = true;
DoStringDiffTest(src, dst, diff, options);
}
TEST(DiffNoHeaderTest, Diff) {
const std::string src = R"(OpCapability Shader
%ext_inst = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%func = OpTypeFunction %void
%main = OpFunction %void None %func
%main_entry = OpLabel
OpReturn
OpFunctionEnd;)";
const std::string dst = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%func = OpTypeFunction %void
%main = OpFunction %void None %func
%main_entry = OpLabel
OpReturn
OpFunctionEnd;)";
const std::string diff = R"( OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
OpExecutionMode %2 OriginUpperLeft
%3 = OpTypeVoid
%4 = OpTypeFunction %3
%2 = OpFunction %3 None %4
%5 = OpLabel
OpReturn
OpFunctionEnd
)";
Options options;
options.no_header = true;
DoStringDiffTest(src, dst, diff, options);
}
TEST(DiffHeaderTest, Diff) {
const std::string src_spirv = R"(OpCapability Shader
%ext_inst = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%func = OpTypeFunction %void
%main = OpFunction %void None %func
%main_entry = OpLabel
OpReturn
OpFunctionEnd;)";
const std::string dst_spirv = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%func = OpTypeFunction %void
%main = OpFunction %void None %func
%main_entry = OpLabel
OpReturn
OpFunctionEnd;)";
const std::string diff = R"( ; SPIR-V
-; Version: 1.3
+; Version: 1.2
-; Generator: Khronos SPIR-V Tools Assembler; 3
+; Generator: Khronos Glslang Reference Front End; 10
; Bound: 6
; Schema: 0
OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
OpExecutionMode %2 OriginUpperLeft
%3 = OpTypeVoid
%4 = OpTypeFunction %3
%2 = OpFunction %3 None %4
%5 = OpLabel
OpReturn
OpFunctionEnd
)";
// Load the src and dst modules
std::unique_ptr<spvtools::opt::IRContext> src = Assemble(src_spirv);
ASSERT_TRUE(src);
std::unique_ptr<spvtools::opt::IRContext> dst = Assemble(dst_spirv);
ASSERT_TRUE(dst);
// Differentiate them in the header.
const spvtools::opt::ModuleHeader src_header = {
SpvMagicNumber,
SPV_SPIRV_VERSION_WORD(1, 3),
SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 3),
src->module()->IdBound(),
src->module()->schema(),
};
const spvtools::opt::ModuleHeader dst_header = {
SpvMagicNumber,
SPV_SPIRV_VERSION_WORD(1, 2),
SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_GLSLANG, 10),
dst->module()->IdBound(),
dst->module()->schema(),
};
src->module()->SetHeader(src_header);
dst->module()->SetHeader(dst_header);
// Take the diff
Options options;
std::ostringstream diff_result;
spv_result_t result =
spvtools::diff::Diff(src.get(), dst.get(), diff_result, options);
ASSERT_EQ(result, SPV_SUCCESS);
// Expect they match
EXPECT_EQ(diff_result.str(), diff);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,58 @@
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "diff_test_utils.h"
#include "source/opt/build_module.h"
#include "source/opt/ir_context.h"
#include "spirv-tools/libspirv.hpp"
#include "tools/io.h"
#include "tools/util/cli_consumer.h"
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
static constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;
void DoStringDiffTest(const std::string& src_spirv,
const std::string& dst_spirv,
const std::string& expected_diff, Options options) {
// Load the src and dst modules
std::unique_ptr<spvtools::opt::IRContext> src = spvtools::BuildModule(
kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, src_spirv,
spvtools::SpirvTools::kDefaultAssembleOption |
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
ASSERT_TRUE(src);
std::unique_ptr<spvtools::opt::IRContext> dst = spvtools::BuildModule(
kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, dst_spirv,
spvtools::SpirvTools::kDefaultAssembleOption |
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
ASSERT_TRUE(dst);
// Take the diff
std::ostringstream diff_result;
spv_result_t result =
spvtools::diff::Diff(src.get(), dst.get(), diff_result, options);
ASSERT_EQ(result, SPV_SUCCESS);
// Expect they match
EXPECT_EQ(diff_result.str(), expected_diff);
}
} // namespace diff
} // namespace spvtools

View File

@ -0,0 +1,30 @@
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef TEST_DIFF_DIFF_TEST_UTILS_H_
#define TEST_DIFF_DIFF_TEST_UTILS_H_
#include "source/diff/diff.h"
namespace spvtools {
namespace diff {
void DoStringDiffTest(const std::string& src_spirv,
const std::string& dst_spirv,
const std::string& expected_diff, Options options);
} // namespace diff
} // namespace spvtools
#endif // TEST_DIFF_DIFF_TEST_UTILS_H_

329
test/diff/lcs_test.cpp Normal file
View File

@ -0,0 +1,329 @@
// Copyright (c) 2022 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/diff/lcs.h"
#include <string>
#include "gtest/gtest.h"
namespace spvtools {
namespace diff {
namespace {
using Sequence = std::vector<int>;
using LCS = LongestCommonSubsequence<Sequence>;
void VerifyMatch(const Sequence& src, const Sequence& dst,
size_t expected_match_count) {
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
EXPECT_EQ(match_count, expected_match_count);
size_t src_cur = 0;
size_t dst_cur = 0;
size_t matches_seen = 0;
while (src_cur < src.size() && dst_cur < dst.size()) {
if (src_match[src_cur] && dst_match[dst_cur]) {
EXPECT_EQ(src[src_cur], dst[dst_cur])
<< "Src: " << src_cur << " Dst: " << dst_cur;
++src_cur;
++dst_cur;
++matches_seen;
continue;
}
if (!src_match[src_cur]) {
++src_cur;
}
if (!dst_match[dst_cur]) {
++dst_cur;
}
}
EXPECT_EQ(matches_seen, expected_match_count);
}
TEST(LCSTest, EmptySequences) {
Sequence src, dst;
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
EXPECT_EQ(match_count, 0u);
EXPECT_TRUE(src_match.empty());
EXPECT_TRUE(dst_match.empty());
}
TEST(LCSTest, EmptySrc) {
Sequence src, dst = {1, 2, 3};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
EXPECT_EQ(match_count, 0u);
EXPECT_TRUE(src_match.empty());
EXPECT_EQ(dst_match, DiffMatch(3, false));
}
TEST(LCSTest, EmptyDst) {
Sequence src = {1, 2, 3}, dst;
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
EXPECT_EQ(match_count, 0u);
EXPECT_EQ(src_match, DiffMatch(3, false));
EXPECT_TRUE(dst_match.empty());
}
TEST(LCSTest, Identical) {
Sequence src = {1, 2, 3, 4, 5, 6}, dst = {1, 2, 3, 4, 5, 6};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
EXPECT_EQ(match_count, 6u);
EXPECT_EQ(src_match, DiffMatch(6, true));
EXPECT_EQ(dst_match, DiffMatch(6, true));
}
TEST(LCSTest, SrcPrefix) {
Sequence src = {1, 2, 3, 4}, dst = {1, 2, 3, 4, 5, 6};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
const DiffMatch src_expect = {true, true, true, true};
const DiffMatch dst_expect = {true, true, true, true, false, false};
EXPECT_EQ(match_count, 4u);
EXPECT_EQ(src_match, src_expect);
EXPECT_EQ(dst_match, dst_expect);
}
TEST(LCSTest, DstPrefix) {
Sequence src = {1, 2, 3, 4, 5, 6}, dst = {1, 2, 3, 4, 5};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
const DiffMatch src_expect = {true, true, true, true, true, false};
const DiffMatch dst_expect = {true, true, true, true, true};
EXPECT_EQ(match_count, 5u);
EXPECT_EQ(src_match, src_expect);
EXPECT_EQ(dst_match, dst_expect);
}
TEST(LCSTest, SrcSuffix) {
Sequence src = {3, 4, 5, 6}, dst = {1, 2, 3, 4, 5, 6};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
const DiffMatch src_expect = {true, true, true, true};
const DiffMatch dst_expect = {false, false, true, true, true, true};
EXPECT_EQ(match_count, 4u);
EXPECT_EQ(src_match, src_expect);
EXPECT_EQ(dst_match, dst_expect);
}
TEST(LCSTest, DstSuffix) {
Sequence src = {1, 2, 3, 4, 5, 6}, dst = {5, 6};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
const DiffMatch src_expect = {false, false, false, false, true, true};
const DiffMatch dst_expect = {true, true};
EXPECT_EQ(match_count, 2u);
EXPECT_EQ(src_match, src_expect);
EXPECT_EQ(dst_match, dst_expect);
}
TEST(LCSTest, None) {
Sequence src = {1, 3, 5, 7, 9}, dst = {2, 4, 6, 8, 10, 12};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
EXPECT_EQ(match_count, 0u);
EXPECT_EQ(src_match, DiffMatch(5, false));
EXPECT_EQ(dst_match, DiffMatch(6, false));
}
TEST(LCSTest, NonContiguous) {
Sequence src = {1, 2, 3, 4, 5, 6, 10}, dst = {2, 4, 5, 8, 9, 10, 12};
DiffMatch src_match, dst_match;
LCS lcs(src, dst);
size_t match_count =
lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
const DiffMatch src_expect = {false, true, false, true, true, false, true};
const DiffMatch dst_expect = {true, true, true, false, false, true, false};
EXPECT_EQ(match_count, 4u);
EXPECT_EQ(src_match, src_expect);
EXPECT_EQ(dst_match, dst_expect);
}
TEST(LCSTest, WithDuplicates) {
Sequence src = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4},
dst = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
VerifyMatch(src, dst, 6);
}
const std::string large_lcs_src_str =
"GUJwrJSlkKJXxCVIAxlVgnUyOrdyRyFtlZwWMmFhYGfkFTNnhiBmClgHyrcXMVwfrRxNUfQk"
"qaoGvCbPZHAzXsaZpXHPfJxOMCUtRDmIQpfiXKbHQbhTfPqhxBDWvmTQAqwsWTLajZYtMUnf"
"hNNCfkuAXkZsaebwEbIZOxTDZsqSMUfCMoGeKJGVSNFgLTiBMbdvchHGfFRkHKcYCDjBfIcj"
"todPnvDjzQYWBcvIfVvyBzHikrwpDORaGEZLhmyztIFCLJOqeLhOzERYmVqzlsoUzruTXTXq"
"DLTxQRakOCMRrgRzCDTXfwwfDcKMBVnxRZemjcwcEsOVxwtwdBCWJycsDcZKlvrCvZaenKlv"
"vyByDQeLdxAyBnPkIMQlMQwqjUfRLybeoaOanlbFkpTPPZdHelQrIvucTHzMpWWQTbuANwvN"
"OVhCGGoIcGNDpfIsaBexlMMdHsxMGerTngmjpdPeQQJHfvKZkdYqAzrtDohqtDsaFMxQViVQ"
"YszDVgyoSHZdOXAvXkJidojLvGZOzhRajVPhWDwKuGqdaympELxHsrXAJYufdCPwJdGJfWqq"
"yvTWpcrFHOIuCEmNLnSCDsxQGRVDwyCykBJazhApfCnrOadnafvqfVuFqEXMSrYbHTfTnzbz"
"MhISyOtMUITaurCXvanCbuOXBhHyCjOhVbxnMvhlPmZBMQgEHCghtAJVMXGPNRtszVZlPxVl"
"QIPTBnPUPejlyZGPqeICyNngdQGkvKbIoWlTLBtVhMdBeUMozNlKQTIPYBeImVcMdLafuxUf"
"TIXysmcTrUTcspOSKBxhdhLwiRnREGFWJTfUKsgGOAQeYojXdrqsGjMJfiKalyoiqrgLnlij"
"CtOapoxDGVOOBalNYGzCtBlxbvaAzxipGnJpOEbmXcpeoIsAdxspKBzBDgoPVxnuRBUwmTSr"
"CRpWhxikgUYQVCwalLUIeBPRyhhsECGCXJmGDZSCIUaBwROkigzdeVPOXhgCGBEprWtNdYfL"
"tOUYJHQXxiIJgSGmWntezJFpNQoTPbRRYAGhtYvAechvBcYWocLkYFxsDAuszvQNLXdhmAHw"
"DErcjbtCdQllnKcDADVNWVezljjLrAuyGHetINMgAvJZwOEYakihYVUbZGCsHEufluLNyNHy"
"gqtSTSFFjBHiIqQejTPWybLdpWNwZrWvIWnlzUcGNQPEYHVPCbteWknjAnWrdTBeCbHUDBoK"
"aHvDStmpNRGIjvlumiZTbdZNAzUeSFnFChCsSExwXeEfDJfjyOoSBofHzJqJErvHLNyUJTjX"
"qmtgKPpMKohUPBMhtCteQFcNEpWrUVGbibMOpvBwdiWYXNissArpSasVJFgDzrqTyGkerTMX"
"gcrzFUGFZRhNdekaJeKYPogsofJaRsUQmIRyYdkrxKeMgLPpwOfSKJOqzXDoeHljTzhOwEVy"
"krOEnACFrWhufajsMitjOWdLOHHchQDddGPzxknEgdwmZepKDvRZGCuPqzeQkjOPqUBKpKLJ"
"eKieSsRXkaqxSPGajfvPKmwFWdLByEcLgvrmteazgFjmMGrLYqRRxzUOfOCokenqHVYstBHf"
"AwsWsqPTvqsRJUfGGTaYiylZMGbQqTzINhFHvdlRQvvYKBcuAHdBeKlHSxVrSsEKbcAvnIcf"
"xzdVDdwQPHMCHeZZRpGHWvKzgTGzSTbYTeOPyKvvYWmQToTpsjAtKUJUjcEHWhmdBLDTBMHJ"
"ivBXcLGtCsumNNVFyGbVviGmqHTdyBlkneibXBesKJGOUzOtIwXCPJggqBekSzNQYkALlItk"
"cbEhbdXAIKVHYpInLwxXalKZrkrpxtfuagqMGmRJnJbFQaEoYMoqPsxZpocddPXXPyvxVkaF"
"qdKISejWDhBImnEEOPDcyWTubbfVfwUztciaFJcsPLhgYVfhqlOfoNjKbmTFptFttYuyBrUI"
"zzmZypOqrjQHTGFwlHStpIwxPtMvtsEDpsmWIgwzYgwmdpbMOnfElZMYpVIcvzSWejeJcdUB"
"QUoBRUmGQVVWvEDseuozrDjgdXFScPwwsgaUPwSzScfBNrkpmEFDSZLKfNjMqvOmUtocUkbo"
"VGFEKgGLbNruwLgXHTloWDrnqymPVAtzjWPutonIsMDPeeCmTjYWAFXcyTAlBeiJTIRkZxiM"
"kLjMnAflSNJzmZkatXkYiPEMYSmzHbLKEizHbEjQOxBDzpRHiFjhedqiyMiUMvThjaRFmwll"
"aMGgwKBIKepwyoEdnuhtzJzboiNEAFKiqiWxxmkRFRoTiFWXLPAWLuzSCrajgkQhDxAQDqyM"
"VwZlhZicQLEDYYisEalesDWZAYzcvENuHUwRutIsGgsdoYwOZiURhcgdbTGWBNqhrFjvTQCj"
"VlTPNlRdRLaaqzUBBwbdtyXFkCBUYYMbmRrkFxfxbCqkgZNGyHPKLkOPnezfVTRmRQgCgHbx"
"wcZlInVOwmFePnSIbThMJosimzkhfuiqYEpwHQiemqsSDNNdbNhBLzbsPZBJZujSHJGtYKGb"
"HaAYGJZxBumsKUrATwPuqXFLfwNyImLQbchBKiJAYRZhkcrKCHXBEGYyBhBGvSqvabcRUrfq"
"AbPiMzjHAehGYjDEmxAnYLyoSFdeWVrfJUCuYZPluhXEBuyUpKaRXDKXeiCvGidpvATwMbcz"
"DZpzxrhTZYyrFORFQWTbPLCBjMKMhlRMFEiarDgGPttjmkrQVlujztMSkxXffXFNqLWOLThI"
"KBoyMHoFTEPCdUAZjLTifAdjjUehyDLEGKlRTFoLpjalziRSUjZfRYbNzhiHgTHowMMkKTwE"
"ZgnqiirMtnNpaBJqhcIVrWXPpcPWZfRpsPstHleFJDZYAsxYhOREVbFtebXTZRAIjGgWeoiN"
"qPLCCAVadqmUrjOcqIbdCTpcDRWuDVbHrZOQRPhqbyvOWwxAWJphjLiDgoAybcjzgfVktPlj"
"kNBCjelpuQfnYsiTgPpCNKYtOrxGaLEEtAuLdGdDsONHNhSn";
const std::string large_lcs_dst_str =
"KzitfifORCbGhfNEbnbObUdFLLaAsLOpMkOeKupjCoatzqfHBkNJfSgqSMYouswfNMnoQngK"
"jWwyPKmEnoZWyPBUdQRmKUNudUclueKXKQefUdXWUyyqtumzsFKznrLVLwfvPZpLChNYrrHK"
"AtpfOuVHiUKyeRCrktJAhkyFKmPWrASEMvBLNOzuGlvinZjvZUUXazNEkyMPiOLdqXvCIroC"
"MeWsvjHShlLhDwLZrVlpYBnDJmILcsNFDSoaLWOKNNkNGBgNBvVjPCJXAuKfsrKZhYcdEpxK"
"UihiRkYvMiLyOUvaqBMklLDwEhvQBfCXHSRoqsLsSCzLZQhIYMhBapvHaPbDoRrHoJXZsNXc"
"rxZYCrOMIzYcVPwDCFiHBFnPNTTeAeKEMGeVUeCaAeuWZmngyPWlQBcgWumSUIfbhjVYdnpV"
"hRSJXrIoFZubBXfNOMhilAkVPixrhILZKgDoFTvytPFPfBLMnbhSOBmLWCbJsLQxrCrMAlOw"
"RmfSQyGhrjhzYVqFSBHeoQBagFwyxIjcHFZngntpVHbSwqhwHeMnWSsISPljTxSNXfCxLebW"
"GhMdlphtJbdvhEcjNpwPCFqhdquxCyOxkjsDUPNgjpDcpIMhMwMclNhfESTrroJaoyeGQclV"
"gonnhuQRmXcBwcsWeLqjNngZOlyMyfeQBwnwMVJEvGqknDyzSApniRTPgJpFoDkJJhXQFuFB"
"VqhuEPMRGCeTDOSEFmXeIHOnDxaJacvnmORwVpmrRhGjDpUCkuODNPdZMdupYExDEDnDLdNF"
"iObKBaVWpGVMKdgNLgsNxcpypBPPKKoaajeSGPZQJWSOKrkLjiFexYVmUGxJnbTNsCXXLfZp"
"jfxQAEVYvqKehBzMsVHVGWmTshWFAoCNDkNppzzjHBZWckrzSTANICioCJSpLwPwQvtXVxst"
"nTRBAboPFREEUFazibpFesCsjzUOnECwoPCOFiwGORlIZVLpUkJyhYXCENmzTBLVigOFuCWO"
"IiXBYmiMtsxnUdoqSTTGyEFFrQsNAjcDdOKDtHwlANWoUVwiJCMCQFILdGqzEePuSXFbOEOz"
"dLlEnTJbKRSTfAFToOZNtDXTfFgvQiefAKbSUWUXFcpCjRYCBNXCCcLMjjuUDXErpiNsRuIx"
"mgHsrObTEXcnmjdqxTGhTjTeYizNnkrJRhNQIqDXmZMwArBccnixpcuiGOOexjgkpcEyGAnz"
"UbgiBfflTUyJfZeFFLrZVueFkSRosebnnwAnakIrywTGByhQKWvmNQJsWQezqLhHQzXnEpeD"
"rFRTSQSpVxPzSeEzfWYzfpcenxsUyzOMLxhNEhfcuprDtqubsXehuqKqZlLQeSclvoGjuKJK"
"XoWrazsgjXXnkWHdqFESZdMGDYldyYdbpSZcgBPgEKLWZHfBirNPLUadmajYkiEzmGuWGELB"
"WLiSrMdaGSbptKmgYVqMGcQaaATStiZYteGAPxSEBHuAzzjlRHYsrdDkaGNXmzRGoalJMiCC"
"GMtWSDMhgvRSEgKnywbRgnqWXFlwrhXbbvcgLGtWSuKQBiqIlWkfPMozOTWgVoLHavDJGRYI"
"YerrmZnTMtuuxmZALWakfzUbksTwoetqkOiRPGqGZepcVXHoZyOaaaijjZWQLlIhYwiQNbfc"
"KCwhhFaMQBoaCnOecJEdKzdsMPFEYQuJNPYiiNtsYxaWBRuWjlLqGokHMNtyTQfSJKbgGdol"
"fWlOZdupouQMfUWXIYHzyJHefMDnqxxasDxtgArvDqtwjDBaVEMACPkLFpiDOoKCHqkWVizh"
"lKqbOHpsPKkhjRQRNGYRYEfxtBjYvlCvHBNUwVuIwDJYMqHxEFtwdLqYWvjdOfQmNiviDfUq"
"pbucbNwjNQfMYgwUuPnQWIPOlqHcbjtuDXvTzLtkdBQanJbrmLSyFqSapZCSPMDOrxWVYzyO"
"lwDTTJFmKxoyfPunadkHcrcSQaQsAbrQtbhqwSTXGTPURYTCbNozjAVwbmcyVxIbZudBZWYm"
"rnSDyelGCRRWYtrUxvOVWlTLHHdYuAmVMGnGbHscbjmjmAzmYLaCxNNwhmMYdExKvySxuYpE"
"rVGwfqMngBCHnZodotNaNJZiNRFWubuPDfiywXPiyVWoQMeOlSuWmpilLTIFOvfpjmJTgrWa"
"dgoxYeyPyOaglOvZVGdFOBSeqEcGXBwjoeUAXqkpvOxEpSXhmklKZydTvRVYVvfQdRNNDkCT"
"dLNfcZCFQbZORdcDOhwotoyccrSbWvlqYMoiAYeEpDzZTvkamapzZMmCpEutZFCcHBWGIIkr"
"urwDNHrobaErPpclyEegLJDtkfUWSNWZosWSbBGAHIvJsFNUlJXbnkSVycLkOVQVcNcUtiBy"
"djLDIFsycbPBEWaMvCbntNtJlOeCttvXypGnHAQFnFSiXFWWqonWuVIKmVPpKXuJtFguXCWC"
"rNExYYvxLGEmuZJLJDjHgjlQyOzeieCpizJxkrdqKCgomyEkvsyVYSsLeyLvOZQrrgEJgRFK"
"CjYtoOfluNrLdRMTRkQXmAiMRFwloYECpXCReAMxOkNiwCtutsrqWoMHsrogRqPoUCueonvW"
"MTwmkAkajfGJkhnQidwpwIMEttQkzIMOPvvyWZHpqkMHWlNTeSKibfRfwDyxveKENZhtlPwP"
"dfAjwegjRcavtFnkkTNVYdCdCrgdUvzsIcqmUjwGmVvuuQvjVrWWIDBmAzQtiZPYvCOEWjce"
"rWzeqVKeiYTJBOedmQCVidOgUIEjfRnbGvUbctYxfRybJkdmeAkLZQMRMGPOnsPbFswXAoCK"
"IxWGwohoPpEJxslbqHFKSwknxTmrDCITRZWEDkGQeucPxHBdYkduwbYhKnoxCKhgjBFiFawC"
"QtgTDldTQmlOsBiGLquMjuecAbrUJJvNtXbFNGjWxaZPimSRXUJWgRbydpsczOqSFIeEtuKA"
"ZpRhmLtPdVNKdSDQZeeImUFmUwXApRTUNHItyvFyJtNtn";
TEST(LCSTest, Large) {
Sequence src;
Sequence dst;
src.reserve(large_lcs_src_str.length());
dst.reserve(large_lcs_dst_str.length());
for (char c : large_lcs_src_str) {
src.push_back(c);
}
for (char c : large_lcs_dst_str) {
dst.push_back(c);
}
VerifyMatch(src, dst, 723);
}
} // namespace
} // namespace diff
} // namespace spvtools

View File

@ -41,6 +41,7 @@ endfunction()
if (NOT ${SPIRV_SKIP_EXECUTABLES})
add_spvtools_tool(TARGET spirv-as SRCS as/as.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-diff SRCS diff/diff.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-dis SRCS dis/dis.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-val SRCS val/val.cpp util/cli_consumer.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-opt SRCS opt/opt.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})

201
tools/diff/diff.cpp Normal file
View File

@ -0,0 +1,201 @@
// Copyright (c) 2022 The Khronos Group Inc.
//
// 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.
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#include "source/diff/diff.h"
#include "source/opt/build_module.h"
#include "source/opt/ir_context.h"
#include "spirv-tools/libspirv.hpp"
#include "tools/io.h"
#include "tools/util/cli_consumer.h"
static void print_usage(char* argv0) {
printf(R"(%s - Compare two SPIR-V files
Usage: %s <src_filename> <dst_filename>
The SPIR-V binary is read from <src_filename> and <dst_filename>. If either
file ends in .spvasm, the SPIR-V is read as text and disassembled.
The contents of the SPIR-V modules are analyzed and a diff is produced showing a
logical transformation from src to dst, in src's id-space.
-h, --help Print this help.
--version Display diff version information.
--color Force color output. The default when printing to a terminal.
Overrides a previous --no-color option.
--no-color Don't print in color. Overrides a previous --color option.
The default when output goes to something other than a
terminal (e.g. a pipe, or a shell redirection).
--no-indent Don't indent instructions.
--no-header Don't output the header as leading comments.
--with-id-map Also output the mapping between src and dst outputs.
--ignore-set-binding
Don't use set/binding decorations for variable matching.
--ignore-location
Don't use location decorations for variable matching.
)",
argv0, argv0);
}
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;
static bool is_assembly(const char* path) {
const char* suffix = strrchr(path, '.');
if (suffix == nullptr) {
return false;
}
return strcmp(suffix, ".spvasm") == 0;
}
static std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) {
if (is_assembly(path)) {
std::vector<char> contents;
if (!ReadTextFile<char>(path, &contents)) return {};
return spvtools::BuildModule(
kDefaultEnvironment, spvtools::utils::CLIMessageConsumer,
std::string(contents.begin(), contents.end()),
spvtools::SpirvTools::kDefaultAssembleOption |
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
}
std::vector<uint32_t> contents;
if (!ReadBinaryFile<uint32_t>(path, &contents)) return {};
return spvtools::BuildModule(kDefaultEnvironment,
spvtools::utils::CLIMessageConsumer,
contents.data(), contents.size());
}
int main(int argc, char** argv) {
const char* src_file = nullptr;
const char* dst_file = nullptr;
bool color_is_possible =
#if SPIRV_COLOR_TERMINAL
true;
#else
false;
#endif
bool force_color = false;
bool force_no_color = false;
bool allow_indent = true;
bool no_header = false;
bool dump_id_map = false;
bool ignore_set_binding = false;
bool ignore_location = false;
for (int argi = 1; argi < argc; ++argi) {
if ('-' == argv[argi][0]) {
switch (argv[argi][1]) {
case 'h':
print_usage(argv[0]);
return 0;
case '-': {
// Long options
if (strcmp(argv[argi], "--no-color") == 0) {
force_no_color = true;
force_color = false;
} else if (strcmp(argv[argi], "--color") == 0) {
force_no_color = false;
force_color = true;
} else if (strcmp(argv[argi], "--no-indent") == 0) {
allow_indent = false;
} else if (strcmp(argv[argi], "--no-header") == 0) {
no_header = true;
} else if (strcmp(argv[argi], "--with-id-map") == 0) {
dump_id_map = true;
} else if (strcmp(argv[argi], "--ignore-set-binding") == 0) {
ignore_set_binding = true;
} else if (strcmp(argv[argi], "--ignore-location") == 0) {
ignore_location = true;
} else if (strcmp(argv[argi], "--help") == 0) {
print_usage(argv[0]);
return 0;
} else if (strcmp(argv[argi], "--version") == 0) {
printf("%s\n", spvSoftwareVersionDetailsString());
printf("Target: %s\n",
spvTargetEnvDescription(kDefaultEnvironment));
return 0;
} else {
print_usage(argv[0]);
return 1;
}
} break;
default:
print_usage(argv[0]);
return 1;
}
} else {
if (src_file == nullptr) {
src_file = argv[argi];
} else if (dst_file == nullptr) {
dst_file = argv[argi];
} else {
fprintf(stderr, "error: More than two input files specified\n");
return 1;
}
}
}
if (src_file == nullptr || dst_file == nullptr) {
print_usage(argv[0]);
return 1;
}
spvtools::diff::Options options;
if (allow_indent) options.indent = true;
if (no_header) options.no_header = true;
if (dump_id_map) options.dump_id_map = true;
if (ignore_set_binding) options.ignore_set_binding = true;
if (ignore_location) options.ignore_location = true;
if (color_is_possible && !force_no_color) {
bool output_is_tty = true;
#if defined(_POSIX_VERSION)
output_is_tty = isatty(fileno(stdout));
#endif
if (output_is_tty || force_color) {
options.color_output = true;
}
}
std::unique_ptr<spvtools::opt::IRContext> src = load_module(src_file);
std::unique_ptr<spvtools::opt::IRContext> dst = load_module(dst_file);
if (!src) {
fprintf(stderr, "error: Loading src file\n");
}
if (!dst) {
fprintf(stderr, "error: Loading dst file\n");
}
if (!src || !dst) {
return 1;
}
spvtools::diff::Diff(src.get(), dst.get(), std::cout, options);
return 0;
}