Update SPIR-V Tools to 7b8f00f00

Changes:
    7b8f00f00a spirv-opt: Fix OpCompositeInsert with Null Constant (#5008)
    40f5bf59c6 Revert "spirv-val: Multiple interface var with same SC (#4969)" (#5009)
    d9446130d5 Update BUILD.gn with recently added file (#5004)
    00018e58af Change EliminateDeadInputComponentsPass to EliminateDeadIOComponentsPass (#4997)
    9a6f4121f4 Fix missing declaration of std::numeric_limits (#5002)
    f33d152400 Add validation support for SPV_NV_shader_invocation_reorder. (#4979)

Commands:
    ./third_party/update-spirvtools.sh

Bug: b/123642959
Change-Id: I1950088a09d1175c080ada9ef8574349c40080c1
diff --git a/third_party/SPIRV-Tools/BUILD.gn b/third_party/SPIRV-Tools/BUILD.gn
index 2194bc5..39c0fee 100644
--- a/third_party/SPIRV-Tools/BUILD.gn
+++ b/third_party/SPIRV-Tools/BUILD.gn
@@ -542,6 +542,7 @@
     "source/val/validate_primitives.cpp",
     "source/val/validate_ray_query.cpp",
     "source/val/validate_ray_tracing.cpp",
+    "source/val/validate_ray_tracing_reorder.cpp",
     "source/val/validate_scopes.cpp",
     "source/val/validate_scopes.h",
     "source/val/validate_small_type_uses.cpp",
@@ -635,8 +636,8 @@
     "source/opt/eliminate_dead_functions_pass.h",
     "source/opt/eliminate_dead_functions_util.cpp",
     "source/opt/eliminate_dead_functions_util.h",
-    "source/opt/eliminate_dead_input_components_pass.cpp",
-    "source/opt/eliminate_dead_input_components_pass.h",
+    "source/opt/eliminate_dead_io_components_pass.cpp",
+    "source/opt/eliminate_dead_io_components_pass.h",
     "source/opt/eliminate_dead_members_pass.cpp",
     "source/opt/eliminate_dead_members_pass.h",
     "source/opt/eliminate_dead_output_stores_pass.cpp",
diff --git a/third_party/SPIRV-Tools/source/CMakeLists.txt b/third_party/SPIRV-Tools/source/CMakeLists.txt
index f904024..e85ec9d 100644
--- a/third_party/SPIRV-Tools/source/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/source/CMakeLists.txt
@@ -328,6 +328,7 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_primitives.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_query.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing_reorder.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_scopes.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_small_type_uses.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_type.cpp
diff --git a/third_party/SPIRV-Tools/source/opcode.cpp b/third_party/SPIRV-Tools/source/opcode.cpp
index c5006af..b1785cc 100644
--- a/third_party/SPIRV-Tools/source/opcode.cpp
+++ b/third_party/SPIRV-Tools/source/opcode.cpp
@@ -342,6 +342,7 @@
     // case spv::Op::OpTypeAccelerationStructureKHR: covered by
     // spv::Op::OpTypeAccelerationStructureNV
     case spv::Op::OpTypeRayQueryKHR:
+    case spv::Op::OpTypeHitObjectNV:
       return true;
     default:
       // In particular, OpTypeForwardPointer does not generate a type,
diff --git a/third_party/SPIRV-Tools/source/opt/CMakeLists.txt b/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
index 085c430..c34c38d 100644
--- a/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
@@ -47,7 +47,7 @@
   eliminate_dead_constant_pass.h
   eliminate_dead_functions_pass.h
   eliminate_dead_functions_util.h
-  eliminate_dead_input_components_pass.h
+  eliminate_dead_io_components_pass.h
   eliminate_dead_members_pass.h
   eliminate_dead_output_stores_pass.h
   empty_pass.h
@@ -166,7 +166,7 @@
   eliminate_dead_constant_pass.cpp
   eliminate_dead_functions_pass.cpp
   eliminate_dead_functions_util.cpp
-  eliminate_dead_input_components_pass.cpp
+  eliminate_dead_io_components_pass.cpp
   eliminate_dead_members_pass.cpp
   eliminate_dead_output_stores_pass.cpp
   feature_manager.cpp
diff --git a/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp b/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
index 19b39d6..14f2208 100644
--- a/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
+++ b/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
@@ -136,32 +136,38 @@
     std::vector<const analysis::Constant*> chain;
     std::vector<const analysis::Constant*> components;
     const analysis::Type* type = nullptr;
+    const uint32_t final_index = (inst->NumInOperands() - 1);
 
-    // Work down hierarchy and add all the indexes, not including the final
-    // index.
+    // Work down hierarchy of all indexes
     for (uint32_t i = 2; i < inst->NumInOperands(); ++i) {
-      if (composite->AsNullConstant()) {
-        // Return Null for the return type.
-        analysis::TypeManager* type_mgr = context->get_type_mgr();
-        return const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), {});
-      }
+      type = composite->type();
 
-      if (i != inst->NumInOperands() - 1) {
-        chain.push_back(composite);
+      if (composite->AsNullConstant()) {
+        // Make new composite so it can be inserted in the index with the
+        // non-null value
+        const auto new_composite = const_mgr->GetNullCompositeConstant(type);
+        // Keep track of any indexes along the way to last index
+        if (i != final_index) {
+          chain.push_back(new_composite);
+        }
+        components = new_composite->AsCompositeConstant()->GetComponents();
+      } else {
+        // Keep track of any indexes along the way to last index
+        if (i != final_index) {
+          chain.push_back(composite);
+        }
+        components = composite->AsCompositeConstant()->GetComponents();
       }
       const uint32_t index = inst->GetSingleWordInOperand(i);
-      components = composite->AsCompositeConstant()->GetComponents();
-      type = composite->AsCompositeConstant()->type();
       composite = components[index];
     }
 
     // Final index in hierarchy is inserted with new object.
-    const uint32_t final_index =
-        inst->GetSingleWordInOperand(inst->NumInOperands() - 1);
+    const uint32_t final_operand = inst->GetSingleWordInOperand(final_index);
     std::vector<uint32_t> ids;
     for (size_t i = 0; i < components.size(); i++) {
       const analysis::Constant* constant =
-          (i == final_index) ? object : components[i];
+          (i == final_operand) ? object : components[i];
       Instruction* member_inst = const_mgr->GetDefiningInstruction(constant);
       ids.push_back(member_inst->result_id());
     }
@@ -171,19 +177,16 @@
     for (size_t i = chain.size(); i > 0; i--) {
       // Need to insert any previous instruction into the module first.
       // Can't just insert in types_values_begin() because it will move above
-      // where the types are declared
-      for (Module::inst_iterator inst_iter = context->types_values_begin();
-           inst_iter != context->types_values_end(); ++inst_iter) {
-        Instruction* x = &*inst_iter;
-        if (inst->result_id() == x->result_id()) {
-          const_mgr->BuildInstructionAndAddToModule(new_constant, &inst_iter);
-          break;
-        }
-      }
+      // where the types are declared.
+      // Can't compare with location of inst because not all new added
+      // instructions are added to types_values_
+      auto iter = context->types_values_end();
+      Module::inst_iterator* pos = &iter;
+      const_mgr->BuildInstructionAndAddToModule(new_constant, pos);
 
       composite = chain[i - 1];
       components = composite->AsCompositeConstant()->GetComponents();
-      type = composite->AsCompositeConstant()->type();
+      type = composite->type();
       ids.clear();
       for (size_t k = 0; k < components.size(); k++) {
         const uint32_t index =
diff --git a/third_party/SPIRV-Tools/source/opt/constants.cpp b/third_party/SPIRV-Tools/source/opt/constants.cpp
index 9930b44..d70e27b 100644
--- a/third_party/SPIRV-Tools/source/opt/constants.cpp
+++ b/third_party/SPIRV-Tools/source/opt/constants.cpp
@@ -391,6 +391,43 @@
   return cst ? RegisterConstant(std::move(cst)) : nullptr;
 }
 
+const Constant* ConstantManager::GetNullCompositeConstant(const Type* type) {
+  std::vector<uint32_t> literal_words_or_id;
+
+  if (type->AsVector()) {
+    const Type* element_type = type->AsVector()->element_type();
+    const uint32_t null_id = GetNullConstId(element_type);
+    const uint32_t element_count = type->AsVector()->element_count();
+    for (uint32_t i = 0; i < element_count; i++) {
+      literal_words_or_id.push_back(null_id);
+    }
+  } else if (type->AsMatrix()) {
+    const Type* element_type = type->AsMatrix()->element_type();
+    const uint32_t null_id = GetNullConstId(element_type);
+    const uint32_t element_count = type->AsMatrix()->element_count();
+    for (uint32_t i = 0; i < element_count; i++) {
+      literal_words_or_id.push_back(null_id);
+    }
+  } else if (type->AsStruct()) {
+    // TODO (sfricke-lunarg) add proper struct support
+    return nullptr;
+  } else if (type->AsArray()) {
+    const Type* element_type = type->AsArray()->element_type();
+    const uint32_t null_id = GetNullConstId(element_type);
+    assert(type->AsArray()->length_info().words[0] ==
+               analysis::Array::LengthInfo::kConstant &&
+           "unexpected array length");
+    const uint32_t element_count = type->AsArray()->length_info().words[0];
+    for (uint32_t i = 0; i < element_count; i++) {
+      literal_words_or_id.push_back(null_id);
+    }
+  } else {
+    return nullptr;
+  }
+
+  return GetConstant(type, literal_words_or_id);
+}
+
 const Constant* ConstantManager::GetNumericVectorConstantWithWords(
     const Vector* type, const std::vector<uint32_t>& literal_words) {
   const auto* element_type = type->element_type();
@@ -445,18 +482,23 @@
   return c;
 }
 
-uint32_t ConstantManager::GetSIntConst(int32_t val) {
+uint32_t ConstantManager::GetSIntConstId(int32_t val) {
   Type* sint_type = context()->get_type_mgr()->GetSIntType();
   const Constant* c = GetConstant(sint_type, {static_cast<uint32_t>(val)});
   return GetDefiningInstruction(c)->result_id();
 }
 
-uint32_t ConstantManager::GetUIntConst(uint32_t val) {
+uint32_t ConstantManager::GetUIntConstId(uint32_t val) {
   Type* uint_type = context()->get_type_mgr()->GetUIntType();
   const Constant* c = GetConstant(uint_type, {val});
   return GetDefiningInstruction(c)->result_id();
 }
 
+uint32_t ConstantManager::GetNullConstId(const Type* type) {
+  const Constant* c = GetConstant(type, {});
+  return GetDefiningInstruction(c)->result_id();
+}
+
 std::vector<const analysis::Constant*> Constant::GetVectorComponents(
     analysis::ConstantManager* const_mgr) const {
   std::vector<const analysis::Constant*> components;
diff --git a/third_party/SPIRV-Tools/source/opt/constants.h b/third_party/SPIRV-Tools/source/opt/constants.h
index 588ca3e..410304e 100644
--- a/third_party/SPIRV-Tools/source/opt/constants.h
+++ b/third_party/SPIRV-Tools/source/opt/constants.h
@@ -520,6 +520,14 @@
                                                    literal_words_or_ids.end()));
   }
 
+  // Takes a type and creates a OpConstantComposite
+  // This allows a
+  // OpConstantNull %composite_type
+  // to become a
+  // OpConstantComposite %composite_type %null %null ... etc
+  // Assumes type is a Composite already, otherwise returns null
+  const Constant* GetNullCompositeConstant(const Type* type);
+
   // Gets or creates a unique Constant instance of Vector type |type| with
   // numeric elements and a vector of constant defining words |literal_words|.
   // If a Constant instance existed already in the constant pool, it returns a
@@ -649,10 +657,13 @@
   const Constant* GetDoubleConst(double val);
 
   // Returns the id of a 32-bit signed integer constant with value |val|.
-  uint32_t GetSIntConst(int32_t val);
+  uint32_t GetSIntConstId(int32_t val);
 
   // Returns the id of a 32-bit unsigned integer constant with value |val|.
-  uint32_t GetUIntConst(uint32_t val);
+  uint32_t GetUIntConstId(uint32_t val);
+
+  // Returns the id of a OpConstantNull with type of |type|.
+  uint32_t GetNullConstId(const Type* type);
 
  private:
   // Creates a Constant instance with the given type and a vector of constant
diff --git a/third_party/SPIRV-Tools/source/opt/debug_info_manager.cpp b/third_party/SPIRV-Tools/source/opt/debug_info_manager.cpp
index 0ec392f..1e614c6 100644
--- a/third_party/SPIRV-Tools/source/opt/debug_info_manager.cpp
+++ b/third_party/SPIRV-Tools/source/opt/debug_info_manager.cpp
@@ -235,7 +235,8 @@
           !context()->AreAnalysesValid(IRContext::Analysis::kAnalysisConstants))
         line_number = AddNewConstInGlobals(context(), line_number);
       else
-        line_number = context()->get_constant_mgr()->GetUIntConst(line_number);
+        line_number =
+            context()->get_constant_mgr()->GetUIntConstId(line_number);
     }
   }
 
@@ -344,7 +345,7 @@
              {static_cast<uint32_t>(OpenCLDebugInfo100Deref)}},
         }));
   } else {
-    uint32_t deref_id = context()->get_constant_mgr()->GetUIntConst(
+    uint32_t deref_id = context()->get_constant_mgr()->GetUIntConstId(
         NonSemanticShaderDebugInfo100Deref);
 
     deref_operation = std::unique_ptr<Instruction>(
diff --git a/third_party/SPIRV-Tools/source/opt/eliminate_dead_input_components_pass.cpp b/third_party/SPIRV-Tools/source/opt/eliminate_dead_io_components_pass.cpp
similarity index 88%
rename from third_party/SPIRV-Tools/source/opt/eliminate_dead_input_components_pass.cpp
rename to third_party/SPIRV-Tools/source/opt/eliminate_dead_io_components_pass.cpp
index fa019ac..e430c6d 100644
--- a/third_party/SPIRV-Tools/source/opt/eliminate_dead_input_components_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/eliminate_dead_io_components_pass.cpp
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "source/opt/eliminate_dead_input_components_pass.h"
+#include "source/opt/eliminate_dead_io_components_pass.h"
 
 #include <set>
 #include <vector>
@@ -32,10 +32,22 @@
 constexpr uint32_t kConstantValueInIdx = 0;
 }  // namespace
 
-Pass::Status EliminateDeadInputComponentsPass::Process() {
-  // Process non-vertex only if explicitly allowed.
+Pass::Status EliminateDeadIOComponentsPass::Process() {
+  // Only process input and output variables
+  if (elim_sclass_ != spv::StorageClass::Input &&
+      elim_sclass_ != spv::StorageClass::Output) {
+    if (consumer()) {
+      std::string message =
+          "EliminateDeadIOComponentsPass only valid for input and output "
+          "variables.";
+      consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str());
+    }
+    return Status::Failure;
+  }
+  // If safe mode, only process Input variables in vertex shader
   const auto stage = context()->GetStage();
-  if (stage != spv::ExecutionModel::Vertex && vertex_shader_only_)
+  if (safe_mode_ && !(stage == spv::ExecutionModel::Vertex &&
+                      elim_sclass_ == spv::StorageClass::Input))
     return Status::SuccessWithoutChange;
   // Current functionality assumes shader capability.
   if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader))
@@ -62,14 +74,8 @@
       continue;
     }
     const auto sclass = ptr_type->storage_class();
