Merge changes Id0d4524c,Ife5beff3
* changes:
Update SPIR-V Tools to 0741f4273
Squashed 'third_party/SPIRV-Tools/' changes from d18d0d92e..0741f4273
diff --git a/third_party/SPIRV-Tools/.gitignore b/third_party/SPIRV-Tools/.gitignore
index b2af56e..ec709ba 100644
--- a/third_party/SPIRV-Tools/.gitignore
+++ b/third_party/SPIRV-Tools/.gitignore
@@ -2,7 +2,7 @@
.ycm_extra_conf.py*
*.pyc
compile_commands.json
-/build/
+/build*/
/buildtools/
/external/googletest
/external/SPIRV-Headers
@@ -20,6 +20,7 @@
bazel-genfiles
bazel-out
bazel-spirv-tools
+bazel-SPIRV-Tools
bazel-testlogs
# Vim
diff --git a/third_party/SPIRV-Tools/BUILD.bazel b/third_party/SPIRV-Tools/BUILD.bazel
index b2031de..c86ebbe 100644
--- a/third_party/SPIRV-Tools/BUILD.bazel
+++ b/third_party/SPIRV-Tools/BUILD.bazel
@@ -81,6 +81,7 @@
srcs = ["@spirv_headers//:spirv_xml_registry"],
outs = ["generators.inc"],
cmd = "$(location generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)",
+ cmd_bat = "$(location //:generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)",
tools = [":generate_registry_tables"],
)
@@ -94,6 +95,7 @@
srcs = ["CHANGES"],
outs = ["build-version.inc"],
cmd = "SOURCE_DATE_EPOCH=0 $(location update_build_version) $$(dirname $(location CHANGES)) $(location build-version.inc)",
+ cmd_bat = "set SOURCE_DATE_EPOCH=0 && $(location //:update_build_version) \"$(location CHANGES)\\..\" $(location build-version.inc)",
tools = [":update_build_version"],
)
diff --git a/third_party/SPIRV-Tools/BUILD.gn b/third_party/SPIRV-Tools/BUILD.gn
index b2cc934..0f58884 100644
--- a/third_party/SPIRV-Tools/BUILD.gn
+++ b/third_party/SPIRV-Tools/BUILD.gn
@@ -716,6 +716,8 @@
"source/opt/register_pressure.h",
"source/opt/relax_float_ops_pass.cpp",
"source/opt/relax_float_ops_pass.h",
+ "source/opt/remove_dontinline_pass.cpp",
+ "source/opt/remove_dontinline_pass.h",
"source/opt/remove_duplicates_pass.cpp",
"source/opt/remove_duplicates_pass.h",
"source/opt/remove_unused_interface_variables_pass.cpp",
diff --git a/third_party/SPIRV-Tools/README.md b/third_party/SPIRV-Tools/README.md
index ad2af49..e951e37 100644
--- a/third_party/SPIRV-Tools/README.md
+++ b/third_party/SPIRV-Tools/README.md
@@ -417,7 +417,7 @@
- [Python 3](http://www.python.org/): for utility scripts and running the test
suite.
- [Bazel](https://bazel.build/) (optional): if building the source with Bazel,
-you need to install Bazel Version 0.29.1 on your machine. Other versions may
+you need to install Bazel Version 5.0.0 on your machine. Other versions may
also work, but are not verified.
- [Emscripten SDK](https://emscripten.org) (optional): if building the
WebAssembly module.
diff --git a/third_party/SPIRV-Tools/build_defs.bzl b/third_party/SPIRV-Tools/build_defs.bzl
index b2cd41b..ef9a829 100644
--- a/third_party/SPIRV-Tools/build_defs.bzl
+++ b/third_party/SPIRV-Tools/build_defs.bzl
@@ -68,6 +68,14 @@
"--core-insts-output=$(location {3}) " +
"--operand-kinds-output=$(location {4})"
).format(*fmtargs),
+ cmd_bat = (
+ "$(location :generate_grammar_tables) " +
+ "--spirv-core-grammar=$(location {0}) " +
+ "--extinst-debuginfo-grammar=$(location {1}) " +
+ "--extinst-cldebuginfo100-grammar=$(location {2}) " +
+ "--core-insts-output=$(location {3}) " +
+ "--operand-kinds-output=$(location {4})"
+ ).format(*fmtargs),
tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -97,6 +105,14 @@
"--extension-enum-output=$(location {3}) " +
"--enum-string-mapping-output=$(location {4})"
).format(*fmtargs),
+ cmd_bat = (
+ "$(location :generate_grammar_tables) " +
+ "--spirv-core-grammar=$(location {0}) " +
+ "--extinst-debuginfo-grammar=$(location {1}) " +
+ "--extinst-cldebuginfo100-grammar=$(location {2}) " +
+ "--extension-enum-output=$(location {3}) " +
+ "--enum-string-mapping-output=$(location {4})"
+ ).format(*fmtargs),
tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -118,6 +134,11 @@
"--extinst-opencl-grammar=$(location {0}) " +
"--opencl-insts-output=$(location {1})"
).format(*fmtargs),
+ cmd_bat = (
+ "$(location :generate_grammar_tables) " +
+ "--extinst-opencl-grammar=$(location {0}) " +
+ "--opencl-insts-output=$(location {1})"
+ ).format(*fmtargs),
tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -139,6 +160,11 @@
"--extinst-glsl-grammar=$(location {0}) " +
"--glsl-insts-output=$(location {1})"
).format(*fmtargs),
+ cmd_bat = (
+ "$(location :generate_grammar_tables) " +
+ "--extinst-glsl-grammar=$(location {0}) " +
+ "--glsl-insts-output=$(location {1})"
+ ).format(*fmtargs),
tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -161,6 +187,12 @@
"--vendor-insts-output=$(location {1}) " +
"--vendor-operand-kind-prefix={2}"
).format(*fmtargs),
+ cmd_bat = (
+ "$(location :generate_grammar_tables) " +
+ "--extinst-vendor-grammar=$(location {0}) " +
+ "--vendor-insts-output=$(location {1}) " +
+ "--vendor-operand-kind-prefix={2}"
+ ).format(*fmtargs),
tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -179,6 +211,11 @@
"--extinst-grammar=$< " +
"--extinst-output-path=$(location {0})"
).format(*fmtargs),
+ cmd_bat = (
+ "$(location :generate_language_headers) " +
+ "--extinst-grammar=$< " +
+ "--extinst-output-path=$(location {0})"
+ ).format(*fmtargs),
tools = [":generate_language_headers"],
visibility = ["//visibility:private"],
)
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp b/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp
index fdb2e64..2273e85 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp
+++ b/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp
@@ -896,6 +896,10 @@
const std::vector<opt::DescriptorSetAndBinding>&
descriptor_set_binding_pairs);
+// Creates a remove-dont-inline pass to remove the |DontInline| function control
+// from every function in the module. This is useful if you want the inliner to
+// inline these functions some reason.
+Optimizer::PassToken CreateRemoveDontInlinePass();
} // namespace spvtools
#endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_
diff --git a/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh b/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh
index d2a516f..c62611a 100644
--- a/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh
+++ b/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh
@@ -31,14 +31,14 @@
git clone --depth=1 https://github.com/google/effcee external/effcee
git clone --depth=1 https://github.com/google/re2 external/re2
-# Get bazel 0.29.1.
-gsutil cp gs://bazel/0.29.1/release/bazel-0.29.1-darwin-x86_64 .
-chmod +x bazel-0.29.1-darwin-x86_64
+# Get bazel 5.0.0
+gsutil cp gs://bazel/5.0.0/release/bazel-5.0.0-darwin-x86_64 .
+chmod +x bazel-5.0.0-darwin-x86_64
echo $(date): Build everything...
-./bazel-0.29.1-darwin-x86_64 build :all
+./bazel-5.0.0-darwin-x86_64 build :all
echo $(date): Build completed.
echo $(date): Starting bazel test...
-./bazel-0.29.1-darwin-x86_64 test :all
+./bazel-5.0.0-darwin-x86_64 test :all
echo $(date): Bazel test completed.
diff --git a/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh b/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh
index 8f76803..80043b8 100755
--- a/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh
+++ b/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh
@@ -195,7 +195,7 @@
echo $(date): ndk-build completed.
elif [ $TOOL = "bazel" ]; then
- using bazel-3.1.0
+ using bazel-5.0.0
echo $(date): Build everything...
bazel build :all
diff --git a/third_party/SPIRV-Tools/kokoro/windows-msvc-2015-release-bazel/build.bat b/third_party/SPIRV-Tools/kokoro/windows-msvc-2015-release-bazel/build.bat
index 2f721af..de20b0a 100644
--- a/third_party/SPIRV-Tools/kokoro/windows-msvc-2015-release-bazel/build.bat
+++ b/third_party/SPIRV-Tools/kokoro/windows-msvc-2015-release-bazel/build.bat
@@ -30,14 +30,13 @@
git clone --depth=1 https://github.com/google/re2 external/re2
:: REM Install Bazel.
-wget -q https://github.com/bazelbuild/bazel/releases/download/0.29.1/bazel-0.29.1-windows-x86_64.zip
-unzip -q bazel-0.29.1-windows-x86_64.zip
+wget -q https://github.com/bazelbuild/bazel/releases/download/5.0.0/bazel-5.0.0-windows-x86_64.zip
+unzip -q bazel-5.0.0-windows-x86_64.zip
:: Set up MSVC
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
set BAZEL_VS=C:\Program Files (x86)\Microsoft Visual Studio 14.0
set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
-set BAZEL_SH=c:\tools\msys64\usr\bin\bash.exe
set BAZEL_PYTHON=c:\tools\python2\python.exe
:: #########################################
diff --git a/third_party/SPIRV-Tools/source/opt/CMakeLists.txt b/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
index 7508dc0..05c02fc 100644
--- a/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
@@ -99,6 +99,7 @@
reflect.h
register_pressure.h
relax_float_ops_pass.h
+ remove_dontinline_pass.h
remove_duplicates_pass.h
remove_unused_interface_variables_pass.h
replace_desc_array_access_using_var_index.h
@@ -207,6 +208,7 @@
redundancy_elimination.cpp
register_pressure.cpp
relax_float_ops_pass.cpp
+ remove_dontinline_pass.cpp
remove_duplicates_pass.cpp
remove_unused_interface_variables_pass.cpp
replace_desc_array_access_using_var_index.cpp
diff --git a/third_party/SPIRV-Tools/source/opt/ccp_pass.cpp b/third_party/SPIRV-Tools/source/opt/ccp_pass.cpp
index 5099b47..5f85502 100644
--- a/third_party/SPIRV-Tools/source/opt/ccp_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/ccp_pass.cpp
@@ -172,7 +172,8 @@
if (folded_inst != nullptr) {
// We do not want to change the body of the function by adding new
// instructions. When folding we can only generate new constants.
- assert(folded_inst->IsConstant() &&
+ assert((folded_inst->IsConstant() ||
+ IsSpecConstantInst(folded_inst->opcode())) &&
"CCP is only interested in constant values.");
uint32_t new_val = ComputeLatticeMeet(instr, folded_inst->result_id());
values_[instr->result_id()] = new_val;
diff --git a/third_party/SPIRV-Tools/source/opt/compact_ids_pass.cpp b/third_party/SPIRV-Tools/source/opt/compact_ids_pass.cpp
index 8815b8c..70848d7 100644
--- a/third_party/SPIRV-Tools/source/opt/compact_ids_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/compact_ids_pass.cpp
@@ -86,7 +86,8 @@
},
true);
- if (modified) {
+ if (context()->module()->id_bound() != result_id_mapping.size() + 1) {
+ modified = true;
context()->module()->SetIdBound(
static_cast<uint32_t>(result_id_mapping.size() + 1));
// There are ids in the feature manager that could now be invalid
diff --git a/third_party/SPIRV-Tools/source/opt/folding_rules.cpp b/third_party/SPIRV-Tools/source/opt/folding_rules.cpp
index 4904f18..c879a0c 100644
--- a/third_party/SPIRV-Tools/source/opt/folding_rules.cpp
+++ b/third_party/SPIRV-Tools/source/opt/folding_rules.cpp
@@ -2368,7 +2368,7 @@
// fold.
return false;
}
- } else {
+ } else if (component_index != undef_literal) {
if (new_feeder_id == 0) {
// First time through, save the id of the operand the element comes
// from.
@@ -2382,7 +2382,7 @@
component_index -= feeder_op0_length;
}
- if (!feeder_is_op0) {
+ if (!feeder_is_op0 && component_index != undef_literal) {
component_index += op0_length;
}
}
diff --git a/third_party/SPIRV-Tools/source/opt/ir_context.cpp b/third_party/SPIRV-Tools/source/opt/ir_context.cpp
index 5b0beeb..a80d4f2 100644
--- a/third_party/SPIRV-Tools/source/opt/ir_context.cpp
+++ b/third_party/SPIRV-Tools/source/opt/ir_context.cpp
@@ -41,6 +41,8 @@
namespace opt {
void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) {
+ set = Analysis(set & ~valid_analyses_);
+
if (set & kAnalysisDefUse) {
BuildDefUseManager();
}
diff --git a/third_party/SPIRV-Tools/source/opt/ir_context.h b/third_party/SPIRV-Tools/source/opt/ir_context.h
index 274dd14..946f9e9 100644
--- a/third_party/SPIRV-Tools/source/opt/ir_context.h
+++ b/third_party/SPIRV-Tools/source/opt/ir_context.h
@@ -867,8 +867,7 @@
inline IRContext::Analysis& operator|=(IRContext::Analysis& lhs,
IRContext::Analysis rhs) {
- lhs = static_cast<IRContext::Analysis>(static_cast<int>(lhs) |
- static_cast<int>(rhs));
+ lhs = lhs | rhs;
return lhs;
}
diff --git a/third_party/SPIRV-Tools/source/opt/merge_return_pass.cpp b/third_party/SPIRV-Tools/source/opt/merge_return_pass.cpp
index a962a7c..7710dea 100644
--- a/third_party/SPIRV-Tools/source/opt/merge_return_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/merge_return_pass.cpp
@@ -431,6 +431,7 @@
std::list<BasicBlock*>* order, Instruction* break_merge_inst) {
// Make sure the CFG is build here. If we don't then it becomes very hard
// to know which new blocks need to be updated.
+ context()->InvalidateAnalyses(IRContext::kAnalysisCFG);
context()->BuildInvalidAnalyses(IRContext::kAnalysisCFG);
// When predicating, be aware of whether this block is a header block, a
diff --git a/third_party/SPIRV-Tools/source/opt/optimizer.cpp b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
index 330093e..ec2c8ea 100644
--- a/third_party/SPIRV-Tools/source/opt/optimizer.cpp
+++ b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
@@ -521,6 +521,8 @@
RegisterPass(CreateAmdExtToKhrPass());
} else if (pass_name == "interpolate-fixup") {
RegisterPass(CreateInterpolateFixupPass());
+ } else if (pass_name == "remove-dont-inline") {
+ RegisterPass(CreateRemoveDontInlinePass());
} else if (pass_name == "convert-to-sampled-image") {
if (pass_args.size() > 0) {
auto descriptor_set_binding_pairs =
@@ -1009,4 +1011,8 @@
MakeUnique<opt::ConvertToSampledImagePass>(descriptor_set_binding_pairs));
}
+Optimizer::PassToken CreateRemoveDontInlinePass() {
+ return MakeUnique<Optimizer::PassToken::Impl>(
+ MakeUnique<opt::RemoveDontInline>());
+}
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/passes.h b/third_party/SPIRV-Tools/source/opt/passes.h
index d51c306..26739cd 100644
--- a/third_party/SPIRV-Tools/source/opt/passes.h
+++ b/third_party/SPIRV-Tools/source/opt/passes.h
@@ -64,6 +64,7 @@
#include "source/opt/reduce_load_size.h"
#include "source/opt/redundancy_elimination.h"
#include "source/opt/relax_float_ops_pass.h"
+#include "source/opt/remove_dontinline_pass.h"
#include "source/opt/remove_duplicates_pass.h"
#include "source/opt/remove_unused_interface_variables_pass.h"
#include "source/opt/replace_desc_array_access_using_var_index.h"
diff --git a/third_party/SPIRV-Tools/source/opt/remove_dontinline_pass.cpp b/third_party/SPIRV-Tools/source/opt/remove_dontinline_pass.cpp
new file mode 100644
index 0000000..4dd1cd4
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/remove_dontinline_pass.cpp
@@ -0,0 +1,49 @@
+// 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/opt/remove_dontinline_pass.h"
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status RemoveDontInline::Process() {
+ bool modified = false;
+ modified = ClearDontInlineFunctionControl();
+ return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
+}
+
+bool RemoveDontInline::ClearDontInlineFunctionControl() {
+ bool modified = false;
+ for (auto& func : *get_module()) {
+ ClearDontInlineFunctionControl(&func);
+ }
+ return modified;
+}
+
+bool RemoveDontInline::ClearDontInlineFunctionControl(Function* function) {
+ constexpr uint32_t kFunctionControlInOperandIdx = 0;
+ Instruction* function_inst = &function->DefInst();
+ uint32_t function_control =
+ function_inst->GetSingleWordInOperand(kFunctionControlInOperandIdx);
+
+ if ((function_control & SpvFunctionControlDontInlineMask) == 0) {
+ return false;
+ }
+ function_control &= ~SpvFunctionControlDontInlineMask;
+ function_inst->SetInOperand(kFunctionControlInOperandIdx, {function_control});
+ return true;
+}
+
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/remove_dontinline_pass.h b/third_party/SPIRV-Tools/source/opt/remove_dontinline_pass.h
new file mode 100644
index 0000000..1624319
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/remove_dontinline_pass.h
@@ -0,0 +1,42 @@
+// 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_OPT_REMOVE_DONTINLINE_PASS_H_
+#define SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_
+
+#include "source/opt/pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// See optimizer.hpp for documentation.
+class RemoveDontInline : public Pass {
+ public:
+ const char* name() const override { return "remove-dont-inline"; }
+ Status Process() override;
+
+ private:
+ // Clears the DontInline function control from every function in the module.
+ // Returns true of a change was made.
+ bool ClearDontInlineFunctionControl();
+
+ // Clears the DontInline function control from |function|.
+ // Returns true of a change was made.
+ bool ClearDontInlineFunctionControl(Function* function);
+};
+
+} // namespace opt
+} // namespace spvtools
+
+#endif // SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_
diff --git a/third_party/SPIRV-Tools/source/val/validate_annotation.cpp b/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
index 0614e16..a27cf16 100644
--- a/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
@@ -326,17 +326,20 @@
case SpvDecorationLocation:
case SpvDecorationComponent:
// Location is used for input, output and ray tracing stages.
- if (sc == SpvStorageClassStorageBuffer ||
- sc == SpvStorageClassUniform ||
- sc == SpvStorageClassUniformConstant ||
- sc == SpvStorageClassWorkgroup || sc == SpvStorageClassPrivate ||
- sc == SpvStorageClassFunction) {
+ if (sc != SpvStorageClassInput && sc != SpvStorageClassOutput &&
+ sc != SpvStorageClassRayPayloadKHR &&
+ sc != SpvStorageClassIncomingRayPayloadKHR &&
+ sc != SpvStorageClassHitAttributeKHR &&
+ sc != SpvStorageClassCallableDataKHR &&
+ sc != SpvStorageClassIncomingCallableDataKHR &&
+ sc != SpvStorageClassShaderRecordBufferKHR) {
return _.diag(SPV_ERROR_INVALID_ID, target)
<< LogStringForDecoration(dec)
<< " decoration must not be applied to this storage class";
}
break;
case SpvDecorationIndex:
+ // Langauge from SPIR-V definition of Index
if (sc != SpvStorageClassOutput) {
return fail(0) << "must be in the Output storage class";
}
@@ -346,8 +349,8 @@
if (sc != SpvStorageClassStorageBuffer &&
sc != SpvStorageClassUniform &&
sc != SpvStorageClassUniformConstant) {
- return fail(0) << "must be in the StorageBuffer, Uniform, or "
- "UniformConstant storage class";
+ return fail(6491) << "must be in the StorageBuffer, Uniform, or "
+ "UniformConstant storage class";
}
break;
case SpvDecorationInputAttachmentIndex:
diff --git a/third_party/SPIRV-Tools/source/val/validate_extensions.cpp b/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
index f1e0ab9..fcf04e2 100644
--- a/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
@@ -147,6 +147,24 @@
return true;
}
+// Overload for NonSemanticShaderDebugInfo100Instructions.
+bool DoesDebugInfoOperandMatchExpectation(
+ const ValidationState_t& _,
+ const std::function<bool(NonSemanticShaderDebugInfo100Instructions)>&
+ expectation,
+ const Instruction* inst, uint32_t word_index) {
+ if (inst->words().size() <= word_index) return false;
+ auto* debug_inst = _.FindDef(inst->word(word_index));
+ if (debug_inst->opcode() != SpvOpExtInst ||
+ (debug_inst->ext_inst_type() !=
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
+ !expectation(
+ NonSemanticShaderDebugInfo100Instructions(debug_inst->word(4)))) {
+ return false;
+ }
+ return true;
+}
+
// Check that the operand of a debug info instruction |inst| at |word_index|
// is a result id of an debug info instruction whose debug instruction type
// is |expected_debug_inst|.
@@ -223,6 +241,18 @@
const Instruction* inst, uint32_t word_index,
const std::function<std::string()>& ext_inst_name,
bool allow_template_param) {
+ // Check for NonSemanticShaderDebugInfo100 specific types.
+ if (inst->ext_inst_type() ==
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
+ std::function<bool(NonSemanticShaderDebugInfo100Instructions)> expectation =
+ [](NonSemanticShaderDebugInfo100Instructions dbg_inst) {
+ return dbg_inst == NonSemanticShaderDebugInfo100DebugTypeMatrix;
+ };
+ if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
+ return SPV_SUCCESS;
+ }
+
+ // Check for common types.
std::function<bool(CommonDebugInfoInstructions)> expectation =
[&allow_template_param](CommonDebugInfoInstructions dbg_inst) {
if (allow_template_param &&
@@ -2719,6 +2749,86 @@
auto num_words = inst->words().size();
+ // Handle any non-common NonSemanticShaderDebugInfo instructions.
+ if (vulkanDebugInfo) {
+ const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
+ NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
+ switch (ext_inst_key) {
+ // The following block of instructions will be handled by the common
+ // validation.
+ case NonSemanticShaderDebugInfo100DebugInfoNone:
+ case NonSemanticShaderDebugInfo100DebugCompilationUnit:
+ case NonSemanticShaderDebugInfo100DebugTypeBasic:
+ case NonSemanticShaderDebugInfo100DebugTypePointer:
+ case NonSemanticShaderDebugInfo100DebugTypeQualifier:
+ case NonSemanticShaderDebugInfo100DebugTypeArray:
+ case NonSemanticShaderDebugInfo100DebugTypeVector:
+ case NonSemanticShaderDebugInfo100DebugTypedef:
+ case NonSemanticShaderDebugInfo100DebugTypeFunction:
+ case NonSemanticShaderDebugInfo100DebugTypeEnum:
+ case NonSemanticShaderDebugInfo100DebugTypeComposite:
+ case NonSemanticShaderDebugInfo100DebugTypeMember:
+ case NonSemanticShaderDebugInfo100DebugTypeInheritance:
+ case NonSemanticShaderDebugInfo100DebugTypePtrToMember:
+ case NonSemanticShaderDebugInfo100DebugTypeTemplate:
+ case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter:
+ case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter:
+ case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack:
+ case NonSemanticShaderDebugInfo100DebugGlobalVariable:
+ case NonSemanticShaderDebugInfo100DebugFunctionDeclaration:
+ case NonSemanticShaderDebugInfo100DebugFunction:
+ case NonSemanticShaderDebugInfo100DebugLexicalBlock:
+ case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator:
+ case NonSemanticShaderDebugInfo100DebugScope:
+ case NonSemanticShaderDebugInfo100DebugNoScope:
+ case NonSemanticShaderDebugInfo100DebugInlinedAt:
+ case NonSemanticShaderDebugInfo100DebugLocalVariable:
+ case NonSemanticShaderDebugInfo100DebugInlinedVariable:
+ case NonSemanticShaderDebugInfo100DebugDeclare:
+ case NonSemanticShaderDebugInfo100DebugValue:
+ case NonSemanticShaderDebugInfo100DebugOperation:
+ case NonSemanticShaderDebugInfo100DebugExpression:
+ case NonSemanticShaderDebugInfo100DebugMacroDef:
+ case NonSemanticShaderDebugInfo100DebugMacroUndef:
+ case NonSemanticShaderDebugInfo100DebugImportedEntity:
+ case NonSemanticShaderDebugInfo100DebugSource:
+ break;
+ case NonSemanticShaderDebugInfo100DebugTypeMatrix: {
+ CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5);
+
+ CHECK_CONST_UINT_OPERAND("Vector Count", 6);
+
+ uint32_t vector_count = inst->word(6);
+ uint64_t const_val;
+ if (!_.GetConstantValUint64(vector_count, &const_val)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name()
+ << ": Vector Count must be 32-bit integer OpConstant";
+ }
+
+ vector_count = const_val & 0xffffffff;
+ if (!vector_count || vector_count > 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": Vector Count must be positive "
+ << "integer less than or equal to 4";
+ }
+ break;
+ }
+ // TODO: Add validation rules for remaining cases as well.
+ case NonSemanticShaderDebugInfo100DebugFunctionDefinition:
+ case NonSemanticShaderDebugInfo100DebugSourceContinued:
+ case NonSemanticShaderDebugInfo100DebugLine:
+ case NonSemanticShaderDebugInfo100DebugNoLine:
+ case NonSemanticShaderDebugInfo100DebugBuildIdentifier:
+ case NonSemanticShaderDebugInfo100DebugStoragePath:
+ case NonSemanticShaderDebugInfo100DebugEntryPoint:
+ break;
+ case NonSemanticShaderDebugInfo100InstructionsMax:
+ assert(0);
+ break;
+ }
+ }
+
// Handle any non-common OpenCL insts, then common
if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
OpenCLDebugInfo100Instructions(ext_inst_index) !=
diff --git a/third_party/SPIRV-Tools/source/val/validate_memory.cpp b/third_party/SPIRV-Tools/source/val/validate_memory.cpp
index 93b1800..4f3d9cd 100644
--- a/third_party/SPIRV-Tools/source/val/validate_memory.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_memory.cpp
@@ -596,23 +596,23 @@
}
}
}
- }
- // Vulkan Appendix A: Check that if contains initializer, then
- // storage class is Output, Private, or Function.
- if (inst->operands().size() > 3 && storage_class != SpvStorageClassOutput &&
- storage_class != SpvStorageClassPrivate &&
- storage_class != SpvStorageClassFunction) {
- if (spvIsVulkanEnv(_.context()->target_env)) {
+ // Initializers in Vulkan are only allowed in some storage clases
+ if (inst->operands().size() > 3) {
if (storage_class == SpvStorageClassWorkgroup) {
auto init_id = inst->GetOperandAs<uint32_t>(3);
auto init = _.FindDef(init_id);
if (init->opcode() != SpvOpConstantNull) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "Variable initializers in Workgroup storage class are "
- "limited to OpConstantNull";
+ << _.VkErrorID(4734) << "OpVariable, <id> '"
+ << _.getIdName(inst->id())
+ << "', initializers are limited to OpConstantNull in "
+ "Workgroup "
+ "storage class";
}
- } else {
+ } else if (storage_class != SpvStorageClassOutput &&
+ storage_class != SpvStorageClassPrivate &&
+ storage_class != SpvStorageClassFunction) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< _.VkErrorID(4651) << "OpVariable, <id> '"
<< _.getIdName(inst->id())
diff --git a/third_party/SPIRV-Tools/source/val/validation_state.cpp b/third_party/SPIRV-Tools/source/val/validation_state.cpp
index 6f97321..977a160 100644
--- a/third_party/SPIRV-Tools/source/val/validation_state.cpp
+++ b/third_party/SPIRV-Tools/source/val/validation_state.cpp
@@ -1882,6 +1882,8 @@
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732);
case 4733:
return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
+ case 4734:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734);
case 4780:
return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
case 4915:
@@ -1894,6 +1896,8 @@
return VUID_WRAP(VUID-StandaloneSpirv-Location-04918);
case 4919:
return VUID_WRAP(VUID-StandaloneSpirv-Location-04919);
+ case 6491:
+ return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
default:
return ""; // unknown id
}
diff --git a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
index 759d423..f50fdda 100644
--- a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
@@ -82,6 +82,7 @@
propagator_test.cpp
reduce_load_size_test.cpp
redundancy_elimination_test.cpp
+ remove_dontinline_test.cpp
remove_unused_interface_variables_test.cpp
register_liveness.cpp
relax_float_ops_test.cpp
diff --git a/third_party/SPIRV-Tools/test/opt/ccp_test.cpp b/third_party/SPIRV-Tools/test/opt/ccp_test.cpp
index ae7043b..f0f2436 100644
--- a/third_party/SPIRV-Tools/test/opt/ccp_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/ccp_test.cpp
@@ -582,6 +582,35 @@
EXPECT_EQ(std::get<1>(res), Pass::Status::SuccessWithoutChange);
}
+TEST_F(CCPTest, FoldConstantCompositeInstrucitonsWithSpecConst) {
+ const std::string spv_asm = R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %1 "main"
+ OpExecutionMode %1 OriginUpperLeft
+ %void = OpTypeVoid
+ %4 = OpTypeFunction %void
+ %bool = OpTypeBool
+ %v3bool = OpTypeVector %bool 3
+ %_struct_8 = OpTypeStruct %v3bool
+ %true = OpConstantTrue %bool
+; CHECK: [[spec_const:%\w+]] = OpSpecConstantComposite %v3bool
+ %11 = OpSpecConstantComposite %v3bool %true %true %true
+ %12 = OpConstantComposite %_struct_8 %11
+; CHECK: OpFunction
+ %1 = OpFunction %void None %4
+ %29 = OpLabel
+ %31 = OpCompositeExtract %v3bool %12 0
+; CHECK: OpCompositeExtract %bool [[spec_const]] 0
+ %32 = OpCompositeExtract %bool %31 0
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ auto result = SinglePassRunAndMatch<CCPPass>(spv_asm, true);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
TEST_F(CCPTest, UpdateSubsequentPhisToVarying) {
const std::string text = R"(
OpCapability Shader
diff --git a/third_party/SPIRV-Tools/test/opt/compact_ids_test.cpp b/third_party/SPIRV-Tools/test/opt/compact_ids_test.cpp
index ba31d84..7c232fe 100644
--- a/third_party/SPIRV-Tools/test/opt/compact_ids_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/compact_ids_test.cpp
@@ -310,6 +310,41 @@
EXPECT_THAT(disassembly, ::testing::Eq(expected));
}
+TEST(CompactIds, ResetIdBound) {
+ const std::string input(R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %1 "main"
+OpExecutionMode %1 OriginUpperLeft
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%1 = OpFunction %void None %3
+%4 = OpLabel
+OpReturn
+OpFunctionEnd
+)");
+
+ spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
+ std::unique_ptr<IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, input,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ ASSERT_NE(context, nullptr);
+
+ CompactIdsPass compact_id_pass;
+ context->module()->SetIdBound(20000);
+ const auto status = compact_id_pass.Run(context.get());
+ EXPECT_EQ(status, Pass::Status::SuccessWithChange);
+ EXPECT_EQ(context->module()->id_bound(), 5);
+
+ // Test output just in case
+ std::vector<uint32_t> binary;
+ context->module()->ToBinary(&binary, false);
+ std::string disassembly;
+ tools.Disassemble(binary, &disassembly,
+ SpirvTools::kDefaultDisassembleOption);
+
+ EXPECT_THAT(disassembly, ::testing::Eq(input));
+}
+
} // namespace
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/fold_test.cpp b/third_party/SPIRV-Tools/test/opt/fold_test.cpp
index df8f3b1..7565ca7 100644
--- a/third_party/SPIRV-Tools/test/opt/fold_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/fold_test.cpp
@@ -7087,6 +7087,27 @@
3, true)
));
+INSTANTIATE_TEST_SUITE_P(VectorShuffleMatchingTest, MatchingInstructionFoldingTest,
+::testing::Values(
+ // Test case 0: Using OpDot to extract last element.
+ InstructionFoldingCase<bool>(
+ Header() +
+ "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
+ "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2{{[[:space:]]}}\n" +
+ "; CHECK: [[null:%\\w+]] = OpConstantNull [[v2int]]\n" +
+ "; CHECK: OpVectorShuffle\n" +
+ "; CHECK: %3 = OpVectorShuffle [[v2int]] [[null]] {{%\\w+}} 4294967295 2\n" +
+ "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 3 0xFFFFFFFF \n" +
+ "%3 = OpVectorShuffle %v2int %2 %v2int_2_3 1 2 \n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 3, true)
+ ));
+
using MatchingInstructionWithNoResultFoldingTest =
::testing::TestWithParam<InstructionFoldingCase<bool>>;
diff --git a/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp b/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp
index b6866d0..ece0479 100644
--- a/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp
@@ -90,6 +90,21 @@
}
}
+TEST_F(IRContextTest, DontRebuildValidAnalysis) {
+ std::unique_ptr<Module> module(new Module());
+ IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+ spvtools::MessageConsumer());
+
+ auto* oldCfg = localContext.cfg();
+ auto* oldDefUse = localContext.get_def_use_mgr();
+ localContext.BuildInvalidAnalyses(IRContext::kAnalysisCFG |
+ IRContext::kAnalysisDefUse);
+ auto* newCfg = localContext.cfg();
+ auto* newDefUse = localContext.get_def_use_mgr();
+ EXPECT_EQ(oldCfg, newCfg);
+ EXPECT_EQ(oldDefUse, newDefUse);
+}
+
TEST_F(IRContextTest, AllValidAfterBuild) {
std::unique_ptr<Module> module = MakeUnique<Module>();
IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
diff --git a/third_party/SPIRV-Tools/test/opt/remove_dontinline_test.cpp b/third_party/SPIRV-Tools/test/opt/remove_dontinline_test.cpp
new file mode 100644
index 0000000..c5425e8
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/opt/remove_dontinline_test.cpp
@@ -0,0 +1,127 @@
+// Copyright (c) 2017 Google 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.
+
+#include <vector>
+
+#include "test/opt/pass_fixture.h"
+#include "test/opt/pass_utils.h"
+
+namespace spvtools {
+namespace opt {
+namespace {
+
+using StrengthReductionBasicTest = PassTest<::testing::Test>;
+
+TEST_F(StrengthReductionBasicTest, ClearDontInline) {
+ const std::vector<const char*> text = {
+ // clang-format off
+ "OpCapability Shader",
+ "%1 = OpExtInstImport \"GLSL.std.450\"",
+ "OpMemoryModel Logical GLSL450",
+ "OpEntryPoint Vertex %main \"main\"",
+ "%void = OpTypeVoid",
+ "%4 = OpTypeFunction %void",
+"; CHECK: OpFunction %void None",
+ "%main = OpFunction %void DontInline %4",
+ "%8 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd"
+ // clang-format on
+ };
+
+ SinglePassRunAndMatch<RemoveDontInline>(JoinAllInsts(text), true);
+}
+
+TEST_F(StrengthReductionBasicTest, LeaveUnchanged1) {
+ const std::vector<const char*> text = {
+ // clang-format off
+ "OpCapability Shader",
+ "%1 = OpExtInstImport \"GLSL.std.450\"",
+ "OpMemoryModel Logical GLSL450",
+ "OpEntryPoint Vertex %main \"main\"",
+ "%void = OpTypeVoid",
+ "%4 = OpTypeFunction %void",
+ "%main = OpFunction %void None %4",
+ "%8 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd"
+ // clang-format on
+ };
+
+ EXPECT_EQ(Pass::Status::SuccessWithoutChange,
+ std::get<1>(SinglePassRunAndDisassemble<RemoveDontInline>(
+ JoinAllInsts(text), false, true)));
+}
+
+TEST_F(StrengthReductionBasicTest, LeaveUnchanged2) {
+ const std::vector<const char*> text = {
+ // clang-format off
+ "OpCapability Shader",
+ "%1 = OpExtInstImport \"GLSL.std.450\"",
+ "OpMemoryModel Logical GLSL450",
+ "OpEntryPoint Vertex %main \"main\"",
+ "%void = OpTypeVoid",
+ "%4 = OpTypeFunction %void",
+ "%main = OpFunction %void Inline %4",
+ "%8 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd"
+ // clang-format on
+ };
+
+ EXPECT_EQ(Pass::Status::SuccessWithoutChange,
+ std::get<1>(SinglePassRunAndDisassemble<RemoveDontInline>(
+ JoinAllInsts(text), false, true)));
+}
+
+TEST_F(StrengthReductionBasicTest, ClearMultipleDontInline) {
+ const std::vector<const char*> text = {
+ // clang-format off
+ "OpCapability Shader",
+ "%1 = OpExtInstImport \"GLSL.std.450\"",
+ "OpMemoryModel Logical GLSL450",
+ "OpEntryPoint Vertex %main1 \"main1\"",
+ "OpEntryPoint Vertex %main2 \"main2\"",
+ "OpEntryPoint Vertex %main3 \"main3\"",
+ "OpEntryPoint Vertex %main4 \"main4\"",
+ "%void = OpTypeVoid",
+ "%4 = OpTypeFunction %void",
+ "; CHECK: OpFunction %void None",
+ "%main1 = OpFunction %void DontInline %4",
+ "%8 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd",
+ "; CHECK: OpFunction %void Inline",
+ "%main2 = OpFunction %void Inline %4",
+ "%9 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd",
+ "; CHECK: OpFunction %void Pure",
+ "%main3 = OpFunction %void DontInline|Pure %4",
+ "%10 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd",
+ "; CHECK: OpFunction %void None",
+ "%main4 = OpFunction %void None %4",
+ "%11 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd"
+ // clang-format on
+ };
+
+ SinglePassRunAndMatch<RemoveDontInline>(JoinAllInsts(text), true);
+}
+} // namespace
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp b/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp
index 889c76c..b711ce7 100644
--- a/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp
@@ -794,6 +794,8 @@
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("VUID-StandaloneSpirv-DescriptorSet-06491"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("must be in the StorageBuffer, Uniform, or "
"UniformConstant storage class"));
}
diff --git a/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp b/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp
index e153072..554e78b 100644
--- a/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp
@@ -1864,6 +1864,178 @@
"integer less than or equal to 4"));
}
+TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrix) {
+ const std::string src = R"(
+%src = OpString "simple.hlsl"
+%code = OpString "main() {}"
+%float_name = OpString "float"
+)";
+
+ const std::string constants = R"(
+%u32_4 = OpConstant %u32 4
+%u32_5 = OpConstant %u32 5
+%u32_32 = OpConstant %u32 32
+%true = OpConstantTrue %bool
+)";
+
+ const std::string dbg_inst_header = R"(
+%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
+%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
+%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
+%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
+%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_4 %true
+)";
+
+ const std::string extension = R"(
+OpExtension "SPV_KHR_non_semantic_info"
+%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+)";
+
+ CompileSuccessfully(GenerateShaderCodeForDebugInfo(
+ src, constants, dbg_inst_header, "", extension, "Vertex"));
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorTypeType) {
+ const std::string src = R"(
+%src = OpString "simple.hlsl"
+%code = OpString "main() {}"
+%float_name = OpString "float"
+)";
+
+ const std::string constants = R"(
+%u32_4 = OpConstant %u32 4
+%u32_5 = OpConstant %u32 5
+%u32_32 = OpConstant %u32 32
+%true = OpConstantTrue %bool
+)";
+
+ const std::string dbg_inst_header = R"(
+%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
+%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
+%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
+%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
+%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %dbg_src %u32_4 %true
+)";
+
+ const std::string extension = R"(
+OpExtension "SPV_KHR_non_semantic_info"
+%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+)";
+
+ CompileSuccessfully(GenerateShaderCodeForDebugInfo(
+ src, constants, dbg_inst_header, "", extension, "Vertex"));
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("expected operand Vector Type must be a result id of "
+ "DebugTypeVector"));
+}
+
+TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountType) {
+ const std::string src = R"(
+%src = OpString "simple.hlsl"
+%code = OpString "main() {}"
+%float_name = OpString "float"
+)";
+
+ const std::string constants = R"(
+%u32_4 = OpConstant %u32 4
+%u32_5 = OpConstant %u32 5
+%u32_32 = OpConstant %u32 32
+%true = OpConstantTrue %bool
+)";
+
+ const std::string dbg_inst_header = R"(
+%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
+%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
+%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
+%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
+%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %dbg_src %true
+)";
+
+ const std::string extension = R"(
+OpExtension "SPV_KHR_non_semantic_info"
+%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+)";
+
+ CompileSuccessfully(GenerateShaderCodeForDebugInfo(
+ src, constants, dbg_inst_header, "", extension, "Vertex"));
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("expected operand Vector Count must be a result id of "
+ "32-bit unsigned OpConstant"));
+}
+
+TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountZero) {
+ const std::string src = R"(
+%src = OpString "simple.hlsl"
+%code = OpString "main() {}"
+%float_name = OpString "float"
+)";
+
+ const std::string constants = R"(
+%u32_4 = OpConstant %u32 4
+%u32_5 = OpConstant %u32 5
+%u32_32 = OpConstant %u32 32
+%true = OpConstantTrue %bool
+)";
+
+ const std::string dbg_inst_header = R"(
+%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
+%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
+%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
+%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
+%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_0 %true
+)";
+
+ const std::string extension = R"(
+OpExtension "SPV_KHR_non_semantic_info"
+%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+)";
+
+ CompileSuccessfully(GenerateShaderCodeForDebugInfo(
+ src, constants, dbg_inst_header, "", extension, "Vertex"));
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Vector Count must be positive "
+ "integer less than or equal to 4"));
+}
+
+TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountFive) {
+ const std::string src = R"(
+%src = OpString "simple.hlsl"
+%code = OpString "main() {}"
+%float_name = OpString "float"
+)";
+
+ const std::string constants = R"(
+%u32_4 = OpConstant %u32 4
+%u32_5 = OpConstant %u32 5
+%u32_32 = OpConstant %u32 32
+%true = OpConstantTrue %bool
+)";
+
+ const std::string dbg_inst_header = R"(
+%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
+%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
+%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
+%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
+%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_5 %true
+)";
+
+ const std::string extension = R"(
+OpExtension "SPV_KHR_non_semantic_info"
+%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+)";
+
+ CompileSuccessfully(GenerateShaderCodeForDebugInfo(
+ src, constants, dbg_inst_header, "", extension, "Vertex"));
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Vector Count must be positive "
+ "integer less than or equal to 4"));
+}
+
TEST_F(ValidateOpenCL100DebugInfo, DebugTypedef) {
const std::string src = R"(
%src = OpString "simple.hlsl"
diff --git a/third_party/SPIRV-Tools/test/val/val_memory_test.cpp b/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
index 8ff40e1..7215974 100644
--- a/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
@@ -4259,8 +4259,10 @@
CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Variable initializers in Workgroup storage class are "
- "limited to OpConstantNull"));
+ AnyVUID(" VUID-StandaloneSpirv-OpVariable-04734"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpVariable, <id> '5[%5]', initializers are limited to "
+ "OpConstantNull in Workgroup storage class"));
}
TEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassGood) {