Sfoglia il codice sorgente

Updated spirv-tools.

Бранимир Караџић 6 anni fa
parent
commit
f69f583517
66 ha cambiato i file con 511 aggiunte e 157 eliminazioni
  1. 2 2
      3rdparty/spirv-tools/.gitignore
  2. 1 0
      3rdparty/spirv-tools/Android.mk
  3. 2 0
      3rdparty/spirv-tools/BUILD.gn
  4. 4 1
      3rdparty/spirv-tools/CMakeLists.txt
  5. 2 7
      3rdparty/spirv-tools/README.md
  6. 1 1
      3rdparty/spirv-tools/include/generated/build-version.inc
  7. 5 0
      3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp
  8. 1 0
      3rdparty/spirv-tools/source/opt/CMakeLists.txt
  9. 1 0
      3rdparty/spirv-tools/source/opt/fix_storage_class.cpp
  10. 39 0
      3rdparty/spirv-tools/source/opt/legalize_vector_shuffle_pass.cpp
  11. 53 0
      3rdparty/spirv-tools/source/opt/legalize_vector_shuffle_pass.h
  12. 13 3
      3rdparty/spirv-tools/source/opt/optimizer.cpp
  13. 1 0
      3rdparty/spirv-tools/source/opt/passes.h
  14. 1 1
      3rdparty/spirv-tools/source/reduce/change_operand_reduction_opportunity.cpp
  15. 4 6
      3rdparty/spirv-tools/source/reduce/change_operand_reduction_opportunity.h
  16. 8 5
      3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp
  17. 1 1
      3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.h
  18. 3 3
      3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity_finder.cpp
  19. 2 2
      3rdparty/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp
  20. 10 7
      3rdparty/spirv-tools/source/reduce/operand_to_dominating_id_reduction_opportunity_finder.cpp
  21. 1 1
      3rdparty/spirv-tools/source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h
  22. 1 1
      3rdparty/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp
  23. 5 2
      3rdparty/spirv-tools/source/reduce/reducer.cpp
  24. 1 2
      3rdparty/spirv-tools/source/reduce/reducer.h
  25. 1 1
      3rdparty/spirv-tools/source/reduce/reduction_opportunity.cpp
  26. 1 1
      3rdparty/spirv-tools/source/reduce/reduction_opportunity_finder.h
  27. 2 2
      3rdparty/spirv-tools/source/reduce/reduction_pass.cpp
  28. 2 1
      3rdparty/spirv-tools/source/reduce/reduction_util.cpp
  29. 3 2
      3rdparty/spirv-tools/source/reduce/remove_block_reduction_opportunity.cpp
  30. 1 1
      3rdparty/spirv-tools/source/reduce/remove_block_reduction_opportunity.h
  31. 7 5
      3rdparty/spirv-tools/source/reduce/remove_block_reduction_opportunity_finder.cpp
  32. 2 1
      3rdparty/spirv-tools/source/reduce/remove_function_reduction_opportunity.cpp
  33. 1 1
      3rdparty/spirv-tools/source/reduce/remove_function_reduction_opportunity.h
  34. 3 2
      3rdparty/spirv-tools/source/reduce/remove_function_reduction_opportunity_finder.cpp
  35. 2 2
      3rdparty/spirv-tools/source/reduce/remove_instruction_reduction_opportunity.cpp
  36. 3 5
      3rdparty/spirv-tools/source/reduce/remove_instruction_reduction_opportunity.h
  37. 5 4
      3rdparty/spirv-tools/source/reduce/remove_opname_instruction_reduction_opportunity_finder.cpp
  38. 1 1
      3rdparty/spirv-tools/source/reduce/remove_opname_instruction_reduction_opportunity_finder.h
  39. 6 4
      3rdparty/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp
  40. 5 4
      3rdparty/spirv-tools/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp
  41. 1 1
      3rdparty/spirv-tools/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h
  42. 7 2
      3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp
  43. 11 11
      3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.h
  44. 5 4
      3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity_finder.cpp
  45. 1 1
      3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h
  46. 15 11
      3rdparty/spirv-tools/source/val/validate_image.cpp
  47. 1 0
      3rdparty/spirv-tools/test/opt/CMakeLists.txt
  48. 19 0
      3rdparty/spirv-tools/test/opt/fix_storage_class_test.cpp
  49. 81 0
      3rdparty/spirv-tools/test/opt/legalize_vector_shuffle_test.cpp
  50. 45 2
      3rdparty/spirv-tools/test/opt/optimizer_test.cpp
  51. 3 2
      3rdparty/spirv-tools/test/reduce/merge_blocks_test.cpp
  52. 4 2
      3rdparty/spirv-tools/test/reduce/operand_to_constant_test.cpp
  53. 4 2
      3rdparty/spirv-tools/test/reduce/operand_to_dominating_id_test.cpp
  54. 3 1
      3rdparty/spirv-tools/test/reduce/operand_to_undef_test.cpp
  55. 17 1
      3rdparty/spirv-tools/test/reduce/reduce_test_util.cpp
  56. 7 1
      3rdparty/spirv-tools/test/reduce/reduce_test_util.h
  57. 2 2
      3rdparty/spirv-tools/test/reduce/reducer_test.cpp
  58. 3 3
      3rdparty/spirv-tools/test/reduce/remove_block_test.cpp
  59. 3 2
      3rdparty/spirv-tools/test/reduce/remove_function_test.cpp
  60. 2 2
      3rdparty/spirv-tools/test/reduce/remove_opname_instruction_test.cpp
  61. 2 2
      3rdparty/spirv-tools/test/reduce/remove_selection_test.cpp
  62. 2 3
      3rdparty/spirv-tools/test/reduce/remove_unreferenced_instruction_test.cpp
  63. 4 2
      3rdparty/spirv-tools/test/reduce/structured_loop_to_selection_test.cpp
  64. 15 11
      3rdparty/spirv-tools/test/reduce/validation_during_reduction_test.cpp
  65. 26 2
      3rdparty/spirv-tools/test/val/val_image_test.cpp
  66. 21 5
      3rdparty/spirv-tools/tools/reduce/reduce.cpp

+ 2 - 2
3rdparty/spirv-tools/.gitignore

@@ -21,5 +21,5 @@ compile_commands.json
 *~
 
 # C-Lion
-.idea
-cmake-build-debug
+/.idea/
+/cmake-build-*/

+ 1 - 0
3rdparty/spirv-tools/Android.mk

@@ -119,6 +119,7 @@ SPVTOOLS_OPT_SRC_FILES := \
 		source/opt/instrument_pass.cpp \
 		source/opt/ir_context.cpp \
 		source/opt/ir_loader.cpp \
+                source/opt/legalize_vector_shuffle_pass.cpp \
 		source/opt/licm_pass.cpp \
 		source/opt/local_access_chain_convert_pass.cpp \
 		source/opt/local_redundancy_elimination.cpp \

+ 2 - 0
3rdparty/spirv-tools/BUILD.gn