-    if (output_instead_) {
-      if (sclass != spv::StorageClass::Output) {
-        continue;
-      }
-    } else {
-      if (sclass != spv::StorageClass::Input) {
-        continue;
-      }
+    if (sclass != elim_sclass_) {
+      continue;
     }
     // For tesc, or input variables in tese or geom shaders,
     // there is a outer per-vertex-array that must be ignored
@@ -137,7 +143,7 @@
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
-unsigned EliminateDeadInputComponentsPass::FindMaxIndex(
+unsigned EliminateDeadIOComponentsPass::FindMaxIndex(
     const Instruction& var, const unsigned original_max,
     const bool skip_first_index) {
   unsigned max = 0;
@@ -182,8 +188,8 @@
   return seen_non_const_ac ? original_max : max;
 }
 
-void EliminateDeadInputComponentsPass::ChangeArrayLength(Instruction& arr_var,
-                                                         unsigned length) {
+void EliminateDeadIOComponentsPass::ChangeArrayLength(Instruction& arr_var,
+                                                      unsigned length) {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
@@ -191,7 +197,7 @@
       type_mgr->GetType(arr_var.type_id())->AsPointer();
   const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray();
   assert(arr_ty && "expecting array type");
-  uint32_t length_id = const_mgr->GetUIntConst(length);
+  uint32_t length_id = const_mgr->GetUIntConstId(length);
   analysis::Array new_arr_ty(arr_ty->element_type(),
                              arr_ty->GetConstantLengthInfo(length_id, length));
   analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty);
@@ -202,8 +208,8 @@
   def_use_mgr->AnalyzeInstUse(&arr_var);
 }
 
-void EliminateDeadInputComponentsPass::ChangeIOVarStructLength(
-    Instruction& io_var, unsigned length) {
+void EliminateDeadIOComponentsPass::ChangeIOVarStructLength(Instruction& io_var,
+                                                            unsigned length) {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   analysis::Pointer* ptr_type =
       type_mgr->GetType(io_var.type_id())->AsPointer();
@@ -235,9 +241,7 @@
     analysis::Array new_arr_ty(reg_new_var_ty, arr_type->length_info());
     reg_new_var_ty = type_mgr->GetRegisteredType(&new_arr_ty);
   }
-  auto sclass =
-      output_instead_ ? spv::StorageClass::Output : spv::StorageClass::Input;
-  analysis::Pointer new_ptr_ty(reg_new_var_ty, sclass);
+  analysis::Pointer new_ptr_ty(reg_new_var_ty, elim_sclass_);
   analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty);
   uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty);
   io_var.SetResultType(new_ptr_ty_id);
diff --git a/third_party/SPIRV-Tools/source/opt/eliminate_dead_input_components_pass.h b/third_party/SPIRV-Tools/source/opt/eliminate_dead_io_components_pass.h
similarity index 81%
rename from third_party/SPIRV-Tools/source/opt/eliminate_dead_input_components_pass.h
rename to third_party/SPIRV-Tools/source/opt/eliminate_dead_io_components_pass.h
index bdfdc21..ef4dfb7 100644
--- a/third_party/SPIRV-Tools/source/opt/eliminate_dead_input_components_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/eliminate_dead_io_components_pass.h
@@ -26,12 +26,11 @@
 namespace opt {
 
 // See optimizer.hpp for documentation.
-class EliminateDeadInputComponentsPass : public Pass {
+class EliminateDeadIOComponentsPass : public Pass {
  public:
-  explicit EliminateDeadInputComponentsPass(bool output_instead = false,
-                                            bool vertex_shader_only = true)
-      : output_instead_(output_instead),
-        vertex_shader_only_(vertex_shader_only) {}
+  explicit EliminateDeadIOComponentsPass(spv::StorageClass elim_sclass,
+                                         bool safe_mode = true)
+      : elim_sclass_(elim_sclass), safe_mode_(safe_mode) {}
 
   const char* name() const override {
     return "eliminate-dead-input-components";
@@ -62,11 +61,12 @@
   // is either the struct or a per-vertex-array of the struct.
   void ChangeIOVarStructLength(Instruction& io_var, unsigned length);
 
-  // Process output variables instead
-  bool output_instead_;
+  // Storage class to be optimized. Must be Input or Output.
+  spv::StorageClass elim_sclass_;
 
-  // Only process vertex shaders
-  bool vertex_shader_only_;
+  // Only make changes that will not cause interface incompatibility if done
+  // standalone. Currently this is only Input variables in vertex shaders.
+  bool safe_mode_;
 };
 
 }  // namespace opt
diff --git a/third_party/SPIRV-Tools/source/opt/interface_var_sroa.cpp b/third_party/SPIRV-Tools/source/opt/interface_var_sroa.cpp
index 8205c75..08477cb 100644
--- a/third_party/SPIRV-Tools/source/opt/interface_var_sroa.cpp
+++ b/third_party/SPIRV-Tools/source/opt/interface_var_sroa.cpp
@@ -489,7 +489,7 @@
     Instruction* insert_before) {
   uint32_t ptr_type_id =
       GetPointerType(component_type_id, GetStorageClass(var));
-  uint32_t index_id = context()->get_constant_mgr()->GetUIntConst(index);
+  uint32_t index_id = context()->get_constant_mgr()->GetUIntConstId(index);
   std::unique_ptr<Instruction> new_access_chain(new Instruction(
       context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(),
       std::initializer_list<Operand>{
@@ -781,7 +781,7 @@
     uint32_t elem_type_id, uint32_t array_length) {
   analysis::Type* elem_type = context()->get_type_mgr()->GetType(elem_type_id);
   uint32_t array_length_id =
-      context()->get_constant_mgr()->GetUIntConst(array_length);
+      context()->get_constant_mgr()->GetUIntConstId(array_length);
   analysis::Array array_type(
       elem_type,
       analysis::Array::LengthInfo{array_length_id, {0, array_length}});
diff --git a/third_party/SPIRV-Tools/source/opt/ir_context.cpp b/third_party/SPIRV-Tools/source/opt/ir_context.cpp
index 0a047e9..889a671 100644
--- a/third_party/SPIRV-Tools/source/opt/ir_context.cpp
+++ b/third_party/SPIRV-Tools/source/opt/ir_context.cpp
@@ -482,6 +482,7 @@
          (uint32_t)spv::Op::OpTypeAccelerationStructureNV,
          (uint32_t)spv::Op::OpTypeAccelerationStructureKHR,
          (uint32_t)spv::Op::OpTypeRayQueryKHR,
+         (uint32_t)spv::Op::OpTypeHitObjectNV,
          (uint32_t)spv::Op::OpTypeArray,
          (uint32_t)spv::Op::OpTypeRuntimeArray,
          (uint32_t)spv::Op::OpTypeStruct,
diff --git a/third_party/SPIRV-Tools/source/opt/optimizer.cpp b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
index 8828c70..be0daeb 100644
--- a/third_party/SPIRV-Tools/source/opt/optimizer.cpp
+++ b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
@@ -1013,19 +1013,20 @@
 
 Optimizer::PassToken CreateEliminateDeadInputComponentsPass() {
   return MakeUnique<Optimizer::PassToken::Impl>(
-      MakeUnique<opt::EliminateDeadInputComponentsPass>(
-          /* output_instead */ false, /* vertex_shader_only */ false));
+      MakeUnique<opt::EliminateDeadIOComponentsPass>(spv::StorageClass::Input,
+                                                     /* safe_mode */ false));
 }
 
 Optimizer::PassToken CreateEliminateDeadOutputComponentsPass() {
   return MakeUnique<Optimizer::PassToken::Impl>(
-      MakeUnique<opt::EliminateDeadInputComponentsPass>(
-          /* output_instead */ true, /* vertex_shader_only */ false));
+      MakeUnique<opt::EliminateDeadIOComponentsPass>(spv::StorageClass::Output,
+                                                     /* safe_mode */ false));
 }
 
 Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass() {
   return MakeUnique<Optimizer::PassToken::Impl>(
-      MakeUnique<opt::EliminateDeadInputComponentsPass>());
+      MakeUnique<opt::EliminateDeadIOComponentsPass>(spv::StorageClass::Input,
+                                                     /* safe_mode */ true));
 }
 
 Optimizer::PassToken CreateAnalyzeLiveInputPass(
diff --git a/third_party/SPIRV-Tools/source/opt/passes.h b/third_party/SPIRV-Tools/source/opt/passes.h
index 5344dcf..eb3b1e5 100644
--- a/third_party/SPIRV-Tools/source/opt/passes.h
+++ b/third_party/SPIRV-Tools/source/opt/passes.h
@@ -35,7 +35,7 @@
 #include "source/opt/desc_sroa.h"
 #include "source/opt/eliminate_dead_constant_pass.h"
 #include "source/opt/eliminate_dead_functions_pass.h"
-#include "source/opt/eliminate_dead_input_components_pass.h"
+#include "source/opt/eliminate_dead_io_components_pass.h"
 #include "source/opt/eliminate_dead_members_pass.h"
 #include "source/opt/eliminate_dead_output_stores_pass.h"
 #include "source/opt/empty_pass.h"
diff --git a/third_party/SPIRV-Tools/source/opt/reflect.h b/third_party/SPIRV-Tools/source/opt/reflect.h
index 1c34600..45bb5c5 100644
--- a/third_party/SPIRV-Tools/source/opt/reflect.h
+++ b/third_party/SPIRV-Tools/source/opt/reflect.h
@@ -53,7 +53,8 @@
          opcode == spv::Op::OpTypeAccelerationStructureNV ||
          opcode == spv::Op::OpTypeAccelerationStructureKHR ||
          opcode == spv::Op::OpTypeRayQueryKHR ||
-         opcode == spv::Op::OpTypeCooperativeMatrixNV;
+         opcode == spv::Op::OpTypeCooperativeMatrixNV ||
+         opcode == spv::Op::OpTypeHitObjectNV;
 }
 inline bool IsConstantInst(spv::Op opcode) {
   return (opcode >= spv::Op::OpConstantTrue &&
diff --git a/third_party/SPIRV-Tools/source/opt/replace_desc_array_access_using_var_index.cpp b/third_party/SPIRV-Tools/source/opt/replace_desc_array_access_using_var_index.cpp
index 93c77d3..59745e1 100644
--- a/third_party/SPIRV-Tools/source/opt/replace_desc_array_access_using_var_index.cpp
+++ b/third_party/SPIRV-Tools/source/opt/replace_desc_array_access_using_var_index.cpp
@@ -331,7 +331,7 @@
 void ReplaceDescArrayAccessUsingVarIndex::UseConstIndexForAccessChain(
     Instruction* access_chain, uint32_t const_element_idx) const {
   uint32_t const_element_idx_id =
-      context()->get_constant_mgr()->GetUIntConst(const_element_idx);
+      context()->get_constant_mgr()->GetUIntConstId(const_element_idx);
   access_chain->SetInOperand(kOpAccessChainInOperandIndexes,
                              {const_element_idx_id});
 }
diff --git a/third_party/SPIRV-Tools/source/opt/scalar_replacement_pass.cpp b/third_party/SPIRV-Tools/source/opt/scalar_replacement_pass.cpp
index 6045158..bfebb01 100644
--- a/third_party/SPIRV-Tools/source/opt/scalar_replacement_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/scalar_replacement_pass.cpp
@@ -191,7 +191,7 @@
     if (added_dbg_value == nullptr) return false;
     added_dbg_value->AddOperand(
         {SPV_OPERAND_TYPE_ID,
-         {context()->get_constant_mgr()->GetSIntConst(idx)}});
+         {context()->get_constant_mgr()->GetSIntConstId(idx)}});
     added_dbg_value->SetOperand(kDebugValueOperandExpressionIndex,
                                 {deref_expr->result_id()});
     if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) {
@@ -217,7 +217,7 @@
     // Append 'Indexes' operand.
     new_dbg_value->AddOperand(
         {SPV_OPERAND_TYPE_ID,
-         {context()->get_constant_mgr()->GetSIntConst(idx)}});
+         {context()->get_constant_mgr()->GetSIntConstId(idx)}});
     // Insert the new DebugValue to the basic block.
     auto* added_instr = dbg_value->InsertBefore(std::move(new_dbg_value));
     get_def_use_mgr()->AnalyzeInstDefUse(added_instr);
diff --git a/third_party/SPIRV-Tools/source/opt/type_manager.cpp b/third_party/SPIRV-Tools/source/opt/type_manager.cpp
index 7dc9c8f..6e4c054 100644
--- a/third_party/SPIRV-Tools/source/opt/type_manager.cpp
+++ b/third_party/SPIRV-Tools/source/opt/type_manager.cpp
@@ -234,6 +234,7 @@
     DefineParameterlessCase(NamedBarrier);
     DefineParameterlessCase(AccelerationStructureNV);
     DefineParameterlessCase(RayQueryKHR);
+    DefineParameterlessCase(HitObjectNV);
 #undef DefineParameterlessCase
     case Type::kInteger:
       typeInst = MakeUnique<Instruction>(
@@ -527,6 +528,7 @@
     DefineNoSubtypeCase(NamedBarrier);
     DefineNoSubtypeCase(AccelerationStructureNV);
     DefineNoSubtypeCase(RayQueryKHR);
+    DefineNoSubtypeCase(HitObjectNV);
 #undef DefineNoSubtypeCase
     case Type::kVector: {
       const Vector* vec_ty = type.AsVector();
@@ -864,6 +866,9 @@
     case spv::Op::OpTypeRayQueryKHR:
       type = new RayQueryKHR();
       break;
+    case spv::Op::OpTypeHitObjectNV:
+      type = new HitObjectNV();
+      break;
     default:
       SPIRV_UNIMPLEMENTED(consumer_, "unhandled type");
       break;
diff --git a/third_party/SPIRV-Tools/source/opt/types.cpp b/third_party/SPIRV-Tools/source/opt/types.cpp
index 12ff139..ab95906 100644
--- a/third_party/SPIRV-Tools/source/opt/types.cpp
+++ b/third_party/SPIRV-Tools/source/opt/types.cpp
@@ -131,6 +131,7 @@
     DeclareKindCase(AccelerationStructureNV);
     DeclareKindCase(CooperativeMatrixNV);
     DeclareKindCase(RayQueryKHR);
+    DeclareKindCase(HitObjectNV);
 #undef DeclareKindCase
     default:
       assert(false && "Unhandled type");
@@ -177,6 +178,7 @@
     DeclareKindCase(AccelerationStructureNV);
     DeclareKindCase(CooperativeMatrixNV);
     DeclareKindCase(RayQueryKHR);
+    DeclareKindCase(HitObjectNV);
 #undef DeclareKindCase
     default:
       assert(false && "Unhandled type");
@@ -231,6 +233,7 @@
     DeclareKindCase(AccelerationStructureNV);
     DeclareKindCase(CooperativeMatrixNV);
     DeclareKindCase(RayQueryKHR);
+    DeclareKindCase(HitObjectNV);
 #undef DeclareKindCase
     default:
       assert(false && "Unhandled type");
diff --git a/third_party/SPIRV-Tools/source/opt/types.h b/third_party/SPIRV-Tools/source/opt/types.h
index 645dbd4..1f32937 100644
--- a/third_party/SPIRV-Tools/source/opt/types.h
+++ b/third_party/SPIRV-Tools/source/opt/types.h
@@ -61,6 +61,7 @@
 class AccelerationStructureNV;
 class CooperativeMatrixNV;
 class RayQueryKHR;
+class HitObjectNV;
 
 // Abstract class for a SPIR-V type. It has a bunch of As<sublcass>() methods,
 // which is used as a way to probe the actual <subclass>.
@@ -100,6 +101,7 @@
     kAccelerationStructureNV,
     kCooperativeMatrixNV,
     kRayQueryKHR,
+    kHitObjectNV,
     kLast
   };
 
@@ -196,6 +198,7 @@
   DeclareCastMethod(AccelerationStructureNV)
   DeclareCastMethod(CooperativeMatrixNV)
   DeclareCastMethod(RayQueryKHR)
+  DeclareCastMethod(HitObjectNV)
 #undef DeclareCastMethod
 
 protected:
@@ -648,6 +651,7 @@
 DefineParameterlessType(NamedBarrier, named_barrier);
 DefineParameterlessType(AccelerationStructureNV, accelerationStructureNV);
 DefineParameterlessType(RayQueryKHR, rayQueryKHR);
+DefineParameterlessType(HitObjectNV, hitObjectNV);
 #undef DefineParameterlessType
 
 }  // namespace analysis
diff --git a/third_party/SPIRV-Tools/source/val/validate.cpp b/third_party/SPIRV-Tools/source/val/validate.cpp
index 10f3d43..52cb0d8 100644
--- a/third_party/SPIRV-Tools/source/val/validate.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate.cpp
@@ -365,6 +365,7 @@
     if (auto error = LiteralsPass(*vstate, &instruction)) return error;
     if (auto error = RayQueryPass(*vstate, &instruction)) return error;
     if (auto error = RayTracingPass(*vstate, &instruction)) return error;
+    if (auto error = RayReorderNVPass(*vstate, &instruction)) return error;
     if (auto error = MeshShadingPass(*vstate, &instruction)) return error;
   }
 
diff --git a/third_party/SPIRV-Tools/source/val/validate.h b/third_party/SPIRV-Tools/source/val/validate.h
index fd84b06..8987438 100644
--- a/third_party/SPIRV-Tools/source/val/validate.h
+++ b/third_party/SPIRV-Tools/source/val/validate.h
@@ -203,6 +203,9 @@
 /// Validates correctness of ray tracing instructions.
 spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst);
 
+/// Validates correctness of shader execution reorder instructions.
+spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst);
+
 /// Validates correctness of mesh shading instructions.
 spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst);
 
diff --git a/third_party/SPIRV-Tools/source/val/validate_annotation.cpp b/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
index 2d13456..bef753d 100644
--- a/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
@@ -200,7 +200,8 @@
             sc != spv::StorageClass::HitAttributeKHR &&
             sc != spv::StorageClass::CallableDataKHR &&
             sc != spv::StorageClass::IncomingCallableDataKHR &&
-            sc != spv::StorageClass::ShaderRecordBufferKHR) {
+            sc != spv::StorageClass::ShaderRecordBufferKHR &&
+            sc != spv::StorageClass::HitObjectAttributeNV) {
           return _.diag(SPV_ERROR_INVALID_ID, target)
                  << _.VkErrorID(6672) << _.SpvDecorationString(dec)
                  << " decoration must not be applied to this storage class";
diff --git a/third_party/SPIRV-Tools/source/val/validate_extensions.cpp b/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
index 98c691b..ebb13cf 100644
--- a/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
@@ -757,7 +757,8 @@
     std::string extension = GetExtensionString(&(inst->c_inst()));
     if (extension ==
             ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) ||
-        extension == ExtensionToString(kSPV_EXT_mesh_shader)) {
+        extension == ExtensionToString(kSPV_EXT_mesh_shader) ||
+        extension == ExtensionToString(kSPV_NV_shader_invocation_reorder)) {
       return _.diag(SPV_ERROR_WRONG_VERSION, inst)
              << extension << " extension requires SPIR-V version 1.4 or later.";
     }
diff --git a/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp b/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp
index 54152da..00a5999 100644
--- a/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp
@@ -537,64 +537,6 @@
   return SPV_SUCCESS;
 }
 
-spv_result_t ValidateStorageClass(ValidationState_t& _,
-                                  const Instruction* entry_point) {
-  bool has_push_constant = false;
-  bool has_ray_payload = false;
-  bool has_hit_attribute = false;
-  bool has_callable_data = false;
-  for (uint32_t i = 3; i < entry_point->operands().size(); ++i) {
-    auto interface_id = entry_point->GetOperandAs<uint32_t>(i);
-    auto interface_var = _.FindDef(interface_id);
-    auto storage_class = interface_var->GetOperandAs<spv::StorageClass>(2);
-    switch (storage_class) {
-      case spv::StorageClass::PushConstant: {
-        if (has_push_constant) {
-          return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
-                 << _.VkErrorID(6673)
-                 << "Entry-point has more than one variable with the "
-                    "PushConstant storage class in the interface";
-        }
-        has_push_constant = true;
-        break;
-      }
-      case spv::StorageClass::IncomingRayPayloadKHR: {
-        if (has_ray_payload) {
-          return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
-                 << _.VkErrorID(4700)
-                 << "Entry-point has more than one variable with the "
-                    "IncomingRayPayloadKHR storage class in the interface";
-        }
-        has_ray_payload = true;
-        break;
-      }
-      case spv::StorageClass::HitAttributeKHR: {
-        if (has_hit_attribute) {
-          return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
-                 << _.VkErrorID(4702)
-                 << "Entry-point has more than one variable with the "
-                    "HitAttributeKHR storage class in the interface";
-        }
-        has_hit_attribute = true;
-        break;
-      }
-      case spv::StorageClass::IncomingCallableDataKHR: {
-        if (has_callable_data) {
-          return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
-                 << _.VkErrorID(4706)
-                 << "Entry-point has more than one variable with the "
-                    "IncomingCallableDataKHR storage class in the interface";
-        }
-        has_callable_data = true;
-        break;
-      }
-      default:
-        break;
-    }
-  }
-  return SPV_SUCCESS;
-}
-
 }  // namespace
 
 spv_result_t ValidateInterfaces(ValidationState_t& _) {
@@ -613,9 +555,6 @@
         if (auto error = ValidateLocations(_, &inst)) {
           return error;
         }
-        if (auto error = ValidateStorageClass(_, &inst)) {
-          return error;
-        }
       }
       if (inst.opcode() == spv::Op::OpTypeVoid) break;
     }