@@ -540,6 +540,8 @@ static_library("spvtools_opt") {
     "source/opt/ir_loader.cpp",
     "source/opt/ir_loader.h",
     "source/opt/iterator.h",
+    "source/opt/legalize_vector_shuffle_pass.cpp",
+    "source/opt/legalize_vector_shuffle_pass.h",
     "source/opt/licm_pass.cpp",
     "source/opt/licm_pass.h",
     "source/opt/local_access_chain_convert_pass.cpp",

+ 4 - 1
3rdparty/spirv-tools/CMakeLists.txt

@@ -140,6 +140,8 @@ function(spvtools_default_compile_options TARGET)
       if(NOT "${SPIRV_USE_SANITIZER}" STREQUAL "")
         target_compile_options(${TARGET} PRIVATE
           -fsanitize=${SPIRV_USE_SANITIZER})
+        set_target_properties(${TARGET} PROPERTIES
+          LINK_FLAGS -fsanitize=${SPIRV_USE_SANITIZER})
       endif()
       target_compile_options(${TARGET} PRIVATE
          -ftemplate-depth=1024)
@@ -176,7 +178,8 @@ if(NOT COMMAND find_host_program)
   endmacro()
 endif()
 
-find_host_package(PythonInterp)
+# Tests require Python3
+find_host_package(PythonInterp 3 REQUIRED)
 
 # Check for symbol exports on Linux.
 # At the moment, this check will fail on the OSX build machines for the Android NDK.

+ 2 - 7
3rdparty/spirv-tools/README.md

@@ -276,13 +276,8 @@ installed regardless of your OS:
 
 - [CMake](http://www.cmake.org/): for generating compilation targets.  Version
   2.8.12 or later.
-- [Python](http://www.python.org/): for utility scripts and running the test 
-suite. Version 2 or 3.
-
-We will be moving to Python3 only in the future.  If you are using Python2, you
-will need to install Python-future: 
-```pip install future
-```
+- [Python 3](http://www.python.org/): for utility scripts and running the test
+suite.
 
 SPIRV-Tools is regularly tested with the the following compilers:
 

+ 1 - 1
3rdparty/spirv-tools/include/generated/build-version.inc

@@ -1 +1 @@
-"v2019.3-dev", "SPIRV-Tools v2019.3-dev v2019.1-132-g0cb2d407"
+"v2019.3-dev", "SPIRV-Tools v2019.3-dev v2019.1-140-g102e430a"

+ 5 - 0
3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp

@@ -763,6 +763,11 @@ Optimizer::PassToken CreateGenerateWebGPUInitializersPass();
 // match up correctly.  This pass will fix the errors that it can.
 Optimizer::PassToken CreateFixStorageClassPass();
 
+// Create a pass to legalize OpVectorShuffle operands going into WebGPU. WebGPU
+// forbids using 0xFFFFFFFF, which indicates an undefined result, so this pass
+// converts those literals to 0.
+Optimizer::PassToken CreateLegalizeVectorShufflePass();
+
 }  // namespace spvtools
 
 #endif  // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_

+ 1 - 0
3rdparty/spirv-tools/source/opt/CMakeLists.txt

@@ -157,6 +157,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
   instrument_pass.cpp
   ir_context.cpp
   ir_loader.cpp
+  legalize_vector_shuffle_pass.cpp
   licm_pass.cpp
   local_access_chain_convert_pass.cpp
   local_redundancy_elimination.cpp

+ 1 - 0
3rdparty/spirv-tools/source/opt/fix_storage_class.cpp

@@ -68,6 +68,7 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst,
     case SpvOpCopyMemory:
     case SpvOpCopyMemorySized:
     case SpvOpVariable:
+    case SpvOpBitcast:
       // Nothing to change for these opcode.  The result type is the same
       // regardless of the storage class of the operand.
       return false;

+ 39 - 0
3rdparty/spirv-tools/source/opt/legalize_vector_shuffle_pass.cpp

@@ -0,0 +1,39 @@
+// Copyright (c) 2019 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 "source/opt/legalize_vector_shuffle_pass.h"
+
+#include "source/opt/ir_context.h"
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status LegalizeVectorShufflePass::Process() {
+  bool changed = false;
+  context()->module()->ForEachInst([&changed](Instruction* inst) {
+    if (inst->opcode() != SpvOpVectorShuffle) return;
+
+    for (uint32_t idx = 2; idx < inst->NumInOperands(); ++idx) {
+      auto literal = inst->GetSingleWordInOperand(idx);
+      if (literal != 0xFFFFFFFF) continue;
+      changed = true;
+      inst->SetInOperand(idx, {0});
+    }
+  });
+
+  return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange;
+}
+
+}  // namespace opt
+}  // namespace spvtools

+ 53 - 0
3rdparty/spirv-tools/source/opt/legalize_vector_shuffle_pass.h

@@ -0,0 +1,53 @@
+// Copyright (c) 2019 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.
+
+#ifndef SOURCE_OPT_LEGALIZE_VECTOR_SHUFFLE_PASS_H_
+#define SOURCE_OPT_LEGALIZE_VECTOR_SHUFFLE_PASS_H_
+
+#include "source/opt/ir_context.h"
+#include "source/opt/module.h"
+#include "source/opt/pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// Converts any usages of 0xFFFFFFFF for the literals in OpVectorShuffle to a
+// literal 0. This is needed because using OxFFFFFFFF is forbidden by the WebGPU
+// spec. 0xFFFFFFFF in the main spec indicates that the result for this
+// component has no source, thus is undefined. Since this is undefined
+// behaviour we are free to use 0.
+class LegalizeVectorShufflePass : public Pass {
+ public:
+  const char* name() const override { return "legalize-vector-shuffle"; }
+  Status Process() override;
+
+  IRContext::Analysis GetPreservedAnalyses() override {
+    return IRContext::kAnalysisInstrToBlockMapping |
+           IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
+           IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis |
+           IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap |
+           IRContext::kAnalysisScalarEvolution |
+           IRContext::kAnalysisRegisterPressure |
+           IRContext::kAnalysisValueNumberTable |
+           IRContext::kAnalysisStructuredCFG |
+           IRContext::kAnalysisBuiltinVarId |
+           IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes |
+           IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants;
+  }
+};
+
+}  // namespace opt
+}  // namespace spvtools
+
+#endif  // SOURCE_OPT_LEGALIZE_VECTOR_SHUFFLE_PASS_H_

+ 13 - 3
3rdparty/spirv-tools/source/opt/optimizer.cpp

@@ -224,6 +224,7 @@ Optimizer& Optimizer::RegisterVulkanToWebGPUPasses() {
   return RegisterPass(CreateStripDebugInfoPass())
       .RegisterPass(CreateStripAtomicCounterMemoryPass())
       .RegisterPass(CreateGenerateWebGPUInitializersPass())
+      .RegisterPass(CreateLegalizeVectorShufflePass())
       .RegisterPass(CreateEliminateDeadConstantPass())
       .RegisterPass(CreateFlattenDecorationPass())
       .RegisterPass(CreateAggressiveDCEPass())
@@ -466,6 +467,8 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
     RegisterLegalizationPasses();
   } else if (pass_name == "generate-webgpu-initializers") {
     RegisterPass(CreateGenerateWebGPUInitializersPass());
+  } else if (pass_name == "legalize-vector-shuffle") {
+    RegisterPass(CreateLegalizeVectorShufflePass());
   } else {
     Errorf(consumer(), nullptr, {},
            "Unknown flag '--%s'. Use --help for a list of valid flags",
@@ -526,10 +529,12 @@ bool Optimizer::Run(const uint32_t* original_binary,
     binary_changed = true;
   } else if (status == opt::Pass::Status::SuccessWithoutChange) {
     if (optimized_binary->size() != original_binary_size ||
-        (memcmp(optimized_binary->data(), original_binary, original_binary_size) != 0)) {
+        (memcmp(optimized_binary->data(), original_binary,
+                original_binary_size) != 0)) {
       binary_changed = true;
-      Logf(consumer(), SPV_MSG_WARNING, nullptr, {},
-           "Binary unexpectedly changed despite optimizer saying there was no change");
+      Log(consumer(), SPV_MSG_WARNING, nullptr, {},
+          "Binary unexpectedly changed despite optimizer saying there was no "
+          "change");
     }
   }
 
@@ -856,4 +861,9 @@ Optimizer::PassToken CreateFixStorageClassPass() {
       MakeUnique<opt::FixStorageClass>());
 }
 
+Optimizer::PassToken CreateLegalizeVectorShufflePass() {
+  return MakeUnique<Optimizer::PassToken::Impl>(
+      MakeUnique<opt::LegalizeVectorShufflePass>());
+}
+
 }  // namespace spvtools