diff --git a/third_party/SPIRV-Tools/source/val/validate_memory.cpp b/third_party/SPIRV-Tools/source/val/validate_memory.cpp
index 80c9e87..57fd23d 100644
--- a/third_party/SPIRV-Tools/source/val/validate_memory.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_memory.cpp
@@ -447,7 +447,8 @@
       storage_class != spv::StorageClass::HitAttributeKHR &&
       storage_class != spv::StorageClass::CallableDataKHR &&
       storage_class != spv::StorageClass::IncomingCallableDataKHR &&
-      storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT) {
+      storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT &&
+      storage_class != spv::StorageClass::HitObjectAttributeNV) {
     bool storage_input_or_output = storage_class == spv::StorageClass::Input ||
                                    storage_class == spv::StorageClass::Output;
     bool builtin = false;
@@ -656,6 +657,11 @@
              << "OpVariable, <id> " << _.getIdName(inst->id())
              << ", initializer are not allowed for Input";
     }
+    if (storage_class == spv::StorageClass::HitObjectAttributeNV) {
+      return _.diag(SPV_ERROR_INVALID_ID, inst)
+             << "OpVariable, <id> " << _.getIdName(inst->id())
+             << ", initializer are not allowed for HitObjectAttributeNV";
+    }
   }
 
   if (storage_class == spv::StorageClass::PhysicalStorageBuffer) {
diff --git a/third_party/SPIRV-Tools/source/val/validate_ray_tracing_reorder.cpp b/third_party/SPIRV-Tools/source/val/validate_ray_tracing_reorder.cpp
new file mode 100644
index 0000000..cb190f9
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/val/validate_ray_tracing_reorder.cpp
@@ -0,0 +1,625 @@
+// Copyright (c) 2022 The Khronos Group Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Validates ray tracing instructions from SPV_NV_shader_execution_reorder
+
+#include "source/opcode.h"
+#include "source/val/instruction.h"
+#include "source/val/validate.h"
+#include "source/val/validation_state.h"
+
+#include <limits>
+
+namespace spvtools {
+namespace val {
+
+static const uint32_t KRayParamInvalidId = std::numeric_limits<uint32_t>::max();
+
+spv_result_t ValidateHitObjectPointer(ValidationState_t& _,
+                                      const Instruction* inst,
+                                      uint32_t hit_object_index) {
+  const uint32_t hit_object_id = inst->GetOperandAs<uint32_t>(hit_object_index);
+  auto variable = _.FindDef(hit_object_id);
+  const auto var_opcode = variable->opcode();
+  if (!variable || (var_opcode != spv::Op::OpVariable &&
+                    var_opcode != spv::Op::OpFunctionParameter &&
+                    var_opcode != spv::Op::OpAccessChain)) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << "Hit Object must be a memory object declaration";
+  }
+  auto pointer = _.FindDef(variable->GetOperandAs<uint32_t>(0));
+  if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << "Hit Object must be a pointer";
+  }
+  auto type = _.FindDef(pointer->GetOperandAs<uint32_t>(2));
+  if (!type || type->opcode() != spv::Op::OpTypeHitObjectNV) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << "Type must be OpTypeHitObjectNV";
+  }
+  return SPV_SUCCESS;
+}
+
+spv_result_t ValidateHitObjectInstructionCommonParameters(
+    ValidationState_t& _, const Instruction* inst,
+    uint32_t acceleration_struct_index, uint32_t instance_id_index,
+    uint32_t primtive_id_index, uint32_t geometry_index,
+    uint32_t ray_flags_index, uint32_t cull_mask_index, uint32_t hit_kind_index,
+    uint32_t sbt_index, uint32_t sbt_offset_index, uint32_t sbt_stride_index,
+    uint32_t sbt_record_offset_index, uint32_t sbt_record_stride_index,
+    uint32_t miss_index, uint32_t ray_origin_index, uint32_t ray_tmin_index,
+    uint32_t ray_direction_index, uint32_t ray_tmax_index,
+    uint32_t payload_index, uint32_t hit_object_attr_index) {
+  auto isValidId = [](uint32_t spvid) { return spvid < KRayParamInvalidId; };
+  if (isValidId(acceleration_struct_index) &&
+      _.GetIdOpcode(_.GetOperandTypeId(inst, acceleration_struct_index)) !=
+          spv::Op::OpTypeAccelerationStructureKHR) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << "Expected Acceleration Structure to be of type "
+              "OpTypeAccelerationStructureKHR";
+  }
+
+  if (isValidId(instance_id_index)) {
+    const uint32_t instance_id = _.GetOperandTypeId(inst, instance_id_index);
+    if (!_.IsIntScalarType(instance_id) || _.GetBitWidth(instance_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Instance Id must be a 32-bit int scalar";
+    }
+  }
+
+  if (isValidId(primtive_id_index)) {
+    const uint32_t primitive_id = _.GetOperandTypeId(inst, primtive_id_index);
+    if (!_.IsIntScalarType(primitive_id) || _.GetBitWidth(primitive_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Primitive Id must be a 32-bit int scalar";
+    }
+  }
+
+  if (isValidId(geometry_index)) {
+    const uint32_t geometry_index_id = _.GetOperandTypeId(inst, geometry_index);
+    if (!_.IsIntScalarType(geometry_index_id) ||
+        _.GetBitWidth(geometry_index_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Geometry Index must be a 32-bit int scalar";
+    }
+  }
+
+  if (isValidId(miss_index)) {
+    const uint32_t miss_index_id = _.GetOperandTypeId(inst, miss_index);
+    if (!_.IsUnsignedIntScalarType(miss_index_id) ||
+        _.GetBitWidth(miss_index_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Miss Index must be a 32-bit int scalar";
+    }
+  }
+
+  if (isValidId(cull_mask_index)) {
+    const uint32_t cull_mask_id = _.GetOperandTypeId(inst, cull_mask_index);
+    if (!_.IsUnsignedIntScalarType(cull_mask_id) ||
+        _.GetBitWidth(cull_mask_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Cull mask must be a 32-bit int scalar";
+    }
+  }
+
+  if (isValidId(sbt_index)) {
+    const uint32_t sbt_index_id = _.GetOperandTypeId(inst, sbt_index);
+    if (!_.IsUnsignedIntScalarType(sbt_index_id) ||
+        _.GetBitWidth(sbt_index_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "SBT Index must be a 32-bit unsigned int scalar";
+    }
+  }
+
+  if (isValidId(sbt_offset_index)) {
+    const uint32_t sbt_offset_id = _.GetOperandTypeId(inst, sbt_offset_index);
+    if (!_.IsUnsignedIntScalarType(sbt_offset_id) ||
+        _.GetBitWidth(sbt_offset_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "SBT Offset must be a 32-bit unsigned int scalar";
+    }
+  }
+
+  if (isValidId(sbt_stride_index)) {
+    const uint32_t sbt_stride_index_id =
+        _.GetOperandTypeId(inst, sbt_stride_index);
+    if (!_.IsUnsignedIntScalarType(sbt_stride_index_id) ||
+        _.GetBitWidth(sbt_stride_index_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "SBT Stride must be a 32-bit unsigned int scalar";
+    }
+  }
+
+  if (isValidId(sbt_record_offset_index)) {
+    const uint32_t sbt_record_offset_index_id =
+        _.GetOperandTypeId(inst, sbt_record_offset_index);
+    if (!_.IsUnsignedIntScalarType(sbt_record_offset_index_id) ||
+        _.GetBitWidth(sbt_record_offset_index_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "SBT record offset must be a 32-bit unsigned int scalar";
+    }
+  }
+
+  if (isValidId(sbt_record_stride_index)) {
+    const uint32_t sbt_record_stride_index_id =
+        _.GetOperandTypeId(inst, sbt_record_stride_index);
+    if (!_.IsUnsignedIntScalarType(sbt_record_stride_index_id) ||
+        _.GetBitWidth(sbt_record_stride_index_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "SBT record stride must be a 32-bit unsigned int scalar";
+    }
+  }
+
+  if (isValidId(ray_origin_index)) {
+    const uint32_t ray_origin_id = _.GetOperandTypeId(inst, ray_origin_index);
+    if (!_.IsFloatVectorType(ray_origin_id) ||
+        _.GetDimension(ray_origin_id) != 3 ||
+        _.GetBitWidth(ray_origin_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Ray Origin must be a 32-bit float 3-component vector";
+    }
+  }
+
+  if (isValidId(ray_tmin_index)) {
+    const uint32_t ray_tmin_id = _.GetOperandTypeId(inst, ray_tmin_index);
+    if (!_.IsFloatScalarType(ray_tmin_id) || _.GetBitWidth(ray_tmin_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Ray TMin must be a 32-bit float scalar";
+    }
+  }
+
+  if (isValidId(ray_direction_index)) {
+    const uint32_t ray_direction_id =
+        _.GetOperandTypeId(inst, ray_direction_index);
+    if (!_.IsFloatVectorType(ray_direction_id) ||
+        _.GetDimension(ray_direction_id) != 3 ||
+        _.GetBitWidth(ray_direction_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Ray Direction must be a 32-bit float 3-component vector";
+    }
+  }
+
+  if (isValidId(ray_tmax_index)) {
+    const uint32_t ray_tmax_id = _.GetOperandTypeId(inst, ray_tmax_index);
+    if (!_.IsFloatScalarType(ray_tmax_id) || _.GetBitWidth(ray_tmax_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Ray TMax must be a 32-bit float scalar";
+    }
+  }
+
+  if (isValidId(ray_flags_index)) {
+    const uint32_t ray_flags_id = _.GetOperandTypeId(inst, ray_flags_index);
+    if (!_.IsIntScalarType(ray_flags_id) || _.GetBitWidth(ray_flags_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Ray Flags must be a 32-bit int scalar";
+    }
+  }
+
+  if (isValidId(payload_index)) {
+    const uint32_t payload_id = inst->GetOperandAs<uint32_t>(payload_index);
+    auto variable = _.FindDef(payload_id);
+    const auto var_opcode = variable->opcode();
+    if (!variable || var_opcode != spv::Op::OpVariable ||
+        (variable->GetOperandAs<spv::StorageClass>(2) !=
+             spv::StorageClass::RayPayloadKHR &&
+         variable->GetOperandAs<spv::StorageClass>(2) !=
+             spv::StorageClass::IncomingRayPayloadKHR)) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "payload must be a OpVariable of storage "
+                "class RayPayloadKHR or IncomingRayPayloadKHR";
+    }
+  }
+
+  if (isValidId(hit_kind_index)) {
+    const uint32_t hit_kind_id = _.GetOperandTypeId(inst, hit_kind_index);
+    if (!_.IsUnsignedIntScalarType(hit_kind_id) ||
+        _.GetBitWidth(hit_kind_id) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Hit Kind must be a 32-bit unsigned int scalar";
+    }
+  }
+
+  if (isValidId(hit_object_attr_index)) {
+    const uint32_t hit_object_attr_id =
+        inst->GetOperandAs<uint32_t>(hit_object_attr_index);
+    auto variable = _.FindDef(hit_object_attr_id);
+    const auto var_opcode = variable->opcode();
+    if (!variable || var_opcode != spv::Op::OpVariable ||
+        (variable->GetOperandAs<spv::StorageClass>(2)) !=
+            spv::StorageClass::HitObjectAttributeNV) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Hit Object Attributes id must be a OpVariable of storage "
+                "class HitObjectAttributeNV";
+    }
+  }
+
+  return SPV_SUCCESS;
+}
+
+spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst) {
+  const spv::Op opcode = inst->opcode();
+  const uint32_t result_type = inst->type_id();
+
+  auto RegisterOpcodeForValidModel = [](ValidationState_t& vs,
+                                        const Instruction* rtinst) {
+    std::string opcode_name = spvOpcodeString(rtinst->opcode());
+    vs.function(rtinst->function()->id())
+        ->RegisterExecutionModelLimitation(
+            [opcode_name](spv::ExecutionModel model, std::string* message) {
+              if (model != spv::ExecutionModel::RayGenerationKHR &&
+                  model != spv::ExecutionModel::ClosestHitKHR &&
+                  model != spv::ExecutionModel::MissKHR) {
+                if (message) {
+                  *message = opcode_name +
+                             " requires RayGenerationKHR, ClosestHitKHR and "
+                             "MissKHR execution models";
+                }
+                return false;
+              }
+              return true;
+            });
+    return;
+  };
+
+  switch (opcode) {
+    case spv::Op::OpHitObjectIsMissNV:
+    case spv::Op::OpHitObjectIsHitNV:
+    case spv::Op::OpHitObjectIsEmptyNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (!_.IsBoolScalarType(result_type)) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "expected Result Type to be bool scalar type";
+      }
+
+      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
+      break;
+    }
+
+    case spv::Op::OpHitObjectGetShaderRecordBufferHandleNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
+
+      if (!_.IsIntVectorType(result_type) ||
+          (_.GetDimension(result_type) != 2) ||
+          (_.GetBitWidth(result_type) != 32))
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Expected 32-bit integer type 2-component vector as Result "
+                  "Type: "
+               << spvOpcodeString(opcode);
+      break;
+    }
+
+    case spv::Op::OpHitObjectGetHitKindNV:
+    case spv::Op::OpHitObjectGetPrimitiveIndexNV:
+    case spv::Op::OpHitObjectGetGeometryIndexNV:
+    case spv::Op::OpHitObjectGetInstanceIdNV:
+    case spv::Op::OpHitObjectGetInstanceCustomIndexNV:
+    case spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
+
+      if (!_.IsIntScalarType(result_type) || !_.GetBitWidth(result_type))
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Expected 32-bit integer type scalar as Result Type: "
+               << spvOpcodeString(opcode);
+      break;
+    }
+
+    case spv::Op::OpHitObjectGetCurrentTimeNV:
+    case spv::Op::OpHitObjectGetRayTMaxNV:
+    case spv::Op::OpHitObjectGetRayTMinNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
+
+      if (!_.IsFloatScalarType(result_type) || _.GetBitWidth(result_type) != 32)
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Expected 32-bit floating-point type scalar as Result Type: "
+               << spvOpcodeString(opcode);
+      break;
+    }
+
+    case spv::Op::OpHitObjectGetObjectToWorldNV:
+    case spv::Op::OpHitObjectGetWorldToObjectNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
+
+      uint32_t num_rows = 0;
+      uint32_t num_cols = 0;
+      uint32_t col_type = 0;
+      uint32_t component_type = 0;
+
+      if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type,
+                               &component_type)) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "expected matrix type as Result Type: "
+               << spvOpcodeString(opcode);
+      }
+
+      if (num_cols != 4) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "expected Result Type matrix to have a Column Count of 4"
+               << spvOpcodeString(opcode);
+      }
+
+      if (!_.IsFloatScalarType(component_type) ||
+          _.GetBitWidth(result_type) != 32 || num_rows != 3) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "expected Result Type matrix to have a Column Type of "
+                  "3-component 32-bit float vectors: "
+               << spvOpcodeString(opcode);
+      }
+      break;
+    }
+
+    case spv::Op::OpHitObjectGetObjectRayOriginNV:
+    case spv::Op::OpHitObjectGetObjectRayDirectionNV:
+    case spv::Op::OpHitObjectGetWorldRayDirectionNV:
+    case spv::Op::OpHitObjectGetWorldRayOriginNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
+
+      if (!_.IsFloatVectorType(result_type) ||
+          (_.GetDimension(result_type) != 3) ||
+          (_.GetBitWidth(result_type) != 32))
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Expected 32-bit floating-point type 3-component vector as "
+                  "Result Type: "
+               << spvOpcodeString(opcode);
+      break;
+    }
+
+    case spv::Op::OpHitObjectGetAttributesNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      const uint32_t hit_object_attr_id = inst->GetOperandAs<uint32_t>(1);
+      auto variable = _.FindDef(hit_object_attr_id);
+      const auto var_opcode = variable->opcode();
+      if (!variable || var_opcode != spv::Op::OpVariable ||
+          variable->GetOperandAs<spv::StorageClass>(2) !=
+              spv::StorageClass::HitObjectAttributeNV) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Hit Object Attributes id must be a OpVariable of storage "
+                  "class HitObjectAttributeNV";
+      }
+      break;
+    }
+
+    case spv::Op::OpHitObjectExecuteShaderNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      const uint32_t hit_object_attr_id = inst->GetOperandAs<uint32_t>(1);
+      auto variable = _.FindDef(hit_object_attr_id);
+      const auto var_opcode = variable->opcode();
+      if (!variable || var_opcode != spv::Op::OpVariable ||
+          (variable->GetOperandAs<spv::StorageClass>(2)) !=
+              spv::StorageClass::RayPayloadKHR) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Hit Object Attributes id must be a OpVariable of storage "
+                  "class RayPayloadKHR";
+      }
+      break;
+    }
+
+    case spv::Op::OpHitObjectRecordEmptyNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+      break;
+    }
+
+    case spv::Op::OpHitObjectRecordMissNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      const uint32_t miss_index = _.GetOperandTypeId(inst, 1);
+      if (!_.IsUnsignedIntScalarType(miss_index) ||
+          _.GetBitWidth(miss_index) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Miss Index must be a 32-bit int scalar";
+      }
+
+      const uint32_t ray_origin = _.GetOperandTypeId(inst, 2);
+      if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 ||
+          _.GetBitWidth(ray_origin) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Ray Origin must be a 32-bit float 3-component vector";
+      }
+
+      const uint32_t ray_tmin = _.GetOperandTypeId(inst, 3);
+      if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Ray TMin must be a 32-bit float scalar";
+      }
+
+      const uint32_t ray_direction = _.GetOperandTypeId(inst, 4);
+      if (!_.IsFloatVectorType(ray_direction) ||
+          _.GetDimension(ray_direction) != 3 ||
+          _.GetBitWidth(ray_direction) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Ray Direction must be a 32-bit float 3-component vector";
+      }
+
+      const uint32_t ray_tmax = _.GetOperandTypeId(inst, 5);
+      if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Ray TMax must be a 32-bit float scalar";
+      }
+      break;
+    }
+
+    case spv::Op::OpHitObjectRecordHitWithIndexNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      if (auto error = ValidateHitObjectInstructionCommonParameters(
+              _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */,
+              3 /* Primtive Id */, 4 /* Geometry Index */,
+              KRayParamInvalidId /* Ray Flags */,
+              KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/,
+              6 /* SBT index */, KRayParamInvalidId /* SBT Offset */,
+              KRayParamInvalidId /* SBT Stride */,
+              KRayParamInvalidId /* SBT Record Offset */,
+              KRayParamInvalidId /* SBT Record Stride */,
+              KRayParamInvalidId /* Miss Index */, 7 /* Ray Origin */,
+              8 /* Ray TMin */, 9 /* Ray Direction */, 10 /* Ray TMax */,
+              KRayParamInvalidId /* Payload */, 11 /* Hit Object Attribute */))
+        return error;
+
+      break;
+    }
+
+    case spv::Op::OpHitObjectRecordHitNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      if (auto error = ValidateHitObjectInstructionCommonParameters(
+              _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */,
+              3 /* Primtive Id */, 4 /* Geometry Index */,
+              KRayParamInvalidId /* Ray Flags */,
+              KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/,
+              KRayParamInvalidId /* SBT index */,
+              KRayParamInvalidId /* SBT Offset */,
+              KRayParamInvalidId /* SBT Stride */, 6 /* SBT Record Offset */,
+              7 /* SBT Record Stride */, KRayParamInvalidId /* Miss Index */,
+              8 /* Ray Origin */, 9 /* Ray TMin */, 10 /* Ray Direction */,
+              11 /* Ray TMax */, KRayParamInvalidId /* Payload */,
+              12 /* Hit Object Attribute */))
+        return error;
+
+      break;
+    }
+
+    case spv::Op::OpHitObjectTraceRayMotionNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      if (auto error = ValidateHitObjectInstructionCommonParameters(
+              _, inst, 1 /* Acceleration Struct */,
+              KRayParamInvalidId /* Instance Id */,
+              KRayParamInvalidId /* Primtive Id */,
+              KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */,
+              3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/,
+              KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */,
+              5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */,
+              KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */,
+              7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */,
+              10 /* Ray TMax */, 12 /* Payload */,
+              KRayParamInvalidId /* Hit Object Attribute */))
+        return error;
+      // Current Time
+      const uint32_t current_time_id = _.GetOperandTypeId(inst, 11);
+      if (!_.IsFloatScalarType(current_time_id) ||
+          _.GetBitWidth(current_time_id) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Current Times must be a 32-bit float scalar type";
+      }
+
+      break;
+    }
+
+    case spv::Op::OpHitObjectTraceRayNV: {
+      RegisterOpcodeForValidModel(_, inst);
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      if (auto error = ValidateHitObjectInstructionCommonParameters(
+              _, inst, 1 /* Acceleration Struct */,
+              KRayParamInvalidId /* Instance Id */,
+              KRayParamInvalidId /* Primtive Id */,
+              KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */,
+              3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/,
+              KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */,
+              5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */,
+              KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */,
+              7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */,
+              10 /* Ray TMax */, 11 /* Payload */,
+              KRayParamInvalidId /* Hit Object Attribute */))
+        return error;
+      break;
+    }
+
+    case spv::Op::OpReorderThreadWithHitObjectNV: {
+      std::string opcode_name = spvOpcodeString(inst->opcode());
+      _.function(inst->function()->id())
+          ->RegisterExecutionModelLimitation(
+              [opcode_name](spv::ExecutionModel model, std::string* message) {
+                if (model != spv::ExecutionModel::RayGenerationKHR) {
+                  if (message) {
+                    *message = opcode_name +
+                               " requires RayGenerationKHR execution model";
+                  }
+                  return false;
+                }
+                return true;
+              });
+
+      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
+
+      if (inst->operands().size() > 1) {
+        if (inst->operands().size() != 3) {
+          return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                 << "Hint and Bits are optional together i.e "
+                 << " Either both Hint and Bits should be provided or neither.";
+        }
+
+        // Validate the optional opreands Hint and Bits
+        const uint32_t hint_id = _.GetOperandTypeId(inst, 1);
+        if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) {
+          return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                 << "Hint must be a 32-bit int scalar";
+        }
+        const uint32_t bits_id = _.GetOperandTypeId(inst, 2);
+        if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) {
+          return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                 << "bits must be a 32-bit int scalar";
+        }
+      }
+      break;
+    }
+
+    case spv::Op::OpReorderThreadWithHintNV: {
+      std::string opcode_name = spvOpcodeString(inst->opcode());
+      _.function(inst->function()->id())
+          ->RegisterExecutionModelLimitation(
+              [opcode_name](spv::ExecutionModel model, std::string* message) {
+                if (model != spv::ExecutionModel::RayGenerationKHR) {
+                  if (message) {
+                    *message = opcode_name +
+                               " requires RayGenerationKHR execution model";
+                  }
+                  return false;
+                }
+                return true;
+              });
+
+      const uint32_t hint_id = _.GetOperandTypeId(inst, 0);
+      if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "Hint must be a 32-bit int scalar";
+      }
+
+      const uint32_t bits_id = _.GetOperandTypeId(inst, 1);
+      if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << "bits must be a 32-bit int scalar";
+      }
+    }
+
+    default:
+      break;
+  }
+  return SPV_SUCCESS;
+}
+}  // namespace val
+}  // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/val/validation_state.cpp b/third_party/SPIRV-Tools/source/val/validation_state.cpp
index d7a196c..c95eec3 100644
--- a/third_party/SPIRV-Tools/source/val/validation_state.cpp
+++ b/third_party/SPIRV-Tools/source/val/validation_state.cpp
@@ -790,6 +790,22 @@
               }
               return true;
             });
+  } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) {
+    function(consumer->function()->id())
+        ->RegisterExecutionModelLimitation([](spv::ExecutionModel model,
+                                              std::string* message) {
+          if (model != spv::ExecutionModel::RayGenerationKHR &&
+              model != spv::ExecutionModel::ClosestHitKHR &&
+              model != spv::ExecutionModel::MissKHR) {
+            if (message) {
+              *message =
+                  "HitObjectAttributeNV Storage Class is limited to "
+                  "RayGenerationKHR, ClosestHitKHR or MissKHR execution model";
+            }
+            return false;
+          }
+          return true;
+        });
   }
 }
 
@@ -1555,6 +1571,7 @@
       case spv::StorageClass::IncomingCallableDataKHR:
       case spv::StorageClass::ShaderRecordBufferKHR:
       case spv::StorageClass::TaskPayloadWorkgroupEXT:
+      case spv::StorageClass::HitObjectAttributeNV:
         return true;
       default:
         return false;
@@ -2060,20 +2077,14 @@
       return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698);
     case 4699:
       return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699);
-    case 4700:
-      return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700);
     case 4701:
       return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701);
-    case 4702:
-      return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04702);
     case 4703:
       return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703);
     case 4704:
       return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704);
     case 4705:
       return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705);
-    case 4706:
-      return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04706);
     case 7119:
       return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119);
     case 4708:
@@ -2132,8 +2143,6 @@
       return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
     case 6672:
       return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
-    case 6673:
-      return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-06673);
     case 6674:
       return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
     case 6675:
diff --git a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
index 36bf04c..af24e65 100644
--- a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
@@ -43,7 +43,7 @@
        desc_sroa_test.cpp
        eliminate_dead_const_test.cpp
        eliminate_dead_functions_test.cpp
-       eliminate_dead_input_components_test.cpp
+       eliminate_dead_io_components_test.cpp
        eliminate_dead_member_test.cpp
        eliminate_dead_output_stores_test.cpp
        feature_manager_test.cpp
diff --git a/third_party/SPIRV-Tools/test/opt/eliminate_dead_input_components_test.cpp b/third_party/SPIRV-Tools/test/opt/eliminate_dead_io_components_test.cpp
similarity index 93%
rename from third_party/SPIRV-Tools/test/opt/eliminate_dead_input_components_test.cpp
rename to third_party/SPIRV-Tools/test/opt/eliminate_dead_io_components_test.cpp
index 48bda22..f175e49 100644
--- a/third_party/SPIRV-Tools/test/opt/eliminate_dead_input_components_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/eliminate_dead_io_components_test.cpp
@@ -23,9 +23,9 @@
 namespace opt {
 namespace {
 
-using ElimDeadInputComponentsTest = PassTest<::testing::Test>;
+using ElimDeadIOComponentsTest = PassTest<::testing::Test>;
 
-TEST_F(ElimDeadInputComponentsTest, ElimOneConstantIndex) {
+TEST_F(ElimDeadIOComponentsTest, ElimOneConstantIndex) {
   // Should reduce to uv[2]
   //
   // #version 450
@@ -85,11 +85,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, ElimOneConstantIndexInBounds) {
+TEST_F(ElimDeadIOComponentsTest, ElimOneConstantIndexInBounds) {
   // Same as ElimOneConstantIndex but with OpInBoundsAccessChain
   const std::string text = R"(
                OpCapability Shader
@@ -136,11 +136,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, ElimTwoConstantIndices) {
+TEST_F(ElimDeadIOComponentsTest, ElimTwoConstantIndices) {
   // Should reduce to uv[4]
   //
   // #version 450
@@ -204,11 +204,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, NoElimMaxConstantIndex) {
+TEST_F(ElimDeadIOComponentsTest, NoElimMaxConstantIndex) {
   // Should not reduce uv[8] because of max index of 7
   //
   // #version 450
@@ -271,11 +271,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, NoElimNonConstantIndex) {
+TEST_F(ElimDeadIOComponentsTest, NoElimNonConstantIndex) {
   // Should not reduce uv[8] because of non-constant index of ui
   //
   // #version 450
@@ -354,11 +354,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, NoElimNonIndexedAccessChain) {
+TEST_F(ElimDeadIOComponentsTest, NoElimNonIndexedAccessChain) {
   // Should not change due to non-indexed access chain
   const std::string text = R"(
                OpCapability Shader
@@ -401,11 +401,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, ElimStructMember) {
+TEST_F(ElimDeadIOComponentsTest, ElimStructMember) {
   // Should eliminate uv
   //
   // #version 450
@@ -466,11 +466,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, ElimOutputStructMember) {
+TEST_F(ElimDeadIOComponentsTest, ElimOutputStructMember) {
   // Should eliminate uv from Vertex and all but gl_Position from gl_PerVertex
   //
   // #version 450
@@ -565,11 +565,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, true,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Output, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, ElimOutputArrayMembers) {
+TEST_F(ElimDeadIOComponentsTest, ElimOutputArrayMembers) {
   // Should reduce to uv[2]
   //
   // #version 450
@@ -618,11 +618,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, true,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Output, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, VertexOnly) {
+TEST_F(ElimDeadIOComponentsTest, VertexOnly) {
   // Should NOT eliminate uv
   //
   // #version 450
@@ -682,11 +682,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          true);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, true);
 }
 
-TEST_F(ElimDeadInputComponentsTest, TescInput) {
+TEST_F(ElimDeadIOComponentsTest, TescInput) {
   // Eliminate PointSize, ClipDistance, CullDistance from gl_in[]
   //
   // #version 450
@@ -771,11 +771,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, TescOutput) {
+TEST_F(ElimDeadIOComponentsTest, TescOutput) {
   // Eliminate PointSize, ClipDistance, CullDistance from gl_out[]
   //
   // #version 450
@@ -859,11 +859,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, true,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Output, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, TeseInput) {
+TEST_F(ElimDeadIOComponentsTest, TeseInput) {
   // Eliminate PointSize, ClipDistance, CullDistance from gl_in[]
   //
   // #version 450
@@ -946,11 +946,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, TeseOutput) {
+TEST_F(ElimDeadIOComponentsTest, TeseOutput) {
   // Eliminate PointSize, ClipDistance, CullDistance from gl_out
   //
   // #version 450
@@ -1030,11 +1030,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, true,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Output, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, GeomInput) {
+TEST_F(ElimDeadIOComponentsTest, GeomInput) {
   // Eliminate PointSize, ClipDistance, CullDistance from gl_in[]
   //
   // #version 450
@@ -1138,11 +1138,11 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, false,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Input, false);
 }
 
-TEST_F(ElimDeadInputComponentsTest, GeomOutput) {
+TEST_F(ElimDeadIOComponentsTest, GeomOutput) {
   // Eliminate PointSize, ClipDistance, CullDistance from gl_out
   //
   // #version 450
@@ -1245,8 +1245,8 @@
 
   SetTargetEnv(SPV_ENV_VULKAN_1_3);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndMatch<EliminateDeadInputComponentsPass>(text, true, true,
-                                                          false);
+  SinglePassRunAndMatch<EliminateDeadIOComponentsPass>(
+      text, true, spv::StorageClass::Output, false);
 }
 
 }  // namespace
diff --git a/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp b/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp
index aae9eb2..f83e86e 100644
--- a/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp
@@ -340,6 +340,41 @@
   SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
 }
 
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
+       CompositeInsertVectorIntoMatrix) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v2float = OpTypeVector %float 2
+ %mat2v2float = OpTypeMatrix %v2float 2
+    %float_0 = OpConstant %float 0
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+ %v2float_01 = OpConstantComposite %v2float %float_0 %float_1
+ %v2float_12 = OpConstantComposite %v2float %float_1 %float_2
+
+; CHECK: %10 = OpConstantComposite %v2float %float_0 %float_1
+; CHECK: %11 = OpConstantComposite %v2float %float_1 %float_2
+; CHECK: %12 = OpConstantComposite %mat2v2float %11 %11
+%mat2v2float_1212 = OpConstantComposite %mat2v2float %v2float_12 %v2float_12
+
+; CHECK: %15 = OpConstantComposite %mat2v2float %10 %11
+     %spec_0 = OpSpecConstantOp %mat2v2float CompositeInsert %v2float_01 %mat2v2float_1212 0
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
 TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertMatrix) {
   const std::string test =
       R"(
@@ -374,7 +409,7 @@
   SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
 }
 
-TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertNull) {
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertFloatNull) {
   const std::string test =
       R"(
                OpCapability Shader
@@ -384,16 +419,254 @@
        %void = OpTypeVoid
           %3 = OpTypeFunction %void
       %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_1 = OpConstant %float 1
+
+; CHECK: %7 = OpConstantNull %float
+; CHECK: %8 = OpConstantComposite %v3float %7 %7 %7
+; CHECK: %12 = OpConstantComposite %v3float %7 %7 %float_1
+       %null = OpConstantNull %float
+     %spec_0 = OpConstantComposite %v3float %null %null %null
+     %spec_1 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_0 2
+
+; CHECK: %float_1_0 = OpConstant %float 1
+     %spec_2 = OpSpecConstantOp %float CompositeExtract %spec_1 2
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
+       CompositeInsertFloatSetNull) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_1 = OpConstant %float 1
+
+; CHECK: %7 = OpConstantNull %float
+; CHECK: %8 = OpConstantComposite %v3float %7 %7 %float_1
+; CHECK: %12 = OpConstantComposite %v3float %7 %7 %7
+       %null = OpConstantNull %float
+     %spec_0 = OpConstantComposite %v3float %null %null %float_1
+     %spec_1 = OpSpecConstantOp %v3float CompositeInsert %null %spec_0 2
+
+; CHECK: %13 = OpConstantNull %float
+     %spec_2 = OpSpecConstantOp %float CompositeExtract %spec_1 2
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertVectorNull) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_1 = OpConstant %float 1
+       %null = OpConstantNull %v3float
+
+; CHECK: %11 = OpConstantNull %float
+; CHECK: %12 = OpConstantComposite %v3float %11 %11 %float_1
+     %spec_0 = OpSpecConstantOp %v3float CompositeInsert %float_1 %null 2
+
+
+; CHECK: %float_1_0 = OpConstant %float 1
+     %spec_1 = OpSpecConstantOp %float CompositeExtract %spec_0 2
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
+       CompositeInsertNullVectorIntoMatrix) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v2float = OpTypeVector %float 2
+ %mat2v2float = OpTypeMatrix %v2float 2
+       %null = OpConstantNull %mat2v2float
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+ %v2float_12 = OpConstantComposite %v2float %float_1 %float_2
+
+; CHECK: %13 = OpConstantNull %v2float
+; CHECK: %14 = OpConstantComposite %mat2v2float %10 %13
+     %spec_0 = OpSpecConstantOp %mat2v2float CompositeInsert %v2float_12 %null 0
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
+       CompositeInsertVectorKeepNull) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_0 = OpConstant %float 0
+ %null_float = OpConstantNull %float
+   %null_vec = OpConstantNull %v3float
+
+; CHECK: %15 = OpConstantComposite %v3float %7 %7 %float_0
+     %spec_0 = OpSpecConstantOp %v3float CompositeInsert %float_0 %null_vec 2
+
+; CHECK: %float_0_0 = OpConstant %float 0
+     %spec_1 = OpSpecConstantOp %float CompositeExtract %spec_0 2
+
+; CHECK: %17 = OpConstantComposite %v3float %7 %7 %7
+     %spec_2 = OpSpecConstantOp %v3float CompositeInsert %null_float %null_vec 2
+
+; CHECK: %18 = OpConstantNull %float
+     %spec_3 = OpSpecConstantOp %float CompositeExtract %spec_2 2
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+        %add = OpFAdd %float %spec_3 %spec_3
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
+       CompositeInsertVectorChainNull) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_1 = OpConstant %float 1
+       %null = OpConstantNull %v3float
+
+; CHECK: %15 = OpConstantNull %float
+; CHECK: %16 = OpConstantComposite %v3float %15 %15 %float_1
+; CHECK: %17 = OpConstantComposite %v3float %15 %float_1 %float_1
+; CHECK: %18 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+     %spec_0 = OpSpecConstantOp %v3float CompositeInsert %float_1 %null 2
+     %spec_1 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_0 1
+     %spec_2 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_1 0
+
+; CHECK: %float_1_0 = OpConstant %float 1
+; CHECK: %float_1_1 = OpConstant %float 1
+; CHECK: %float_1_2 = OpConstant %float 1
+     %spec_3 = OpSpecConstantOp %float CompositeExtract %spec_2 0
+     %spec_4 = OpSpecConstantOp %float CompositeExtract %spec_2 1
+     %spec_5 = OpSpecConstantOp %float CompositeExtract %spec_2 2
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
+       CompositeInsertVectorChainReset) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 1 1 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_1 = OpConstant %float 1
+       %null = OpConstantNull %float
+; CHECK: %8 = OpConstantComposite %v3float %7 %7 %float_1
+     %spec_0 = OpConstantComposite %v3float %null %null %float_1
+
+            ; set to null
+; CHECK: %13 = OpConstantComposite %v3float %7 %7 %7
+     %spec_1 = OpSpecConstantOp %v3float CompositeInsert %null %spec_0 2
+
+            ; set to back to original value
+; CHECK: %14 = OpConstantComposite %v3float %7 %7 %float_1
+     %spec_2 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_1 2
+
+; CHECK: %float_1_0 = OpConstant %float 1
+     %spec_3 = OpSpecConstantOp %float CompositeExtract %spec_2 2
+          %1 = OpFunction %void None %3
+      %label = OpLabel
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertMatrixNull) {
+  const std::string test =
+      R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main"
+               OpExecutionMode %main LocalSize 1 1 1
+       %void = OpTypeVoid
+       %func = OpTypeFunction %void
+      %float = OpTypeFloat 32
+        %int = OpTypeInt 32 0
 %v2float = OpTypeVector %float 2
 %mat2v2float = OpTypeMatrix %v2float 2
 %null = OpConstantNull %mat2v2float
     %float_1 = OpConstant %float 1
-  %v2float_1 = OpConstantComposite %v2float %float_1 %float_1
-   %mat2v2_1 = OpConstantComposite %mat2v2float %v2float_1 %v2float_1
- ; CHECK: %13 = OpConstantNull %mat2v2float
-         %14 = OpSpecConstantOp %mat2v2float CompositeInsert %mat2v2_1 %null 0 0
-          %1 = OpFunction %void None %3
-         %16 = OpLabel
+ ; CHECK: %13 = OpConstantNull %v2float
+ ; CHECK: %14 = OpConstantNull %float
+ ; CHECK: %15 = OpConstantComposite %v2float %float_1 %14
+ ; CHECK: %16 = OpConstantComposite %mat2v2float %13 %15
+       %spec = OpSpecConstantOp %mat2v2float CompositeInsert %float_1 %null 1 0
+; extra type def to make sure new type def are not just thrown at end
+      %v2int = OpTypeVector %int 2
+       %main = OpFunction %void None %func
+      %label = OpLabel
                OpReturn
                OpFunctionEnd
 )";
diff --git a/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp b/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp
index eebc50d..bc80050 100644
--- a/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp
@@ -172,6 +172,7 @@
   types.emplace_back(new AccelerationStructureNV());
   types.emplace_back(new CooperativeMatrixNV(f32, 24, 24, 24));
   types.emplace_back(new RayQueryKHR());
+  types.emplace_back(new HitObjectNV());
 
   return types;
 }
@@ -1085,6 +1086,7 @@
 ; CHECK: OpTypeAccelerationStructureKHR
 ; CHECK: OpTypeCooperativeMatrixNV [[f32]] [[uint24]] [[uint24]] [[uint24]]
 ; CHECK: OpTypeRayQueryKHR
+; CHECK: OpTypeHitObjectNV
 OpCapability Shader
 OpCapability Int64
 OpCapability Linkage
diff --git a/third_party/SPIRV-Tools/test/val/CMakeLists.txt b/third_party/SPIRV-Tools/test/val/CMakeLists.txt
index de89b93..62d93bd 100644
--- a/third_party/SPIRV-Tools/test/val/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/val/CMakeLists.txt
@@ -93,6 +93,7 @@
   SRCS
        val_ray_query_test.cpp
        val_ray_tracing_test.cpp
+       val_ray_tracing_reorder_test.cpp
        val_small_type_uses_test.cpp
        val_ssa_test.cpp
        val_state_test.cpp
diff --git a/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp b/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
index dae6c26..ff62f4b 100644
--- a/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
@@ -3210,48 +3210,6 @@
           "statically used per shader entry point."));
 }
 