+ 1 - 0
3rdparty/spirv-tools/source/opt/passes.h

@@ -41,6 +41,7 @@
 #include "source/opt/inline_exhaustive_pass.h"
 #include "source/opt/inline_opaque_pass.h"
 #include "source/opt/inst_bindless_check_pass.h"
+#include "source/opt/legalize_vector_shuffle_pass.h"
 #include "source/opt/licm_pass.h"
 #include "source/opt/local_access_chain_convert_pass.h"
 #include "source/opt/local_redundancy_elimination.h"

+ 1 - 1
3rdparty/spirv-tools/source/reduce/change_operand_reduction_opportunity.cpp

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "change_operand_reduction_opportunity.h"
+#include "source/reduce/change_operand_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 4 - 6
3rdparty/spirv-tools/source/reduce/change_operand_reduction_opportunity.h

@@ -15,22 +15,20 @@
 #ifndef SOURCE_REDUCE_CHANGE_OPERAND_REDUCTION_OPPORTUNITY_H_
 #define SOURCE_REDUCE_CHANGE_OPERAND_REDUCTION_OPPORTUNITY_H_
 
-#include "reduction_opportunity.h"
 #include "source/opt/instruction.h"
+#include "source/reduce/reduction_opportunity.h"
 #include "spirv-tools/libspirv.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