-TEST_F(ValidateDecorations,
-       VulkanMultiplePushConstantsSingleEntryPointInterfaceBad) {
-  std::string spirv = R"(
-            OpCapability Shader
-            OpMemoryModel Logical GLSL450
-            OpEntryPoint Vertex %func1 "func1" %pc1 %pc2
-            OpDecorate %struct Block
-            OpMemberDecorate %struct 0 Offset 0
-    %void = OpTypeVoid
-  %voidfn = OpTypeFunction %void
-   %float = OpTypeFloat 32
-     %int = OpTypeInt 32 0
-   %int_0 = OpConstant %int 0
-  %struct = OpTypeStruct %float
-     %ptr = OpTypePointer PushConstant %struct
-%ptr_float = OpTypePointer PushConstant %float
-     %pc1 = OpVariable %ptr PushConstant
-     %pc2 = OpVariable %ptr PushConstant
-   %func1 = OpFunction %void None %voidfn
-  %label1 = OpLabel
- %access1 = OpAccessChain %ptr_float %pc1 %int_0
-   %load1 = OpLoad %float %access1
-            OpReturn
-            OpFunctionEnd
-   %func2 = OpFunction %void None %voidfn
-  %label2 = OpLabel
- %access2 = OpAccessChain %ptr_float %pc2 %int_0
-   %load2 = OpLoad %float %access2
-            OpReturn
-            OpFunctionEnd
-)";
-
-  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
-  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
-            ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
-  EXPECT_THAT(getDiagnosticString(),
-              AnyVUID("VUID-StandaloneSpirv-OpVariable-06673"));
-  EXPECT_THAT(getDiagnosticString(),
-              HasSubstr("Entry-point has more than one variable with the "
-                        "PushConstant storage class in the interface"));
-}
-
 TEST_F(ValidateDecorations, VulkanUniformMissingDescriptorSetBad) {
   std::string spirv = R"(
             OpCapability Shader
diff --git a/third_party/SPIRV-Tools/test/val/val_ray_tracing_reorder_test.cpp b/third_party/SPIRV-Tools/test/val/val_ray_tracing_reorder_test.cpp
new file mode 100644
index 0000000..6038c38
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/val/val_ray_tracing_reorder_test.cpp
@@ -0,0 +1,598 @@
+// Copyright (c) 2022 The Khronos Group Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Tests instructions from SPV_NV_shader_invocation_reorder.
+
+#include <sstream>
+#include <string>
+
+#include "gmock/gmock.h"
+#include "test/val/val_fixtures.h"
+
+namespace spvtools {
+namespace val {
+namespace {
+
+using ::testing::HasSubstr;
+using ::testing::Values;
+
+using ValidateRayTracingReorderNV = spvtest::ValidateBase<bool>;
+
+std::string GenerateReorderThreadCode(const std::string& body = "",
+                                      const std::string& declarations = "") {
+  std::ostringstream ss;
+  ss << R"(
+            OpCapability RayTracingKHR
+            OpCapability ShaderInvocationReorderNV
+            OpExtension "SPV_KHR_ray_tracing"
+            OpExtension "SPV_NV_shader_invocation_reorder"
+       %1 = OpExtInstImport "GLSL.std.450"
+            OpMemoryModel Logical GLSL450
+            OpEntryPoint RayGenerationNV %main "main" %hObj
+            OpSourceExtension "GL_EXT_ray_tracing"
+            OpSourceExtension "GL_NV_shader_invocation_reorder"
+            OpName %main "main"
+    %void = OpTypeVoid
+       %3 = OpTypeFunction %void
+       %6 = OpTypeHitObjectNV
+%_ptr_Private_6 = OpTypePointer Private %6
+    %hObj = OpVariable %_ptr_Private_6 Private
+    )";
+  ss << declarations;
+
+  ss << R"(
+   %main  = OpFunction %void None %3
+     %5   = OpLabel 
+    )";
+
+  ss << body;
+
+  ss << R"(
+            OpReturn
+            OpFunctionEnd
+    )";
+  return ss.str();
+}
+
+TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHintNV) {
+  const std::string declarations = R"(
+             %uint = OpTypeInt 32 0
+           %uint_4 = OpConstant %uint 4
+  )";
+
+  const std::string body = R"(
+    OpReorderThreadWithHintNV %uint_4 %uint_4
+  )";
+
+  CompileSuccessfully(GenerateReorderThreadCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHitObjectNV) {
+  const std::string declarations = R"(
+      %uint = OpTypeInt 32 0
+    %uint_4 = OpConstant %uint 4
+    %uint_2 = OpConstant %uint 2
+  )";
+
+  const std::string body = R"(
+             OpReorderThreadWithHitObjectNV %hObj
+             OpReorderThreadWithHitObjectNV %hObj %uint_4 %uint_2
+  )";
+
+  CompileSuccessfully(GenerateReorderThreadCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+std::string GenerateReorderShaderCode(
+    const std::string& body = "", const std::string& declarations = "",
+    const std::string execution_model = "RayGenerationKHR") {
+  std::ostringstream ss;
+  ss << R"(
+               OpCapability RayTracingKHR
+               OpCapability ShaderInvocationReorderNV
+               OpExtension "SPV_KHR_ray_tracing"
+               OpExtension "SPV_NV_shader_invocation_reorder"
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint )"
+     << execution_model
+     << R"( %main "main" %attr %_ %hObj %payload %__0 %as %__1
+               OpSource GLSL 460
+               OpSourceExtension "GL_EXT_ray_tracing"
+               OpSourceExtension "GL_NV_shader_invocation_reorder"
+               OpName %main "main"
+               OpName %attr "attr"
+               OpName %hBlock "hBlock"
+               OpMemberName %hBlock 0 "attrval"
+               OpName %_ ""
+               OpName %hObj "hObj"
+               OpName %payload "payload"
+               OpName %pBlock "pBlock"
+               OpMemberName %pBlock 0 "val1"
+               OpMemberName %pBlock 1 "val2"
+               OpName %__0 ""
+               OpName %as "as"
+               OpName %block "block"
+               OpMemberName %block 0 "op"
+               OpName %__1 ""
+               OpDecorate %hBlock Block
+               OpDecorate %pBlock Block
+               OpDecorate %as DescriptorSet 0
+               OpDecorate %as Binding 0
+               OpMemberDecorate %block 0 Offset 0
+               OpDecorate %block Block
+               OpDecorate %__1 DescriptorSet 0
+               OpDecorate %__1 Binding 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v2float = OpTypeVector %float 2
+%_ptr_HitObjectAttributeNV_v2float = OpTypePointer HitObjectAttributeNV %v2float
+       %attr = OpVariable %_ptr_HitObjectAttributeNV_v2float HitObjectAttributeNV
+    %float_1 = OpConstant %float 1
+         %11 = OpConstantComposite %v2float %float_1 %float_1
+     %hBlock = OpTypeStruct %float
+%_ptr_HitObjectAttributeNV_hBlock = OpTypePointer HitObjectAttributeNV %hBlock
+          %_ = OpVariable %_ptr_HitObjectAttributeNV_hBlock HitObjectAttributeNV
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+    %float_2 = OpConstant %float 2
+%_ptr_HitObjectAttributeNV_float = OpTypePointer HitObjectAttributeNV %float
+             %20 = OpTypeHitObjectNV
+    %_ptr_Private_20 = OpTypePointer Private %20
+           %hObj = OpVariable %_ptr_Private_20 Private
+             %23 = OpTypeAccelerationStructureKHR
+    %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
+             %as = OpVariable %_ptr_UniformConstant_23 UniformConstant
+    %v4float = OpTypeVector %float 4
+%_ptr_RayPayloadNV_v4float = OpTypePointer RayPayloadNV %v4float
+    %payload = OpVariable %_ptr_RayPayloadNV_v4float RayPayloadNV
+     %pBlock = OpTypeStruct %v2float %v2float
+%_ptr_RayPayloadNV_pBlock = OpTypePointer RayPayloadNV %pBlock
+        %__0 = OpVariable %_ptr_RayPayloadNV_pBlock RayPayloadNV
+      %block = OpTypeStruct %float
+%_ptr_StorageBuffer_block = OpTypePointer StorageBuffer %block
+        %__1 = OpVariable %_ptr_StorageBuffer_block StorageBuffer
+       )";
+
+  ss << declarations;
+
+  ss << R"(
+        %main = OpFunction %void None %3
+          %5 = OpLabel 
+         )";
+
+  ss << body;
+
+  ss << R"(
+               OpReturn
+               OpFunctionEnd)";
+  return ss.str();
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayNV) {
+  const std::string declarations = R"(
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+    %v3float = OpTypeVector %float 3
+  %float_0_5 = OpConstant %float 0.5
+         %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+         %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+      %int_1 = OpConstant %int 1
+  )";
+
+  const std::string body = R"(
+  OpStore %attr %11
+  %26 = OpLoad %23 %as
+  OpHitObjectTraceRayNV %hObj %26 %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %31 %float_0_5 %32 %float_1 %payload
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayMotionNV) {
+  const std::string declarations = R"(
+        %uint = OpTypeInt 32 0
+      %uint_1 = OpConstant %uint 1
+     %v3float = OpTypeVector %float 3
+   %float_0_5 = OpConstant %float 0.5
+          %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+          %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+    %float_10 = OpConstant %float 10
+       %int_2 = OpConstant %int 2
+  )";
+
+  const std::string body = R"(
+      OpStore %attr %11
+      %26 = OpLoad %23 %as
+      OpHitObjectTraceRayMotionNV %hObj %26 %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %31 %float_0_5 %32 %float_1 %float_10 %__0
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitNV) {
+  const std::string declarations = R"(
+        %int_1 = OpConstant %int 1
+        %uint = OpTypeInt 32 0
+      %uint_2 = OpConstant %uint 2
+     %v3float = OpTypeVector %float 3
+   %float_0_5 = OpConstant %float 0.5
+          %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+          %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+    %float_10 = OpConstant %float 10
+       %int_2 = OpConstant %int 2
+  )";
+
+  const std::string body = R"(
+      OpStore %attr %11
+      %26 = OpLoad %23 %as
+      OpHitObjectRecordHitNV %hObj %26 %int_1 %int_1 %int_1 %uint_2 %uint_2 %uint_2 %31 %float_1 %32 %float_2 %attr
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitWithIndexNV) {
+  const std::string declarations = R"(
+        %int_1 = OpConstant %int 1
+        %uint = OpTypeInt 32 0
+      %uint_2 = OpConstant %uint 2
+     %v3float = OpTypeVector %float 3
+   %float_0_5 = OpConstant %float 0.5
+          %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+          %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+    %float_10 = OpConstant %float 10
+       %int_2 = OpConstant %int 2
+  )";
+
+  const std::string body = R"(
+      OpStore %attr %11
+      %26 = OpLoad %23 %as
+      OpHitObjectRecordHitWithIndexNV %hObj %26 %int_1 %int_1 %int_1 %uint_2 %uint_2 %31 %float_1 %32 %float_2 %_
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectRecordEmptyNV) {
+  const std::string body = R"(
+      OpHitObjectRecordEmptyNV %hObj
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectRecordMissNV) {
+  const std::string declarations = R"(
+         %uint = OpTypeInt 32 0
+       %uint_1 = OpConstant %uint 1
+      %v3float = OpTypeVector %float 3
+    %float_0_5 = OpConstant %float 0.5
+           %29 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+    %float_1_5 = OpConstant %float 1.5
+           %31 = OpConstantComposite %v3float %float_1_5 %float_1_5 %float_1_5
+      %float_5 = OpConstant %float 5
+  )";
+
+  const std::string body = R"(
+      OpHitObjectRecordMissNV %hObj %uint_1 %29 %float_2 %31 %float_5
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectIsHitNV) {
+  const std::string declarations = R"(
+        %bool = OpTypeBool
+        %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+  )";
+
+  const std::string body = R"(
+      %26 = OpHitObjectIsHitNV %bool %hObj
+            OpSelectionMerge %28 None
+            OpBranchConditional %26 %27 %28
+      %27 = OpLabel
+      %33 = OpAccessChain %_ptr_StorageBuffer_float %__1 %int_0
+            OpStore %33 %float_1
+            OpBranch %28
+      %28 = OpLabel
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMaxNV) {
+  const std::string declarations = R"(
+        %_ptr_Function_float = OpTypePointer Function %float
+  )";
+
+  const std::string body = R"(
+      %tmin = OpVariable %_ptr_Function_float Function
+      %12 = OpHitObjectGetRayTMaxNV %float %hObj
+      OpStore %tmin %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMinNV) {
+  const std::string declarations = R"(
+        %_ptr_Function_float = OpTypePointer Function %float
+  )";
+
+  const std::string body = R"(
+      %tmin = OpVariable %_ptr_Function_float Function
+      %12 = OpHitObjectGetRayTMinNV %float %hObj
+      OpStore %tmin %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayOriginNV) {
+  const std::string declarations = R"(
+        %v3float = OpTypeVector %float 3
+        %_ptr_Function_v3float = OpTypePointer Function %v3float
+  )";
+
+  const std::string body = R"(
+      %orig = OpVariable %_ptr_Function_v3float Function
+      %13 = OpHitObjectGetWorldRayOriginNV %v3float %hObj
+      OpStore %orig %13
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayOriginNV) {
+  const std::string declarations = R"(
+        %v3float = OpTypeVector %float 3
+        %_ptr_Function_v3float = OpTypePointer Function %v3float
+  )";
+
+  const std::string body = R"(
+      %oorig = OpVariable %_ptr_Function_v3float Function
+      %13 = OpHitObjectGetObjectRayOriginNV %v3float %hObj
+      OpStore %oorig %13
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayDirectionNV) {
+  const std::string declarations = R"(
+        %v3float = OpTypeVector %float 3
+        %_ptr_Function_v3float = OpTypePointer Function %v3float
+  )";
+
+  const std::string body = R"(
+      %dir = OpVariable %_ptr_Function_v3float Function
+      %13 = OpHitObjectGetWorldRayDirectionNV %v3float %hObj
+      OpStore %dir %13
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayDirectionNV) {
+  const std::string declarations = R"(
+        %v3float = OpTypeVector %float 3
+        %_ptr_Function_v3float = OpTypePointer Function %v3float
+  )";
+
+  const std::string body = R"(
+      %odir = OpVariable %_ptr_Function_v3float Function
+      %13 = OpHitObjectGetObjectRayDirectionNV %v3float %hObj
+      OpStore %odir %13
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectToWorldNV) {
+  const std::string declarations = R"(
+        %v3float = OpTypeVector %float 3
+        %mat4v3float = OpTypeMatrix %v3float 4
+        %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
+  )";
+
+  const std::string body = R"(
+      %otw = OpVariable %_ptr_Function_mat4v3float Function
+      %14 = OpHitObjectGetObjectToWorldNV %mat4v3float %hObj
+      OpStore %otw %14
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldToObjectNV) {
+  const std::string declarations = R"(
+        %v3float = OpTypeVector %float 3
+        %mat4v3float = OpTypeMatrix %v3float 4
+        %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
+  )";
+
+  const std::string body = R"(
+      %wto = OpVariable %_ptr_Function_mat4v3float Function
+      %14 = OpHitObjectGetWorldToObjectNV %mat4v3float %hObj
+      OpStore %wto %14
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceCustomIndexNV) {
+  const std::string declarations = R"(
+        %_ptr_Function_int = OpTypePointer Function %int
+  )";
+
+  const std::string body = R"(
+      %id = OpVariable %_ptr_Function_int Function
+      %12 = OpHitObjectGetInstanceCustomIndexNV %int %hObj
+      OpStore %id %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceIdNV) {
+  const std::string declarations = R"(
+        %_ptr_Function_int = OpTypePointer Function %int
+  )";
+
+  const std::string body = R"(
+      %id = OpVariable %_ptr_Function_int Function
+      %12 = OpHitObjectGetInstanceIdNV %int %hObj
+      OpStore %id %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetPrimitiveIndexNV) {
+  const std::string declarations = R"(
+        %_ptr_Function_int = OpTypePointer Function %int
+  )";
+
+  const std::string body = R"(
+      %id = OpVariable %_ptr_Function_int Function
+      %12 = OpHitObjectGetPrimitiveIndexNV %int %hObj
+      OpStore %id %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetGeometryIndexNV) {
+  const std::string declarations = R"(
+        %_ptr_Function_int = OpTypePointer Function %int
+  )";
+
+  const std::string body = R"(
+      %id = OpVariable %_ptr_Function_int Function
+      %12 = OpHitObjectGetGeometryIndexNV %int %hObj
+      OpStore %id %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetHitKindNV) {
+  const std::string declarations = R"(
+    %uint = OpTypeInt 32 0
+    %_ptr_Function_uint = OpTypePointer Function %uint
+  )";
+
+  const std::string body = R"(
+    %uid = OpVariable %_ptr_Function_uint Function
+    %12 = OpHitObjectGetHitKindNV %uint %hObj
+    OpStore %uid %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetAttributesNV) {
+  const std::string body = R"(
+    OpHitObjectGetAttributesNV %hObj %attr
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV, HitObjectGetShaderRecordBufferHandleNV) {
+  const std::string declarations = R"(
+           %uint = OpTypeInt 32 0
+         %v2uint = OpTypeVector %uint 2
+    %_ptr_Function_v2uint = OpTypePointer Function %v2uint
+  )";
+
+  const std::string body = R"(
+    %handle = OpVariable %_ptr_Function_v2uint Function
+        %13 = OpHitObjectGetShaderRecordBufferHandleNV %v2uint %hObj
+              OpStore %handle %13
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateRayTracingReorderNV,
+       HitObjectGetShaderBindingTableRecordIndexNV) {
+  const std::string declarations = R"(
+    %uint = OpTypeInt 32 0
+    %_ptr_Function_uint = OpTypePointer Function %uint
+  )";
+
+  const std::string body = R"(
+    %rid = OpVariable %_ptr_Function_uint Function
+     %12 = OpHitObjectGetShaderBindingTableRecordIndexNV %uint %hObj
+           OpStore %rid %12
+  )";
+
+  CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
+                      SPV_ENV_VULKAN_1_2);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+}  // namespace
+}  // namespace val
+}  // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp b/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp
index 60f2f89..58b9356 100644
--- a/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp
@@ -578,95 +578,6 @@
                         "IncomingRayPayloadKHR"));
 }
 
-TEST_F(ValidateRayTracing, InterfaceIncomingRayPayload) {
-  const std::string body = R"(
-OpCapability RayTracingKHR
-OpExtension "SPV_KHR_ray_tracing"
-OpMemoryModel Logical GLSL450
-OpEntryPoint CallableKHR %main "main" %inData1 %inData2
-OpName %main "main"
-%void = OpTypeVoid
-%func = OpTypeFunction %void
-%int = OpTypeInt 32 1
-%inData_ptr = OpTypePointer IncomingRayPayloadKHR %int
-%inData1 = OpVariable %inData_ptr IncomingRayPayloadKHR
-%inData2 = OpVariable %inData_ptr IncomingRayPayloadKHR
-%main = OpFunction %void None %func
-%label = OpLabel
-OpReturn
-OpFunctionEnd
-)";
-
-  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
-  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
-            ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
-  EXPECT_THAT(getDiagnosticString(),
-              AnyVUID("VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700"));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("Entry-point has more than one variable with the "
-                "IncomingRayPayloadKHR storage class in the interface"));
-}
-
-TEST_F(ValidateRayTracing, InterfaceHitAttribute) {
-  const std::string body = R"(
-OpCapability RayTracingKHR
-OpExtension "SPV_KHR_ray_tracing"
-OpMemoryModel Logical GLSL450
-OpEntryPoint CallableKHR %main "main" %inData1 %inData2
-OpName %main "main"
-%void = OpTypeVoid
-%func = OpTypeFunction %void
-%int = OpTypeInt 32 1
-%inData_ptr = OpTypePointer HitAttributeKHR %int
-%inData1 = OpVariable %inData_ptr HitAttributeKHR
-%inData2 = OpVariable %inData_ptr HitAttributeKHR
-%main = OpFunction %void None %func
-%label = OpLabel
-OpReturn
-OpFunctionEnd
-)";
-
-  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
-  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
-            ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
-  EXPECT_THAT(getDiagnosticString(),
-              AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04702"));
-  EXPECT_THAT(getDiagnosticString(),
-              HasSubstr("Entry-point has more than one variable with the "
-                        "HitAttributeKHR storage class in the interface"));
-}
-
-TEST_F(ValidateRayTracing, InterfaceIncomingCallableData) {
-  const std::string body = R"(
-OpCapability RayTracingKHR
-OpExtension "SPV_KHR_ray_tracing"
-OpMemoryModel Logical GLSL450
-OpEntryPoint CallableKHR %main "main" %inData1 %inData2
-OpName %main "main"
-%void = OpTypeVoid
-%func = OpTypeFunction %void
-%int = OpTypeInt 32 1
-%inData_ptr = OpTypePointer IncomingCallableDataKHR %int
-%inData1 = OpVariable %inData_ptr IncomingCallableDataKHR
-%inData2 = OpVariable %inData_ptr IncomingCallableDataKHR
-%main = OpFunction %void None %func
-%label = OpLabel
-OpReturn
-OpFunctionEnd
-)";
-
-  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
-  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
-            ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
-  EXPECT_THAT(getDiagnosticString(),
-              AnyVUID("VUID-StandaloneSpirv-IncomingCallableDataKHR-04706"));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("Entry-point has more than one variable with the "
-                "IncomingCallableDataKHR storage class in the interface"));
-}
-
 }  // namespace
 }  // namespace val
 }  // namespace spvtools