-
 // An opportunity to replace an id operand of an instruction with some other id.
 class ChangeOperandReductionOpportunity : public ReductionOpportunity {
  public:
   // Constructs the opportunity to replace operand |operand_index| of |inst|
   // with |new_id|.
-  ChangeOperandReductionOpportunity(Instruction* inst, uint32_t operand_index,
-                                    uint32_t new_id)
+  ChangeOperandReductionOpportunity(opt::Instruction* inst,
+                                    uint32_t operand_index, uint32_t new_id)
       : inst_(inst),
         operand_index_(operand_index),
         original_id_(inst->GetOperand(operand_index).words[0]),
@@ -43,7 +41,7 @@ class ChangeOperandReductionOpportunity : public ReductionOpportunity {
   void Apply() override;
 
  private:
-  Instruction* const inst_;
+  opt::Instruction* const inst_;
   const uint32_t operand_index_;
   const uint32_t original_id_;
   const spv_operand_type_t original_type_;

+ 8 - 5
3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp

@@ -12,15 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "merge_blocks_reduction_opportunity.h"
-#include "source/opt/block_merge_util.h"
+#include "source/reduce/merge_blocks_reduction_opportunity.h"
 
+#include "source/opt/block_merge_util.h"
 #include "source/opt/ir_context.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::BasicBlock;
+using opt::Function;
+using opt::IRContext;
 
 MergeBlocksReductionOpportunity::MergeBlocksReductionOpportunity(
     IRContext* context, Function* function, BasicBlock* block) {
@@ -48,7 +50,8 @@ bool MergeBlocksReductionOpportunity::PreconditionHolds() {
          "predecessor must be present.");
   const uint32_t predecessor_id = predecessors[0];
   BasicBlock* predecessor_block = context_->get_instr_block(predecessor_id);
-  return blockmergeutil::CanMergeWithSuccessor(context_, predecessor_block);
+  return opt::blockmergeutil::CanMergeWithSuccessor(context_,
+                                                    predecessor_block);
 }
 
 void MergeBlocksReductionOpportunity::Apply() {
@@ -65,7 +68,7 @@ void MergeBlocksReductionOpportunity::Apply() {
   // We need an iterator pointing to the predecessor, hence the loop.
   for (auto bi = function_->begin(); bi != function_->end(); ++bi) {
     if (bi->id() == predecessor_id) {
-      blockmergeutil::MergeWithSuccessor(context_, function_, bi);
+      opt::blockmergeutil::MergeWithSuccessor(context_, function_, bi);
       // Block merging changes the control flow graph, so invalidate it.
       context_->InvalidateAnalysesExceptFor(IRContext::Analysis::kAnalysisNone);
       return;

+ 1 - 1
3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.h

@@ -15,9 +15,9 @@
 #ifndef SOURCE_REDUCE_MERGE_BLOCKS_REDUCTION_OPPORTUNITY_H_
 #define SOURCE_REDUCE_MERGE_BLOCKS_REDUCTION_OPPORTUNITY_H_
 
-#include "reduction_opportunity.h"
 #include "source/opt/basic_block.h"
 #include "source/opt/function.h"
+#include "source/reduce/reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 3 - 3
3rdparty/spirv-tools/source/reduce/merge_blocks_reduction_opportunity_finder.cpp

@@ -19,7 +19,7 @@
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
 
 std::string MergeBlocksReductionOpportunityFinder::GetName() const {
   return "MergeBlocksReductionOpportunityFinder";
@@ -27,14 +27,14 @@ std::string MergeBlocksReductionOpportunityFinder::GetName() const {
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 MergeBlocksReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
 
   // Consider every block in every function.
   for (auto& function : *context->module()) {
     for (auto& block : function) {
       // See whether it is possible to merge this block with its successor.
-      if (blockmergeutil::CanMergeWithSuccessor(context, &block)) {
+      if (opt::blockmergeutil::CanMergeWithSuccessor(context, &block)) {
         // It is, so record an opportunity to do this.
         result.push_back(spvtools::MakeUnique<MergeBlocksReductionOpportunity>(
             context, &function, &block));

+ 2 - 2
3rdparty/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp

@@ -20,11 +20,11 @@
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 OperandToConstReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
   assert(result.empty());
 

+ 10 - 7
3rdparty/spirv-tools/source/reduce/operand_to_dominating_id_reduction_opportunity_finder.cpp

@@ -12,18 +12,21 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "operand_to_dominating_id_reduction_opportunity_finder.h"
-#include "change_operand_reduction_opportunity.h"
+#include "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h"
+
 #include "source/opt/instruction.h"
+#include "source/reduce/change_operand_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::Function;
+using opt::IRContext;
+using opt::Instruction;
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 OperandToDominatingIdReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
 
   // Go through every instruction in every block, considering it as a potential
@@ -58,9 +61,9 @@ OperandToDominatingIdReductionOpportunityFinder::GetAvailableOpportunities(
 void OperandToDominatingIdReductionOpportunityFinder::
     GetOpportunitiesForDominatingInst(
         std::vector<std::unique_ptr<ReductionOpportunity>>* opportunities,
-        opt::Instruction* candidate_dominator,
-        opt::Function::iterator candidate_dominator_block,
-        opt::Function* function, opt::IRContext* context) const {
+        Instruction* candidate_dominator,
+        Function::iterator candidate_dominator_block, Function* function,
+        IRContext* context) const {
   assert(candidate_dominator->HasResultId());
   assert(candidate_dominator->type_id());
   auto dominator_analysis = context->GetDominatorAnalysis(function);

+ 1 - 1
3rdparty/spirv-tools/source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h

@@ -15,7 +15,7 @@
 #ifndef SOURCE_REDUCE_OPERAND_TO_DOMINATING_ID_REDUCTION_OPPORTUNITY_FINDER_H_
 #define SOURCE_REDUCE_OPERAND_TO_DOMINATING_ID_REDUCTION_OPPORTUNITY_FINDER_H_
 
-#include "reduction_opportunity_finder.h"
+#include "source/reduce/reduction_opportunity_finder.h"
 
 namespace spvtools {
 namespace reduce {

+ 1 - 1
3rdparty/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp

@@ -20,7 +20,7 @@
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities(

+ 5 - 2
3rdparty/spirv-tools/source/reduce/reducer.cpp

@@ -12,6 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "source/reduce/reducer.h"
+
 #include <cassert>
 #include <sstream>
 
@@ -19,6 +21,7 @@
 #include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
 #include "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h"
 #include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
+#include "source/reduce/remove_block_reduction_opportunity_finder.h"
 #include "source/reduce/remove_function_reduction_opportunity_finder.h"
 #include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
 #include "source/reduce/remove_selection_reduction_opportunity_finder.h"
@@ -26,8 +29,6 @@
 #include "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h"
 #include "source/spirv_reducer_options.h"
 
-#include "reducer.h"
-
 namespace spvtools {
 namespace reduce {
 
@@ -186,6 +187,8 @@ void Reducer::AddDefaultReductionPasses() {
       spvtools::MakeUnique<MergeBlocksReductionOpportunityFinder>());
   AddReductionPass(
       spvtools::MakeUnique<RemoveFunctionReductionOpportunityFinder>());
+  AddReductionPass(
+      spvtools::MakeUnique<RemoveBlockReductionOpportunityFinder>());
   AddReductionPass(
       spvtools::MakeUnique<RemoveSelectionReductionOpportunityFinder>());
 }

+ 1 - 2
3rdparty/spirv-tools/source/reduce/reducer.h

@@ -18,10 +18,9 @@
 #include <functional>
 #include <string>
 
+#include "source/reduce/reduction_pass.h"
 #include "spirv-tools/libspirv.hpp"
 
-#include "reduction_pass.h"
-
 namespace spvtools {
 namespace reduce {
 

+ 1 - 1
3rdparty/spirv-tools/source/reduce/reduction_opportunity.cpp

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduction_opportunity.h"
+#include "source/reduce/reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 1 - 1
3rdparty/spirv-tools/source/reduce/reduction_opportunity_finder.h

@@ -15,8 +15,8 @@
 #ifndef SOURCE_REDUCE_REDUCTION_OPPORTUNITY_FINDER_H_
 #define SOURCE_REDUCE_REDUCTION_OPPORTUNITY_FINDER_H_
 
-#include "reduction_opportunity.h"
 #include "source/opt/ir_context.h"
+#include "source/reduce/reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 2 - 2
3rdparty/spirv-tools/source/reduce/reduction_pass.cpp

@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <algorithm>
+#include "source/reduce/reduction_pass.h"
 
-#include "reduction_pass.h"
+#include <algorithm>
 
 #include "source/opt/build_module.h"
 

+ 2 - 1
3rdparty/spirv-tools/source/reduce/reduction_util.cpp

@@ -19,7 +19,8 @@
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
+using opt::Instruction;
 
 uint32_t FindOrCreateGlobalUndef(IRContext* context, uint32_t type_id) {
   for (auto& inst : context->module()->types_values()) {

+ 3 - 2
3rdparty/spirv-tools/source/reduce/remove_block_reduction_opportunity.cpp

@@ -12,14 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "remove_block_reduction_opportunity.h"
+#include "source/reduce/remove_block_reduction_opportunity.h"
 
 #include "source/opt/ir_context.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::BasicBlock;
+using opt::Function;
 
 RemoveBlockReductionOpportunity::RemoveBlockReductionOpportunity(
     Function* function, BasicBlock* block)

+ 1 - 1
3rdparty/spirv-tools/source/reduce/remove_block_reduction_opportunity.h

@@ -15,9 +15,9 @@
 #ifndef SOURCE_REDUCE_REMOVE_BLOCK_REDUCTION_OPPORTUNITY_H_
 #define SOURCE_REDUCE_REMOVE_BLOCK_REDUCTION_OPPORTUNITY_H_
 
-#include "reduction_opportunity.h"
 #include "source/opt/basic_block.h"
 #include "source/opt/function.h"
+#include "source/reduce/reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 7 - 5
3rdparty/spirv-tools/source/reduce/remove_block_reduction_opportunity_finder.cpp

@@ -13,12 +13,15 @@
 // limitations under the License.
 
 #include "source/reduce/remove_block_reduction_opportunity_finder.h"
+
 #include "source/reduce/remove_block_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::Function;
+using opt::IRContext;
+using opt::Instruction;
 
 std::string RemoveBlockReductionOpportunityFinder::GetName() const {
   return "RemoveBlockReductionOpportunityFinder";
@@ -26,7 +29,7 @@ std::string RemoveBlockReductionOpportunityFinder::GetName() const {
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 RemoveBlockReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
 
   // Consider every block in every function.
@@ -42,8 +45,7 @@ RemoveBlockReductionOpportunityFinder::GetAvailableOpportunities(
 }
 
 bool RemoveBlockReductionOpportunityFinder::IsBlockValidOpportunity(
-    opt::IRContext* context, opt::Function& function,
-    opt::Function::iterator& bi) {
+    IRContext* context, Function& function, Function::iterator& bi) {
   assert(bi != function.end() && "Block iterator was out of bounds");
 
   // Don't remove first block; we don't want to end up with no blocks.
@@ -65,7 +67,7 @@ bool RemoveBlockReductionOpportunityFinder::IsBlockValidOpportunity(
 }
 
 bool RemoveBlockReductionOpportunityFinder::
-    BlockInstructionsHaveNoOutsideReferences(opt::IRContext* context,
+    BlockInstructionsHaveNoOutsideReferences(IRContext* context,
                                              const Function::iterator& bi) {
   // Get all instructions in block.
   std::unordered_set<uint32_t> instructions_in_block;

+ 2 - 1
3rdparty/spirv-tools/source/reduce/remove_function_reduction_opportunity.cpp

@@ -12,7 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "remove_function_reduction_opportunity.h"
+#include "source/reduce/remove_function_reduction_opportunity.h"
+
 #include "source/opt/eliminate_dead_functions_util.h"
 
 namespace spvtools {

+ 1 - 1
3rdparty/spirv-tools/source/reduce/remove_function_reduction_opportunity.h

@@ -15,8 +15,8 @@
 #ifndef SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_H_
 #define SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_H_
 
-#include "reduction_opportunity.h"
 #include "source/opt/function.h"
+#include "source/reduce/reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 3 - 2
3rdparty/spirv-tools/source/reduce/remove_function_reduction_opportunity_finder.cpp

@@ -12,8 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "remove_function_reduction_opportunity_finder.h"
-#include "remove_function_reduction_opportunity.h"
+#include "source/reduce/remove_function_reduction_opportunity_finder.h"
+
+#include "source/reduce/remove_function_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {

+ 2 - 2
3rdparty/spirv-tools/source/reduce/remove_instruction_reduction_opportunity.cpp

@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "source/opt/ir_context.h"
+#include "source/reduce/remove_instruction_reduction_opportunity.h"
 
-#include "remove_instruction_reduction_opportunity.h"
+#include "source/opt/ir_context.h"
 
 namespace spvtools {
 namespace reduce {

+ 3 - 5
3rdparty/spirv-tools/source/reduce/remove_instruction_reduction_opportunity.h

@@ -15,19 +15,17 @@
 #ifndef SOURCE_REDUCE_REMOVE_INSTRUCTION_REDUCTION_OPPORTUNITY_H_
 #define SOURCE_REDUCE_REMOVE_INSTRUCTION_REDUCTION_OPPORTUNITY_H_
 
-#include "reduction_opportunity.h"
 #include "source/opt/instruction.h"
+#include "source/reduce/reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
-
 // An opportunity to remove an instruction from the SPIR-V module.
 class RemoveInstructionReductionOpportunity : public ReductionOpportunity {
  public:
   // Constructs the opportunity to remove |inst|.
-  explicit RemoveInstructionReductionOpportunity(Instruction* inst)
+  explicit RemoveInstructionReductionOpportunity(opt::Instruction* inst)
       : inst_(inst) {}
 
   // Always returns true, as this opportunity can always be applied.
@@ -37,7 +35,7 @@ class RemoveInstructionReductionOpportunity : public ReductionOpportunity {
   void Apply() override;
 
  private:
-  Instruction* inst_;
+  opt::Instruction* inst_;
 };
 
 }  // namespace reduce

+ 5 - 4
3rdparty/spirv-tools/source/reduce/remove_opname_instruction_reduction_opportunity_finder.cpp

@@ -12,19 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "remove_opname_instruction_reduction_opportunity_finder.h"
-#include "remove_instruction_reduction_opportunity.h"
+#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
+
 #include "source/opcode.h"
 #include "source/opt/instruction.h"
+#include "source/reduce/remove_instruction_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 RemoveOpNameInstructionReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
 
   for (auto& inst : context->module()->debugs2()) {

+ 1 - 1
3rdparty/spirv-tools/source/reduce/remove_opname_instruction_reduction_opportunity_finder.h

@@ -15,7 +15,7 @@
 #ifndef SOURCE_REDUCE_REMOVE_OPNAME_INSTRUCTION_REDUCTION_OPPORTUNITY_FINDER_H_
 #define SOURCE_REDUCE_REMOVE_OPNAME_INSTRUCTION_REDUCTION_OPPORTUNITY_FINDER_H_
 
-#include "reduction_opportunity_finder.h"
+#include "source/reduce/reduction_opportunity_finder.h"
 
 namespace spvtools {
 namespace reduce {

+ 6 - 4
3rdparty/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp

@@ -19,7 +19,9 @@
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::BasicBlock;
+using opt::IRContext;
+using opt::Instruction;
 
 namespace {
 const uint32_t kMergeNodeIndex = 0;
@@ -32,7 +34,7 @@ std::string RemoveSelectionReductionOpportunityFinder::GetName() const {
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 RemoveSelectionReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   // Get all loop merge and continue blocks so we can check for these later.
   std::unordered_set<uint32_t> merge_and_continue_blocks_from_loops;
   for (auto& function : *context->module()) {
@@ -71,8 +73,8 @@ RemoveSelectionReductionOpportunityFinder::GetAvailableOpportunities(
 }
 
 bool RemoveSelectionReductionOpportunityFinder::CanOpSelectionMergeBeRemoved(
-    opt::IRContext* context, const opt::BasicBlock& header_block,
-    opt::Instruction* merge_instruction,
+    IRContext* context, const BasicBlock& header_block,
+    Instruction* merge_instruction,
     std::unordered_set<uint32_t> merge_and_continue_blocks_from_loops) {
   assert(header_block.GetMergeInst() == merge_instruction &&
          "CanOpSelectionMergeBeRemoved(...): header block and merge "

+ 5 - 4
3rdparty/spirv-tools/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp

@@ -12,19 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "remove_unreferenced_instruction_reduction_opportunity_finder.h"
-#include "remove_instruction_reduction_opportunity.h"
+#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
+
 #include "source/opcode.h"
 #include "source/opt/instruction.h"
+#include "source/reduce/remove_instruction_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 RemoveUnreferencedInstructionReductionOpportunityFinder::
-    GetAvailableOpportunities(opt::IRContext* context) const {
+    GetAvailableOpportunities(IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
 
   for (auto& function : *context->module()) {

+ 1 - 1
3rdparty/spirv-tools/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h

@@ -15,7 +15,7 @@
 #ifndef SOURCE_REDUCE_REMOVE_UNREFERENCED_INSTRUCTION_REDUCTION_OPPORTUNITY_FINDER_H_
 #define SOURCE_REDUCE_REMOVE_UNREFERENCED_INSTRUCTION_REDUCTION_OPPORTUNITY_FINDER_H_
 
-#include "reduction_opportunity_finder.h"
+#include "source/reduce/reduction_opportunity_finder.h"
 
 namespace spvtools {
 namespace reduce {

+ 7 - 2
3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp

@@ -21,6 +21,11 @@
 namespace spvtools {
 namespace reduce {
 
+using opt::BasicBlock;
+using opt::IRContext;
+using opt::Instruction;
+using opt::Operand;
+
 namespace {
 const uint32_t kMergeNodeIndex = 0;
 }  // namespace
@@ -208,8 +213,8 @@ void StructuredLoopToSelectionReductionOpportunity::ChangeLoopToSelection() {
   // the "else" branch be the merge block.
   auto terminator = loop_construct_header_->terminator();
   if (terminator->opcode() == SpvOpBranch) {
-    analysis::Bool temp;
-    const analysis::Bool* bool_type =
+    opt::analysis::Bool temp;
+    const opt::analysis::Bool* bool_type =
         context_->get_type_mgr()->GetRegisteredType(&temp)->AsBool();
     auto const_mgr = context_->get_constant_mgr();
     auto true_const = const_mgr->GetConstant(bool_type, {1});

+ 11 - 11
3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.h

@@ -23,8 +23,6 @@
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
-
 // An opportunity to replace a structured loop with a selection.
 class StructuredLoopToSelectionReductionOpportunity
     : public ReductionOpportunity {
@@ -32,8 +30,8 @@ class StructuredLoopToSelectionReductionOpportunity
   // Constructs an opportunity from a loop header block and the function that
   // encloses it.
   explicit StructuredLoopToSelectionReductionOpportunity(
-      IRContext* context, BasicBlock* loop_construct_header,
-      Function* enclosing_function)
+      opt::IRContext* context, opt::BasicBlock* loop_construct_header,
+      opt::Function* enclosing_function)
       : context_(context),
         loop_construct_header_(loop_construct_header),
         enclosing_function_(enclosing_function) {}
@@ -67,11 +65,12 @@ class StructuredLoopToSelectionReductionOpportunity
   // Removes any components of |to_block|'s phi instructions relating to
   // |from_id|.
   void AdaptPhiInstructionsForRemovedEdge(uint32_t from_id,
-                                          BasicBlock* to_block);
+                                          opt::BasicBlock* to_block);
 
   // Adds components to |to_block|'s phi instructions to account for a new
   // incoming edge from |from_id|.
-  void AdaptPhiInstructionsForAddedEdge(uint32_t from_id, BasicBlock* to_block);
+  void AdaptPhiInstructionsForAddedEdge(uint32_t from_id,
+                                        opt::BasicBlock* to_block);
 
   // Turns the OpLoopMerge for the loop into OpSelectionMerge, and adapts the
   // following branch instruction accordingly.
@@ -87,9 +86,10 @@ class StructuredLoopToSelectionReductionOpportunity
   // 2) |def| is an OpVariable
   // 3) |use| is part of an OpPhi, with associated incoming block b, and |def|
   // dominates b.
-  bool DefinitionSufficientlyDominatesUse(Instruction* def, Instruction* use,
+  bool DefinitionSufficientlyDominatesUse(opt::Instruction* def,
+                                          opt::Instruction* use,
                                           uint32_t use_index,
-                                          BasicBlock& def_block);
+                                          opt::BasicBlock& def_block);
 
   // Checks whether the global value list has an OpVariable of the given pointer
   // type, adding one if not, and returns the id of such an OpVariable.
@@ -105,9 +105,9 @@ class StructuredLoopToSelectionReductionOpportunity
   // be factored out in due course.
   uint32_t FindOrCreateFunctionVariable(uint32_t pointer_type_id);
 
-  IRContext* context_;
-  BasicBlock* loop_construct_header_;
-  Function* enclosing_function_;
+  opt::IRContext* context_;
+  opt::BasicBlock* loop_construct_header_;
+  opt::Function* enclosing_function_;
 };
 
 }  // namespace reduce

+ 5 - 4
3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity_finder.cpp

@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "structured_loop_to_selection_reduction_opportunity_finder.h"
-#include "structured_loop_to_selection_reduction_opportunity.h"
+#include "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h"
+
+#include "source/reduce/structured_loop_to_selection_reduction_opportunity.h"
 
 namespace spvtools {
 namespace reduce {
 
-using namespace opt;
+using opt::IRContext;
 
 namespace {
 const uint32_t kMergeNodeIndex = 0;
@@ -27,7 +28,7 @@ const uint32_t kContinueNodeIndex = 1;
 
 std::vector<std::unique_ptr<ReductionOpportunity>>
 StructuredLoopToSelectionReductionOpportunityFinder::GetAvailableOpportunities(
-    opt::IRContext* context) const {
+    IRContext* context) const {
   std::vector<std::unique_ptr<ReductionOpportunity>> result;
 
   std::set<uint32_t> merge_block_ids;

+ 1 - 1
3rdparty/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h

@@ -15,7 +15,7 @@
 #ifndef SOURCE_REDUCE_STRUCTURED_LOOP_TO_SELECTION_REDUCTION_OPPORTUNITY_FINDER_H
 #define SOURCE_REDUCE_STRUCTURED_LOOP_TO_SELECTION_REDUCTION_OPPORTUNITY_FINDER_H
 
-#include "reduction_opportunity_finder.h"
+#include "source/reduce/reduction_opportunity_finder.h"
 
 namespace spvtools {
 namespace reduce {

+ 15 - 11
3rdparty/spirv-tools/source/val/validate_image.cpp

@@ -1362,11 +1362,13 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
            << " components, but given only " << actual_coord_size;
   }
 
-  if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData &&
-      !_.HasCapability(SpvCapabilityStorageImageReadWithoutFormat)) {
-    return _.diag(SPV_ERROR_INVALID_DATA, inst)
-           << "Capability StorageImageReadWithoutFormat is required to "
-           << "read storage image";
+  if (spvIsVulkanEnv(_.context()->target_env)) {
+    if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData &&
+        !_.HasCapability(SpvCapabilityStorageImageReadWithoutFormat)) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Capability StorageImageReadWithoutFormat is required to "
+             << "read storage image";
+    }
   }
 
   if (inst->words().size() <= 5) return SPV_SUCCESS;
@@ -1439,12 +1441,14 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) {
     }
   }
 
-  if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData &&
-      !_.HasCapability(SpvCapabilityStorageImageWriteWithoutFormat)) {
-    return _.diag(SPV_ERROR_INVALID_DATA, inst)
-           << "Capability StorageImageWriteWithoutFormat is required to "
-              "write "
-           << "to storage image";
+  if (spvIsVulkanEnv(_.context()->target_env)) {
+    if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData &&
+        !_.HasCapability(SpvCapabilityStorageImageWriteWithoutFormat)) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Capability StorageImageWriteWithoutFormat is required to "
+                "write "
+             << "to storage image";
+    }
   }
 
   if (inst->words().size() <= 4) return SPV_SUCCESS;

+ 1 - 0
3rdparty/spirv-tools/test/opt/CMakeLists.txt

@@ -54,6 +54,7 @@ add_spvtools_unittest(TARGET opt
        ir_context_test.cpp
        ir_loader_test.cpp
        iterator_test.cpp
+       legalize_vector_shuffle_test.cpp
        line_debug_info_test.cpp
        local_access_chain_convert_test.cpp
        local_redundancy_elimination_test.cpp

+ 19 - 0
3rdparty/spirv-tools/test/opt/fix_storage_class_test.cpp

@@ -440,6 +440,25 @@ TEST_F(FixStorageClassTest, FixSelect) {
   SinglePassRunAndMatch<FixStorageClass>(text, false);
 }
 
+TEST_F(FixStorageClassTest, BitCast) {
+  const std::string text = R"(OpCapability VariablePointersStorageBuffer
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %1 "main"
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%_ptr_Output_void = OpTypePointer Output %void
+%_ptr_Private__ptr_Output_void = OpTypePointer Private %_ptr_Output_void
+%6 = OpVariable %_ptr_Private__ptr_Output_void Private
+%1 = OpFunction %void Inline %3
+%7 = OpLabel
+%8 = OpBitcast %_ptr_Output_void %6
+OpReturn
+OpFunctionEnd
+)";
+
+  SinglePassRunAndCheck<FixStorageClass>(text, text, false);
+}
+
 }  // namespace
 }  // namespace opt
 }  // namespace spvtools

+ 81 - 0
3rdparty/spirv-tools/test/opt/legalize_vector_shuffle_test.cpp

@@ -0,0 +1,81 @@
+// Copyright (c) 2019 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 LegalizeVectorShuffleTest = PassTest<::testing::Test>;
+
+void operator+=(std::vector<const char*>& lhs, const char* rhs) {
+  lhs.push_back(rhs);
+}
+
+void operator+=(std::vector<const char*>& lhs,
+                const std::vector<const char*> rhs) {
+  for (auto elem : rhs) lhs.push_back(elem);
+}
+
+std::vector<const char*> header = {
+    "OpCapability Shader",
+    "OpCapability VulkanMemoryModelKHR",
+    "OpExtension \"SPV_KHR_vulkan_memory_model\"",
+    "OpMemoryModel Logical VulkanKHR",
+    "OpEntryPoint Vertex %1 \"shader\"",
+    "%uint = OpTypeInt 32 0",
+    "%v3uint = OpTypeVector %uint 3"};
+
+std::string GetTestString(const char* shuffle) {
+  std::vector<const char*> result = header;
+  result += {"%_ptr_Function_v3uint = OpTypePointer Function %v3uint",
+             "%void = OpTypeVoid",
+             "%6 = OpTypeFunction %void",
+             "%1 = OpFunction %void None %6",
+             "%7 = OpLabel",
+             "%8 = OpVariable %_ptr_Function_v3uint Function",
+             "%9 = OpLoad %v3uint %8",
+             "%10 = OpLoad %v3uint %8"};
+  result += shuffle;
+  result += {"OpReturn", "OpFunctionEnd"};
+  return JoinAllInsts(result);
+}
+
+TEST_F(LegalizeVectorShuffleTest, Changed) {
+  std::string input =
+      GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0xFFFFFFFF");
+  std::string expected =
+      GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0");
+
+  SinglePassRunAndCheck<LegalizeVectorShufflePass>(input, expected,
+                                                   /* skip_nop = */ false);
+}
+
+TEST_F(LegalizeVectorShuffleTest, FunctionUnchanged) {
+  std::string input =
+      GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0");
+  std::string expected =
+      GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0");
+
+  SinglePassRunAndCheck<LegalizeVectorShufflePass>(input, expected,
+                                                   /* skip_nop = */ false);
+}
+
+}  // namespace
+}  // namespace opt
+}  // namespace spvtools

+ 45 - 2
3rdparty/spirv-tools/test/opt/optimizer_test.cpp

@@ -237,7 +237,8 @@ TEST(Optimizer, VulkanToWebGPUModeSetsCorrectPasses) {
                                               "flatten-decorations",
                                               "strip-debug",
                                               "strip-atomic-counter-memory",
-                                              "generate-webgpu-initializers"};
+                                              "generate-webgpu-initializers",
+                                              "legalize-vector-shuffle"};
   std::sort(registered_passes.begin(), registered_passes.end());
   std::sort(expected_passes.begin(), expected_passes.end());
 
@@ -476,7 +477,49 @@ INSTANTIATE_TEST_SUITE_P(
          "OpReturn\n"
          "OpFunctionEnd\n",
          // pass
-         "generate-webgpu-initializers"}}));
+         "generate-webgpu-initializers"},
+        // Legalize Vector Shuffle
+        {// input
+         "OpCapability Shader\n"
+         "OpCapability VulkanMemoryModelKHR\n"
+         "OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
+         "OpMemoryModel Logical VulkanKHR\n"
+         "OpEntryPoint Vertex %1 \"shader\"\n"
+         "%uint = OpTypeInt 32 0\n"
+         "%v3uint = OpTypeVector %uint 3\n"
+         "%_ptr_Function_v3uint = OpTypePointer Function %v3uint\n"
+         "%void = OpTypeVoid\n"
+         "%6 = OpTypeFunction %void\n"
+         "%1 = OpFunction %void None %6\n"
+         "%7 = OpLabel\n"
+         "%8 = OpVariable %_ptr_Function_v3uint Function\n"
+         "%9 = OpLoad %v3uint %8\n"
+         "%10 = OpLoad %v3uint %8\n"
+         "%11 = OpVectorShuffle %v3uint %9 %10 2 1 0xFFFFFFFF\n"
+         "OpReturn\n"
+         "OpFunctionEnd\n",
+         // expected
+         "OpCapability Shader\n"
+         "OpCapability VulkanMemoryModelKHR\n"
+         "OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
+         "OpMemoryModel Logical VulkanKHR\n"
+         "OpEntryPoint Vertex %1 \"shader\"\n"
+         "%uint = OpTypeInt 32 0\n"
+         "%v3uint = OpTypeVector %uint 3\n"
+         "%_ptr_Function_v3uint = OpTypePointer Function %v3uint\n"
+         "%void = OpTypeVoid\n"
+         "%6 = OpTypeFunction %void\n"
+         "%12 = OpConstantNull %v3uint\n"
+         "%1 = OpFunction %void None %6\n"
+         "%7 = OpLabel\n"
+         "%8 = OpVariable %_ptr_Function_v3uint Function %12\n"
+         "%9 = OpLoad %v3uint %8\n"
+         "%10 = OpLoad %v3uint %8\n"
+         "%11 = OpVectorShuffle %v3uint %9 %10 2 1 0\n"
+         "OpReturn\n"
+         "OpFunctionEnd\n",
+         // pass
+         "legalize-vector-shuffle"}}));
 
 }  // namespace
 }  // namespace opt

+ 3 - 2
3rdparty/spirv-tools/test/reduce/merge_blocks_test.cpp

@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
-#include "source/opt/build_module.h"
 #include "source/reduce/merge_blocks_reduction_opportunity_finder.h"
+
+#include "source/opt/build_module.h"
 #include "source/reduce/reduction_opportunity.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {

+ 4 - 2
3rdparty/spirv-tools/test/reduce/operand_to_constant_test.cpp

@@ -12,10 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
-#include "source/opt/build_module.h"
 #include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
 
+#include "source/opt/build_module.h"
+#include "source/reduce/reduction_opportunity.h"
+#include "test/reduce/reduce_test_util.h"
+
 namespace spvtools {
 namespace reduce {
 namespace {

+ 4 - 2
3rdparty/spirv-tools/test/reduce/operand_to_dominating_id_test.cpp

@@ -12,10 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
-#include "source/opt/build_module.h"
 #include "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h"
 
+#include "source/opt/build_module.h"
+#include "source/reduce/reduction_opportunity.h"
+#include "test/reduce/reduce_test_util.h"
+
 namespace spvtools {
 namespace reduce {
 namespace {

+ 3 - 1
3rdparty/spirv-tools/test/reduce/operand_to_undef_test.cpp

@@ -12,8 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "source/opt/build_module.h"
 #include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
+
+#include "source/opt/build_module.h"
+#include "source/reduce/reduction_opportunity.h"
 #include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {

+ 17 - 1
3rdparty/spirv-tools/test/reduce/reduce_test_util.cpp

@@ -12,10 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
+#include "test/reduce/reduce_test_util.h"
 
 #include <iostream>
 
+#include "tools/io.h"
+
 namespace spvtools {
 namespace reduce {
 
@@ -92,5 +94,19 @@ void CLIMessageConsumer(spv_message_level_t level, const char*,
   }
 }
 
+void DumpShader(opt::IRContext* context, const char* filename) {
+  std::vector<uint32_t> binary;
+  context->module()->ToBinary(&binary, false);
+  DumpShader(binary, filename);
+}
+
+void DumpShader(const std::vector<uint32_t>& binary, const char* filename) {
+  auto write_file_succeeded =
+      WriteFile(filename, "wb", &binary[0], binary.size());
+  if (!write_file_succeeded) {
+    std::cerr << "Failed to dump shader" << std::endl;
+  }
+}
+
 }  // namespace reduce
 }  // namespace spvtools

+ 7 - 1
3rdparty/spirv-tools/test/reduce/reduce_test_util.h

@@ -16,7 +16,6 @@
 #define TEST_REDUCE_REDUCE_TEST_UTIL_H_
 
 #include "gtest/gtest.h"
-
 #include "source/opt/ir_context.h"
 #include "source/reduce/reduction_opportunity.h"
 #include "spirv-tools/libspirv.h"
@@ -63,6 +62,13 @@ void NopDiagnostic(spv_message_level_t /*level*/, const char* /*source*/,
 void CLIMessageConsumer(spv_message_level_t level, const char*,
                         const spv_position_t& position, const char* message);
 
+// Dumps the SPIRV-V module in |context| to file |filename|. Useful for
+// interactive debugging.
+void DumpShader(opt::IRContext* context, const char* filename);
+
+// Dumps |binary| to file |filename|. Useful for interactive debugging.
+void DumpShader(const std::vector<uint32_t>& binary, const char* filename);
+
 }  // namespace reduce
 }  // namespace spvtools
 

+ 2 - 2
3rdparty/spirv-tools/test/reduce/reducer_test.cpp

@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
+#include "source/reduce/reducer.h"
 
 #include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
-#include "source/reduce/reducer.h"
 #include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
 #include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {

+ 3 - 3
3rdparty/spirv-tools/test/reduce/remove_block_test.cpp

@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
+#include "source/reduce/remove_block_reduction_opportunity_finder.h"
+
 #include "source/opt/build_module.h"
 #include "source/reduce/reduction_opportunity.h"
-#include "source/reduce/remove_block_reduction_opportunity.h"
-#include "source/reduce/remove_block_reduction_opportunity_finder.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {

+ 3 - 2
3rdparty/spirv-tools/test/reduce/remove_function_test.cpp

@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
+#include "source/reduce/remove_function_reduction_opportunity_finder.h"
+
 #include "source/opt/build_module.h"
 #include "source/reduce/reduction_opportunity.h"
-#include "source/reduce/remove_function_reduction_opportunity_finder.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {

+ 2 - 2
3rdparty/spirv-tools/test/reduce/remove_opname_instruction_test.cpp

@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
+#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
 
 #include "source/opt/build_module.h"
 #include "source/reduce/reduction_opportunity.h"
 #include "source/reduce/reduction_pass.h"
-#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {

+ 2 - 2
3rdparty/spirv-tools/test/reduce/remove_selection_test.cpp

@@ -12,10 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "source/reduce/remove_selection_reduction_opportunity_finder.h"
+
 #include "source/opt/build_module.h"
 #include "source/reduce/reduction_opportunity.h"
-#include "source/reduce/reduction_pass.h"
-#include "source/reduce/remove_selection_reduction_opportunity_finder.h"
 #include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {

+ 2 - 3
3rdparty/spirv-tools/test/reduce/remove_unreferenced_instruction_test.cpp

@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
+#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
 
 #include "source/opt/build_module.h"
 #include "source/reduce/reduction_opportunity.h"
-#include "source/reduce/reduction_pass.h"
-#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
 #include "source/util/make_unique.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {

+ 4 - 2
3rdparty/spirv-tools/test/reduce/structured_loop_to_selection_test.cpp

@@ -12,10 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
-#include "source/opt/build_module.h"
 #include "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h"
 
+#include "source/opt/build_module.h"
+#include "source/reduce/reduction_opportunity.h"
+#include "test/reduce/reduce_test_util.h"
+
 namespace spvtools {
 namespace reduce {
 namespace {

+ 15 - 11
3rdparty/spirv-tools/test/reduce/validation_during_reduction_test.cpp

@@ -12,16 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "reduce_test_util.h"
-
 #include "source/reduce/reducer.h"
-#include "source/reduce/reduction_pass.h"
+
+#include "source/reduce/reduction_opportunity.h"
 #include "source/reduce/remove_instruction_reduction_opportunity.h"
+#include "test/reduce/reduce_test_util.h"
 
 namespace spvtools {
 namespace reduce {
 namespace {
 
+using opt::Function;
+using opt::IRContext;
+using opt::Instruction;
+
 // A dumb reduction opportunity finder that finds opportunities to remove global
 // values regardless of whether they are referenced. This is very likely to make
 // the resulting module invalid.  We use this to test the reducer's behavior in
@@ -40,7 +44,7 @@ class BlindlyRemoveGlobalValuesReductionOpportunityFinder
   // referenced (directly or indirectly) from elsewhere in the module, each such
   // opportunity will make the module invalid.
   std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
-      opt::IRContext* context) const final {
+      IRContext* context) const final {
     std::vector<std::unique_ptr<ReductionOpportunity>> result;
     for (auto& inst : context->module()->types_values()) {
       if (inst.HasResultId()) {
@@ -59,8 +63,8 @@ class BlindlyRemoveGlobalValuesReductionOpportunityFinder
 // limits are enforced.
 class OpVariableDuplicatorReductionOpportunity : public ReductionOpportunity {
  public:
-  OpVariableDuplicatorReductionOpportunity(Function* function_)
-      : function_(function_) {}
+  OpVariableDuplicatorReductionOpportunity(Function* function)
+      : function_(function) {}
 
   bool PreconditionHolds() override {
     Instruction* first_instruction = &*function_->begin()[0].begin();
@@ -98,7 +102,7 @@ class OpVariableDuplicatorReductionOpportunityFinder
   };
 
   std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
-      opt::IRContext* context) const final {
+      IRContext* context) const final {
     std::vector<std::unique_ptr<ReductionOpportunity>> result;
     for (auto& function : *context->module()) {
       Instruction* first_instruction = &*function.begin()[0].begin();
@@ -446,7 +450,7 @@ TEST(ValidationDuringReductionTest, CheckNotAlwaysInvalidCanMakeProgress) {
 
 // Sets up a Reducer for use in the CheckValidationOptions test; avoids
 // repetition.
-void setupReducerForCheckValidationOptions(Reducer* reducer) {
+void SetupReducerForCheckValidationOptions(Reducer* reducer) {
   reducer->SetMessageConsumer(NopDiagnostic);
 
   // Say that every module is interesting.
@@ -531,7 +535,7 @@ TEST(ValidationDuringReductionTest, CheckValidationOptions) {
   // always returns true.
   {
     Reducer reducer(env);
-    setupReducerForCheckValidationOptions(&reducer);
+    SetupReducerForCheckValidationOptions(&reducer);
 
     Reducer::ReductionResultStatus status =
         reducer.Run(std::vector<uint32_t>(binary_in), &binary_out,
@@ -547,7 +551,7 @@ TEST(ValidationDuringReductionTest, CheckValidationOptions) {
   // test always succeeds, and the finder yields infinite opportunities.
   {
     Reducer reducer(env);
-    setupReducerForCheckValidationOptions(&reducer);
+    SetupReducerForCheckValidationOptions(&reducer);
 
     Reducer::ReductionResultStatus status =
         reducer.Run(std::vector<uint32_t>(binary_in), &binary_out,
@@ -565,7 +569,7 @@ TEST(ValidationDuringReductionTest, CheckValidationOptions) {
   // validator limits.
   {
     Reducer reducer(env);
-    setupReducerForCheckValidationOptions(&reducer);
+    SetupReducerForCheckValidationOptions(&reducer);
 
     Reducer::ReductionResultStatus status =
         reducer.Run(std::vector<uint32_t>(binary_in), &binary_out,

+ 26 - 2
3rdparty/spirv-tools/test/val/val_image_test.cpp

@@ -2748,7 +2748,19 @@ TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormat) {
 )";
 
   CompileSuccessfully(GenerateShaderCode(body).c_str());
-  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
+  const std::string body = R"(
+%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
+%res1 = OpImageRead %u32vec4 %img %u32vec2_01
+)";
+
+  spv_target_env env = SPV_ENV_VULKAN_1_0;
+  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env).c_str(),
+                      env);
+  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("Capability StorageImageReadWithoutFormat is required "
                         "to read storage image"));
@@ -2954,7 +2966,19 @@ TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
 )";
 
   CompileSuccessfully(GenerateShaderCode(body).c_str());
-  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
+  const std::string body = R"(
+%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
+%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123
+)";
+
+  spv_target_env env = SPV_ENV_VULKAN_1_0;
+  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env).c_str(),
+                      env);
+  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   EXPECT_THAT(
       getDiagnosticString(),
       HasSubstr(

+ 21 - 5
3rdparty/spirv-tools/tools/reduce/reduce.cpp

@@ -18,6 +18,7 @@
 #include <functional>
 
 #include "source/opt/build_module.h"
+#include "source/opt/ir_context.h"
 #include "source/opt/log.h"
 #include "source/reduce/reducer.h"
 #include "source/spirv_reducer_options.h"
@@ -25,8 +26,6 @@
 #include "tools/io.h"
 #include "tools/util/cli_consumer.h"
 
-using namespace spvtools::reduce;
-
 namespace {
 
 using ErrorOrInt = std::pair<std::string, int>;
@@ -200,6 +199,23 @@ ReduceStatus ParseFlags(int argc, const char** argv, const char** in_file,
 
 }  // namespace
 
+// Dumps |binary| to file |filename|. Useful for interactive debugging.
+void DumpShader(const std::vector<uint32_t>& binary, const char* filename) {
+  auto write_file_succeeded =
+      WriteFile(filename, "wb", &binary[0], binary.size());
+  if (!write_file_succeeded) {
+    std::cerr << "Failed to dump shader" << std::endl;
+  }
+}
+
+// Dumps the SPIRV-V module in |context| to file |filename|. Useful for
+// interactive debugging.
+void DumpShader(spvtools::opt::IRContext* context, const char* filename) {
+  std::vector<uint32_t> binary;
+  context->module()->ToBinary(&binary, false);
+  DumpShader(binary, filename);
+}
+
 const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3;
 
 int main(int argc, const char** argv) {
@@ -223,7 +239,7 @@ int main(int argc, const char** argv) {
     return 2;
   }
 
-  Reducer reducer(target_env);
+  spvtools::reduce::Reducer reducer(target_env);
 
   reducer.SetInterestingnessFunction(
       [interestingness_test](std::vector<uint32_t> binary,
@@ -254,8 +270,8 @@ int main(int argc, const char** argv) {
   const auto reduction_status = reducer.Run(std::move(binary_in), &binary_out,
                                             reducer_options, validator_options);
 
-  if (reduction_status ==
-          Reducer::ReductionResultStatus::kInitialStateNotInteresting ||
+  if (reduction_status == spvtools::reduce::Reducer::ReductionResultStatus::
+                              kInitialStateNotInteresting ||
       !WriteFile<uint32_t>("_reduced_final.spv", "wb", binary_out.data(),
                            binary_out.size())) {
     return 1;