// Copyright (c) 2018 Google LLC.
// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All
// rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <string>
#include <vector>

#include "source/opcode.h"
#include "source/spirv_target_env.h"
#include "source/val/instruction.h"
#include "source/val/validate.h"
#include "source/val/validate_scopes.h"
#include "source/val/validation_state.h"

namespace spvtools {
namespace val {
namespace {

bool AreLayoutCompatibleStructs(ValidationState_t&, const Instruction*,
                                const Instruction*);
bool HaveLayoutCompatibleMembers(ValidationState_t&, const Instruction*,
                                 const Instruction*);
bool HaveSameLayoutDecorations(ValidationState_t&, const Instruction*,
                               const Instruction*);
bool HasConflictingMemberOffsets(const std::set<Decoration>&,
                                 const std::set<Decoration>&);

bool IsAllowedTypeOrArrayOfSame(ValidationState_t& _, const Instruction* type,
                                std::initializer_list<spv::Op> allowed) {
  if (std::find(allowed.begin(), allowed.end(), type->opcode()) !=
      allowed.end()) {
    return true;
  }
  if (type->opcode() == spv::Op::OpTypeArray ||
      type->opcode() == spv::Op::OpTypeRuntimeArray) {
    auto elem_type = _.FindDef(type->word(2));
    return std::find(allowed.begin(), allowed.end(), elem_type->opcode()) !=
           allowed.end();
  }
  return false;
}

// Returns true if the two instructions represent structs that, as far as the
// validator can tell, have the exact same data layout.
bool AreLayoutCompatibleStructs(ValidationState_t& _, const Instruction* type1,
                                const Instruction* type2) {
  if (type1->opcode() != spv::Op::OpTypeStruct) {
    return false;
  }
  if (type2->opcode() != spv::Op::OpTypeStruct) {
    return false;
  }

  if (!HaveLayoutCompatibleMembers(_, type1, type2)) return false;

  return HaveSameLayoutDecorations(_, type1, type2);
}

// Returns true if the operands to the OpTypeStruct instruction defining the
// types are the same or are layout compatible types. |type1| and |type2| must
// be OpTypeStruct instructions.
bool HaveLayoutCompatibleMembers(ValidationState_t& _, const Instruction* type1,
                                 const Instruction* type2) {
  assert(type1->opcode() == spv::Op::OpTypeStruct &&
         "type1 must be an OpTypeStruct instruction.");
  assert(type2->opcode() == spv::Op::OpTypeStruct &&
         "type2 must be an OpTypeStruct instruction.");
  const auto& type1_operands = type1->operands();
  const auto& type2_operands = type2->operands();
  if (type1_operands.size() != type2_operands.size()) {
    return false;
  }

  for (size_t operand = 2; operand < type1_operands.size(); ++operand) {
    if (type1->word(operand) != type2->word(operand)) {
      auto def1 = _.FindDef(type1->word(operand));
      auto def2 = _.FindDef(type2->word(operand));
      if (!AreLayoutCompatibleStructs(_, def1, def2)) {
        return false;
      }
    }
  }
  return true;
}

// Returns true if all decorations that affect the data layout of the struct
// (like Offset), are the same for the two types. |type1| and |type2| must be
// OpTypeStruct instructions.
bool HaveSameLayoutDecorations(ValidationState_t& _, const Instruction* type1,
                               const Instruction* type2) {
  assert(type1->opcode() == spv::Op::OpTypeStruct &&
         "type1 must be an OpTypeStruct instruction.");
  assert(type2->opcode() == spv::Op::OpTypeStruct &&
         "type2 must be an OpTypeStruct instruction.");
  const std::set<Decoration>& type1_decorations = _.id_decorations(type1->id());
  const std::set<Decoration>& type2_decorations = _.id_decorations(type2->id());

  // TODO: Will have to add other check for arrays an matricies if we want to
  // handle them.
  if (HasConflictingMemberOffsets(type1_decorations, type2_decorations)) {
    return false;
  }

  return true;
}

bool HasConflictingMemberOffsets(
    const std::set<Decoration>& type1_decorations,
    const std::set<Decoration>& type2_decorations) {
  {
    // We are interested in conflicting decoration.  If a decoration is in one
    // list but not the other, then we will assume the code is correct.  We are
    // looking for things we know to be wrong.
    //
    // We do not have to traverse type2_decoration because, after traversing
    // type1_decorations, anything new will not be found in
    // type1_decoration.  Therefore, it cannot lead to a conflict.
    for (const Decoration& decoration : type1_decorations) {
      switch (decoration.dec_type()) {
        case spv::Decoration::Offset: {
          // Since these affect the layout of the struct, they must be present
          // in both structs.
          auto compare = [&decoration](const Decoration& rhs) {
            if (rhs.dec_type() != spv::Decoration::Offset) return false;
            return decoration.struct_member_index() ==
                   rhs.struct_member_index();
          };
          auto i = std::find_if(type2_decorations.begin(),
                                type2_decorations.end(), compare);
          if (i != type2_decorations.end() &&
              decoration.params().front() != i->params().front()) {
            return true;
          }
        } break;
        default:
          // This decoration does not affect the layout of the structure, so
          // just moving on.
          break;
      }
    }
  }
  return false;
}

// If |skip_builtin| is true, returns true if |storage| contains bool within
// it and no storage that contains the bool is builtin.
// If |skip_builtin| is false, returns true if |storage| contains bool within
// it.
bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage,
                         bool skip_builtin) {
  if (skip_builtin) {
    for (const Decoration& decoration : _.id_decorations(storage->id())) {
      if (decoration.dec_type() == spv::Decoration::BuiltIn) return false;
    }
  }

  const size_t elem_type_index = 1;
  uint32_t elem_type_id;
  Instruction* elem_type;

  switch (storage->opcode()) {
    case spv::Op::OpTypeBool:
      return true;
    case spv::Op::OpTypeVector:
    case spv::Op::OpTypeMatrix:
    case spv::Op::OpTypeArray:
    case spv::Op::OpTypeRuntimeArray:
      elem_type_id = storage->GetOperandAs<uint32_t>(elem_type_index);
      elem_type = _.FindDef(elem_type_id);
      return ContainsInvalidBool(_, elem_type, skip_builtin);
    case spv::Op::OpTypeStruct:
      for (size_t member_type_index = 1;
           member_type_index < storage->operands().size();
           ++member_type_index) {
        auto member_type_id =
            storage->GetOperandAs<uint32_t>(member_type_index);
        auto member_type = _.FindDef(member_type_id);
        if (ContainsInvalidBool(_, member_type, skip_builtin)) return true;
      }
    default:
      break;
  }
  return false;
}

std::pair<spv::StorageClass, spv::StorageClass> GetStorageClass(
    ValidationState_t& _, const Instruction* inst) {
  spv::StorageClass dst_sc = spv::StorageClass::Max;
  spv::StorageClass src_sc = spv::StorageClass::Max;
  switch (inst->opcode()) {
    case spv::Op::OpCooperativeMatrixLoadNV:
    case spv::Op::OpCooperativeMatrixLoadTensorNV:
    case spv::Op::OpCooperativeMatrixLoadKHR:
    case spv::Op::OpCooperativeVectorLoadNV:
    case spv::Op::OpLoad: {
      auto load_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(2));
      auto load_pointer_type = _.FindDef(load_pointer->type_id());
      dst_sc = load_pointer_type->GetOperandAs<spv::StorageClass>(1);
      break;
    }
    case spv::Op::OpCooperativeMatrixStoreNV:
    case spv::Op::OpCooperativeMatrixStoreTensorNV:
    case spv::Op::OpCooperativeMatrixStoreKHR:
    case spv::Op::OpCooperativeVectorStoreNV:
    case spv::Op::OpStore: {
      auto store_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(0));
      auto store_pointer_type = _.FindDef(store_pointer->type_id());
      dst_sc = store_pointer_type->GetOperandAs<spv::StorageClass>(1);
      break;
    }
    case spv::Op::OpCopyMemory:
    case spv::Op::OpCopyMemorySized: {
      auto dst = _.FindDef(inst->GetOperandAs<uint32_t>(0));
      auto dst_type = _.FindDef(dst->type_id());
      dst_sc = dst_type->GetOperandAs<spv::StorageClass>(1);
      auto src = _.FindDef(inst->GetOperandAs<uint32_t>(1));
      auto src_type = _.FindDef(src->type_id());
      src_sc = src_type->GetOperandAs<spv::StorageClass>(1);
      break;
    }
    default:
      break;
  }

  return std::make_pair(dst_sc, src_sc);
}

// Returns the number of instruction words taken up by a memory access
// argument and its implied operands.
int MemoryAccessNumWords(uint32_t mask) {
  int result = 1;  // Count the mask
  if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result;
  if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result;
  if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result;
  return result;
}

// Returns the scope ID operand for MakeAvailable memory access with mask
// at the given operand index.
// This function is only called for OpLoad, OpStore, OpCopyMemory and
// OpCopyMemorySized, OpCooperativeMatrixLoadNV,
// OpCooperativeMatrixStoreNV, OpCooperativeVectorLoadNV,
// OpCooperativeVectorStoreNV.
uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask,
                               uint32_t mask_index) {
  assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR));
  uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR);
  uint32_t index =
      mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1)));
  return inst->GetOperandAs<uint32_t>(index);
}

// This function is only called for OpLoad, OpStore, OpCopyMemory,
// OpCopyMemorySized, OpCooperativeMatrixLoadNV,
// OpCooperativeMatrixStoreNV, OpCooperativeVectorLoadNV,
// OpCooperativeVectorStoreNV.
uint32_t GetMakeVisibleScope(const Instruction* inst, uint32_t mask,
                             uint32_t mask_index) {
  assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR));
  uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR);
  uint32_t index =
      mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1)));
  return inst->GetOperandAs<uint32_t>(index);
}

bool DoesStructContainRTA(const ValidationState_t& _, const Instruction* inst) {
  for (size_t member_index = 1; member_index < inst->operands().size();
       ++member_index) {
    const auto member_id = inst->GetOperandAs<uint32_t>(member_index);
    const auto member_type = _.FindDef(member_id);
    if (member_type->opcode() == spv::Op::OpTypeRuntimeArray) return true;
  }
  return false;
}

spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
                               uint32_t index) {
  spv::StorageClass dst_sc, src_sc;
  std::tie(dst_sc, src_sc) = GetStorageClass(_, inst);
  if (inst->operands().size() <= index) {
    // Cases where lack of some operand is invalid
    if (src_sc == spv::StorageClass::PhysicalStorageBuffer ||
        dst_sc == spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << _.VkErrorID(4708)
             << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
    }
    return SPV_SUCCESS;
  }

  const uint32_t mask = inst->GetOperandAs<uint32_t>(index);
  if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) {
    if (inst->opcode() == spv::Op::OpLoad ||
        inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV ||
        inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV ||
        inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR ||
        inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "MakePointerAvailableKHR cannot be used with OpLoad.";
    }

    if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "NonPrivatePointerKHR must be specified if "
                "MakePointerAvailableKHR is specified.";
    }

    // Check the associated scope for MakeAvailableKHR.
    const auto available_scope = GetMakeAvailableScope(inst, mask, index);
    if (auto error = ValidateMemoryScope(_, inst, available_scope))
      return error;
  }

  if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) {
    if (inst->opcode() == spv::Op::OpStore ||
        inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV ||
        inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR ||
        inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV ||
        inst->opcode() == spv::Op::OpCooperativeVectorStoreNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "MakePointerVisibleKHR cannot be used with OpStore.";
    }

    if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "NonPrivatePointerKHR must be specified if "
             << "MakePointerVisibleKHR is specified.";
    }

    // Check the associated scope for MakeVisibleKHR.
    const auto visible_scope = GetMakeVisibleScope(inst, mask, index);
    if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error;
  }

  if (mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR)) {
    if (dst_sc != spv::StorageClass::Uniform &&
        dst_sc != spv::StorageClass::Workgroup &&
        dst_sc != spv::StorageClass::CrossWorkgroup &&
        dst_sc != spv::StorageClass::Generic &&
        dst_sc != spv::StorageClass::Image &&
        dst_sc != spv::StorageClass::StorageBuffer &&
        dst_sc != spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "NonPrivatePointerKHR requires a pointer in Uniform, "
             << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
             << "storage classes.";
    }
    if (src_sc != spv::StorageClass::Max &&
        src_sc != spv::StorageClass::Uniform &&
        src_sc != spv::StorageClass::Workgroup &&
        src_sc != spv::StorageClass::CrossWorkgroup &&
        src_sc != spv::StorageClass::Generic &&
        src_sc != spv::StorageClass::Image &&
        src_sc != spv::StorageClass::StorageBuffer &&
        src_sc != spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "NonPrivatePointerKHR requires a pointer in Uniform, "
             << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
             << "storage classes.";
    }
  }

  if (!(mask & uint32_t(spv::MemoryAccessMask::Aligned))) {
    if (src_sc == spv::StorageClass::PhysicalStorageBuffer ||
        dst_sc == spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << _.VkErrorID(4708)
             << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
    }
  } else {
    // even if there are other masks, the Aligned operand will be next
    const uint32_t aligned_value = inst->GetOperandAs<uint32_t>(index + 1);
    const bool is_power_of_two =
        aligned_value && !(aligned_value & (aligned_value - 1));
    if (!is_power_of_two) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Memory accesses Aligned operand value " << aligned_value
             << " is not a power of two.";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
  const bool untyped_pointer = inst->opcode() == spv::Op::OpUntypedVariableKHR;

  auto result_type = _.FindDef(inst->type_id());
  if (untyped_pointer) {
    if (!result_type ||
        result_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Result type must be an untyped pointer";
  } else {
    if (!result_type || result_type->opcode() != spv::Op::OpTypePointer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpVariable Result Type <id> " << _.getIdName(inst->type_id())
             << " is not a pointer type.";
    }
  }

  const auto storage_class_index = 2u;
  auto storage_class =
      inst->GetOperandAs<spv::StorageClass>(storage_class_index);
  uint32_t value_id = 0;
  if (untyped_pointer) {
    const auto has_data_type = 3u < inst->operands().size();
    if (has_data_type) {
      value_id = inst->GetOperandAs<uint32_t>(3u);
      auto data_type = _.FindDef(value_id);
      if (!data_type || !spvOpcodeGeneratesType(data_type->opcode())) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Data type must be a type instruction";
      }
    } else {
      if (storage_class == spv::StorageClass::Function ||
          storage_class == spv::StorageClass::Private ||
          storage_class == spv::StorageClass::Workgroup) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Data type must be specified for Function, Private, and "
                  "Workgroup storage classes";
      }
      if (spvIsVulkanEnv(_.context()->target_env)) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Vulkan requires that data type be specified";
      }
    }
  }

  // For OpVariable the data type comes from pointee type of the result type,
  // while for OpUntypedVariableKHR the data type comes from the operand.
  if (!untyped_pointer) {
    value_id = result_type->GetOperandAs<uint32_t>(2);
  }
  auto value_type = value_id == 0 ? nullptr : _.FindDef(value_id);

  const auto initializer_index = untyped_pointer ? 4u : 3u;
  if (initializer_index < inst->operands().size()) {
    const auto initializer_id = inst->GetOperandAs<uint32_t>(initializer_index);
    const auto initializer = _.FindDef(initializer_id);
    const auto is_module_scope_var =
        initializer &&
        (initializer->opcode() == spv::Op::OpVariable ||
         initializer->opcode() == spv::Op::OpUntypedVariableKHR) &&
        (initializer->GetOperandAs<spv::StorageClass>(storage_class_index) !=
         spv::StorageClass::Function);
    const auto is_constant =
        initializer && spvOpcodeIsConstant(initializer->opcode());
    if (!initializer || !(is_constant || is_module_scope_var)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Variable Initializer <id> " << _.getIdName(initializer_id)
             << " is not a constant or module-scope variable.";
    }
    if (initializer->type_id() != value_id) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Initializer type must match the data type";
    }
  }

  if (storage_class != spv::StorageClass::Workgroup &&
      storage_class != spv::StorageClass::CrossWorkgroup &&
      storage_class != spv::StorageClass::Private &&
      storage_class != spv::StorageClass::Function &&
      storage_class != spv::StorageClass::UniformConstant &&
      storage_class != spv::StorageClass::RayPayloadKHR &&
      storage_class != spv::StorageClass::IncomingRayPayloadKHR &&
      storage_class != spv::StorageClass::HitAttributeKHR &&
      storage_class != spv::StorageClass::CallableDataKHR &&
      storage_class != spv::StorageClass::IncomingCallableDataKHR &&
      storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT &&
      storage_class != spv::StorageClass::HitObjectAttributeNV &&
      storage_class != spv::StorageClass::NodePayloadAMDX) {
    bool storage_input_or_output = storage_class == spv::StorageClass::Input ||
                                   storage_class == spv::StorageClass::Output;
    bool builtin = false;
    if (storage_input_or_output) {
      for (const Decoration& decoration : _.id_decorations(inst->id())) {
        if (decoration.dec_type() == spv::Decoration::BuiltIn) {
          builtin = true;
          break;
        }
      }
    }
    if (!builtin && value_type &&
        ContainsInvalidBool(_, value_type, storage_input_or_output)) {
      if (storage_input_or_output) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(7290)
               << "If OpTypeBool is stored in conjunction with OpVariable "
                  "using Input or Output Storage Classes it requires a BuiltIn "
                  "decoration";

      } else {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "If OpTypeBool is stored in conjunction with OpVariable, it "
                  "can only be used with non-externally visible shader Storage "
                  "Classes: Workgroup, CrossWorkgroup, Private, Function, "
                  "Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, "
                  "HitAttributeKHR, CallableDataKHR, "
                  "IncomingCallableDataKHR, NodePayloadAMDX, or "
                  "UniformConstant";
      }
    }
  }

  if (!_.IsValidStorageClass(storage_class)) {
    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
           << _.VkErrorID(4643)
           << "Invalid storage class for target environment";
  }

  if (storage_class == spv::StorageClass::Generic) {
    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
           << "Variable storage class cannot be Generic";
  }

  if (inst->function() && storage_class != spv::StorageClass::Function) {
    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
           << "Variables must have a function[7] storage class inside"
              " of a function";
  }

  if (!inst->function() && storage_class == spv::StorageClass::Function) {
    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
           << "Variables can not have a function[7] storage class "
              "outside of a function";
  }

  // SPIR-V 3.32.8: Check that pointer type and variable type have the same
  // storage class.
  const auto result_storage_class_index = 1;
  const auto result_storage_class =
      result_type->GetOperandAs<spv::StorageClass>(result_storage_class_index);
  if (storage_class != result_storage_class) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Storage class must match result type storage class";
  }

  // Variable pointer related restrictions.
  const auto pointee = untyped_pointer
                           ? value_id == 0 ? nullptr : _.FindDef(value_id)
                           : _.FindDef(result_type->word(3));
  if (_.addressing_model() == spv::AddressingModel::Logical &&
      !_.options()->relax_logical_pointer) {
    // VariablePointersStorageBuffer is implied by VariablePointers.
    if (pointee && pointee->opcode() == spv::Op::OpTypePointer) {
      if (!_.HasCapability(spv::Capability::VariablePointersStorageBuffer)) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "In Logical addressing, variables may not allocate a pointer "
               << "type";
      } else if (storage_class != spv::StorageClass::Function &&
                 storage_class != spv::StorageClass::Private) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "In Logical addressing with variable pointers, variables "
               << "that allocate pointers must be in Function or Private "
               << "storage classes";
      }
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    // Vulkan Push Constant Interface section: Check type of PushConstant
    // variables.
    if (storage_class == spv::StorageClass::PushConstant) {
      if (pointee && pointee->opcode() != spv::Op::OpTypeStruct) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(6808) << "PushConstant OpVariable <id> "
               << _.getIdName(inst->id()) << " has illegal type.\n"
               << "From Vulkan spec, Push Constant Interface section:\n"
               << "Such variables must be typed as OpTypeStruct";
      }
    }

    // Vulkan Descriptor Set Interface: Check type of UniformConstant and
    // Uniform variables.
    if (storage_class == spv::StorageClass::UniformConstant) {
      if (pointee && !IsAllowedTypeOrArrayOfSame(
                         _, pointee,
                         {spv::Op::OpTypeImage, spv::Op::OpTypeSampler,
                          spv::Op::OpTypeSampledImage, spv::Op::OpTypeTensorARM,
                          spv::Op::OpTypeAccelerationStructureKHR})) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(4655) << "UniformConstant OpVariable <id> "
               << _.getIdName(inst->id()) << " has illegal type.\n"
               << "Variables identified with the UniformConstant storage class "
               << "are used only as handles to refer to opaque resources. Such "
               << "variables must be typed as OpTypeImage, OpTypeSampler, "
               << "OpTypeSampledImage, OpTypeAccelerationStructureKHR, "
               << "or an array of one of these types.";
      }
    }

    if (storage_class == spv::StorageClass::Uniform) {
      if (pointee &&
          !IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(6807) << "Uniform OpVariable <id> "
               << _.getIdName(inst->id()) << " has illegal type.\n"
               << "From Vulkan spec:\n"
               << "Variables identified with the Uniform storage class are "
               << "used to access transparent buffer backed resources. Such "
               << "variables must be typed as OpTypeStruct, or an array of "
               << "this type";
      }
    }

    if (storage_class == spv::StorageClass::StorageBuffer) {
      if (pointee &&
          !IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(6807) << "StorageBuffer OpVariable <id> "
               << _.getIdName(inst->id()) << " has illegal type.\n"
               << "From Vulkan spec:\n"
               << "Variables identified with the StorageBuffer storage class "
                  "are used to access transparent buffer backed resources. "
                  "Such variables must be typed as OpTypeStruct, or an array "
                  "of this type";
      }
    }

    // Check for invalid use of Invariant
    if (storage_class != spv::StorageClass::Input &&
        storage_class != spv::StorageClass::Output) {
      if (_.HasDecoration(inst->id(), spv::Decoration::Invariant)) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(4677)
               << "Variable decorated with Invariant must only be identified "
                  "with the Input or Output storage class in Vulkan "
                  "environment.";
      }
      // Need to check if only the members in a struct are decorated
      if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) {
        if (_.HasDecoration(value_id, spv::Decoration::Invariant)) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << _.VkErrorID(4677)
                 << "Variable struct member decorated with Invariant must only "
                    "be identified with the Input or Output storage class in "
                    "Vulkan environment.";
        }
      }
    }
  }

  // Vulkan Appendix A: Check that if contains initializer, then
  // storage class is Output, Private, or Function.
  if (inst->operands().size() > initializer_index &&
      storage_class != spv::StorageClass::Output &&
      storage_class != spv::StorageClass::Private &&
      storage_class != spv::StorageClass::Function) {
    if (spvIsVulkanEnv(_.context()->target_env)) {
      if (storage_class == spv::StorageClass::Workgroup) {
        auto init_id = inst->GetOperandAs<uint32_t>(initializer_index);
        auto init = _.FindDef(init_id);
        if (init->opcode() != spv::Op::OpConstantNull) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << _.VkErrorID(4734) << "OpVariable, <id> "
                 << _.getIdName(inst->id())
                 << ", initializers are limited to OpConstantNull in "
                    "Workgroup "
                    "storage class";
        }
      } else if (storage_class != spv::StorageClass::Output &&
                 storage_class != spv::StorageClass::Private &&
                 storage_class != spv::StorageClass::Function) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(4651) << "OpVariable, <id> "
               << _.getIdName(inst->id())
               << ", has a disallowed initializer & storage class "
               << "combination.\n"
               << "From " << spvLogStringForEnv(_.context()->target_env)
               << " spec:\n"
               << "Variable declarations that include initializers must have "
               << "one of the following storage classes: Output, Private, "
               << "Function or Workgroup";
      }
    }
  }

  if (initializer_index < inst->operands().size()) {
    if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpVariable, <id> " << _.getIdName(inst->id())
             << ", initializer are not allowed for TaskPayloadWorkgroupEXT";
    }
    if (storage_class == spv::StorageClass::Input) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "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) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "PhysicalStorageBuffer must not be used with OpVariable.";
  }

  // Vulkan specific validation rules for OpTypeRuntimeArray
  if (spvIsVulkanEnv(_.context()->target_env)) {
    // OpTypeRuntimeArray should only ever be in a container like OpTypeStruct,
    // so should never appear as a bare variable.
    // Unless the module has the RuntimeDescriptorArrayEXT capability.
    if (value_type && value_type->opcode() == spv::Op::OpTypeRuntimeArray) {
      if (!_.HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << _.VkErrorID(4680) << "OpVariable, <id> "
               << _.getIdName(inst->id())
               << ", is attempting to create memory for an illegal type, "
               << "OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray can only "
               << "appear as the final member of an OpTypeStruct, thus cannot "
               << "be instantiated via OpVariable";
      } else {
        // A bare variable OpTypeRuntimeArray is allowed in this context, but
        // still need to check the storage class.
        if (storage_class != spv::StorageClass::StorageBuffer &&
            storage_class != spv::StorageClass::Uniform &&
            storage_class != spv::StorageClass::UniformConstant) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << _.VkErrorID(4680)
                 << "For Vulkan with RuntimeDescriptorArrayEXT, a variable "
                 << "containing OpTypeRuntimeArray must have storage class of "
                 << "StorageBuffer, Uniform, or UniformConstant.";
        }
      }
    }

    // If an OpStruct has an OpTypeRuntimeArray somewhere within it, then it
    // must either have the storage class StorageBuffer and be decorated
    // with Block, or it must be in the Uniform storage class and be decorated
    // as BufferBlock.
    if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) {
      if (DoesStructContainRTA(_, value_type)) {
        if (storage_class == spv::StorageClass::StorageBuffer ||
            storage_class == spv::StorageClass::PhysicalStorageBuffer) {
          if (!_.HasDecoration(value_id, spv::Decoration::Block)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << _.VkErrorID(4680)
                   << "For Vulkan, an OpTypeStruct variable containing an "
                   << "OpTypeRuntimeArray must be decorated with Block if it "
                   << "has storage class StorageBuffer or "
                      "PhysicalStorageBuffer.";
          }
        } else if (storage_class == spv::StorageClass::Uniform) {
          if (!_.HasDecoration(value_id, spv::Decoration::BufferBlock)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << _.VkErrorID(4680)
                   << "For Vulkan, an OpTypeStruct variable containing an "
                   << "OpTypeRuntimeArray must be decorated with BufferBlock "
                   << "if it has storage class Uniform.";
          }
        } else {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << _.VkErrorID(4680)
                 << "For Vulkan, OpTypeStruct variables containing "
                 << "OpTypeRuntimeArray must have storage class of "
                 << "StorageBuffer, PhysicalStorageBuffer, or Uniform.";
        }
      }
    }
  }

  // Cooperative matrix types can only be allocated in Function or Private
  if ((storage_class != spv::StorageClass::Function &&
       storage_class != spv::StorageClass::Private) &&
      pointee &&
      _.ContainsType(pointee->id(), [](const Instruction* type_inst) {
        auto opcode = type_inst->opcode();
        return opcode == spv::Op::OpTypeCooperativeMatrixNV ||
               opcode == spv::Op::OpTypeCooperativeMatrixKHR;
      })) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Cooperative matrix types (or types containing them) can only be "
              "allocated "
           << "in Function or Private storage classes or as function "
              "parameters";
  }

  if ((storage_class != spv::StorageClass::Function &&
       storage_class != spv::StorageClass::Private) &&
      pointee &&
      _.ContainsType(pointee->id(), [](const Instruction* type_inst) {
        auto opcode = type_inst->opcode();
        return opcode == spv::Op::OpTypeCooperativeVectorNV;
      })) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Cooperative vector types (or types containing them) can only be "
              "allocated "
           << "in Function or Private storage classes or as function "
              "parameters";
  }

  if (_.HasCapability(spv::Capability::Shader)) {
    // Don't allow variables containing 16-bit elements without the appropriate
    // capabilities.
    if ((!_.HasCapability(spv::Capability::Int16) &&
         _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 16)) ||
        (!_.HasCapability(spv::Capability::Float16) &&
         _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeFloat, 16))) {
      auto underlying_type = value_type;
      while (underlying_type &&
             underlying_type->opcode() == spv::Op::OpTypePointer) {
        storage_class = underlying_type->GetOperandAs<spv::StorageClass>(1u);
        underlying_type =
            _.FindDef(underlying_type->GetOperandAs<uint32_t>(2u));
      }
      bool storage_class_ok = true;
      std::string sc_name = _.grammar().lookupOperandName(
          SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class));
      switch (storage_class) {
        case spv::StorageClass::StorageBuffer:
        case spv::StorageClass::PhysicalStorageBuffer:
          if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess)) {
            storage_class_ok = false;
          }
          break;
        case spv::StorageClass::Uniform:
          if (underlying_type &&
              !_.HasCapability(
                  spv::Capability::UniformAndStorageBuffer16BitAccess)) {
            if (underlying_type->opcode() == spv::Op::OpTypeArray ||
                underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) {
              underlying_type =
                  _.FindDef(underlying_type->GetOperandAs<uint32_t>(1u));
            }
            if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess) ||
                !_.HasDecoration(underlying_type->id(),
                                 spv::Decoration::BufferBlock)) {
              storage_class_ok = false;
            }
          }
          break;
        case spv::StorageClass::PushConstant:
          if (!_.HasCapability(spv::Capability::StoragePushConstant16)) {
            storage_class_ok = false;
          }
          break;
        case spv::StorageClass::Input:
        case spv::StorageClass::Output:
          if (!_.HasCapability(spv::Capability::StorageInputOutput16)) {
            storage_class_ok = false;
          }
          break;
        case spv::StorageClass::Workgroup:
          if (!_.HasCapability(
                  spv::Capability::
                      WorkgroupMemoryExplicitLayout16BitAccessKHR)) {
            storage_class_ok = false;
          }
          break;
        default:
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "Cannot allocate a variable containing a 16-bit type in "
                 << sc_name << " storage class";
      }
      if (!storage_class_ok) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Allocating a variable containing a 16-bit element in "
               << sc_name << " storage class requires an additional capability";
      }
    }
    // Don't allow variables containing 8-bit elements without the appropriate
    // capabilities.
    if (!_.HasCapability(spv::Capability::Int8) &&
        _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 8)) {
      auto underlying_type = value_type;
      while (underlying_type &&
             underlying_type->opcode() == spv::Op::OpTypePointer) {
        storage_class = underlying_type->GetOperandAs<spv::StorageClass>(1u);
        underlying_type =
            _.FindDef(underlying_type->GetOperandAs<uint32_t>(2u));
      }
      bool storage_class_ok = true;
      std::string sc_name = _.grammar().lookupOperandName(
          SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class));
      switch (storage_class) {
        case spv::StorageClass::StorageBuffer:
        case spv::StorageClass::PhysicalStorageBuffer:
          if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess)) {
            storage_class_ok = false;
          }
          break;
        case spv::StorageClass::Uniform:
          if (underlying_type &&
              !_.HasCapability(
                  spv::Capability::UniformAndStorageBuffer8BitAccess)) {
            if (underlying_type->opcode() == spv::Op::OpTypeArray ||
                underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) {
              underlying_type =
                  _.FindDef(underlying_type->GetOperandAs<uint32_t>(1u));
            }
            if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess) ||
                !_.HasDecoration(underlying_type->id(),
                                 spv::Decoration::BufferBlock)) {
              storage_class_ok = false;
            }
          }
          break;
        case spv::StorageClass::PushConstant:
          if (!_.HasCapability(spv::Capability::StoragePushConstant8)) {
            storage_class_ok = false;
          }
          break;
        case spv::StorageClass::Workgroup:
          if (!_.HasCapability(
                  spv::Capability::
                      WorkgroupMemoryExplicitLayout8BitAccessKHR)) {
            storage_class_ok = false;
          }
          break;
        default:
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "Cannot allocate a variable containing a 8-bit type in "
                 << sc_name << " storage class";
      }
      if (!storage_class_ok) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Allocating a variable containing a 8-bit element in "
               << sc_name << " storage class requires an additional capability";
      }
    }
  }

  if (_.HasCapability(spv::Capability::TileShadingQCOM) &&
      storage_class == spv::StorageClass::TileAttachmentQCOM) {
    if (result_type->opcode() == spv::Op::OpTypePointer) {
      const auto pointee_type =
          _.FindDef(result_type->GetOperandAs<uint32_t>(2));
      if (pointee_type && pointee_type->opcode() == spv::Op::OpTypeImage) {
        spv::Dim dim = static_cast<spv::Dim>(pointee_type->word(3));
        if (dim != spv::Dim::Dim2D) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Any OpTypeImage variable in the TileAttachmentQCOM "
                    "Storage Class must "
                    "have 2D as its dimension";
        }
        unsigned sampled = pointee_type->word(7);
        if (sampled != 1 && sampled != 2) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Any OpyTpeImage variable in the TileAttachmentQCOM "
                    "Storage Class must "
                    "have 1 or 2 as Image 'Sampled' parameter";
        }
        for (const auto& pair_o : inst->uses()) {
          const auto* use_inst_o = pair_o.first;
          if (use_inst_o->opcode() == spv::Op::OpLoad) {
            for (const auto& pair_i : use_inst_o->uses()) {
              const auto* use_inst_i = pair_i.first;
              switch (use_inst_i->opcode()) {
                case spv::Op::OpImageQueryFormat:
                case spv::Op::OpImageQueryOrder:
                case spv::Op::OpImageQuerySizeLod:
                case spv::Op::OpImageQuerySize:
                case spv::Op::OpImageQueryLod:
                case spv::Op::OpImageQueryLevels:
                case spv::Op::OpImageQuerySamples:
                  return _.diag(SPV_ERROR_INVALID_DATA, inst)
                         << "Any variable in the TileAttachmentQCOM Storage "
                            "Class must "
                            "not be consumed by an OpImageQuery* instruction";
                default:
                  break;
              }
            }
          }
        }
      }
    }

    if (!(_.HasDecoration(inst->id(), spv::Decoration::DescriptorSet) &&
          _.HasDecoration(inst->id(), spv::Decoration::Binding))) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Any variable in the TileAttachmentQCOM Storage Class must "
                "be decorated with DescriptorSet and Binding";
    }
    if (_.HasDecoration(inst->id(), spv::Decoration::Component)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Any variable in the TileAttachmentQCOM Storage Class must "
                "not be decorated with Component decoration";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
  const auto result_type = _.FindDef(inst->type_id());
  if (!result_type) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpLoad Result Type <id> " << _.getIdName(inst->type_id())
           << " is not defined.";
  }

  const auto pointer_index = 2;
  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  const auto pointer = _.FindDef(pointer_id);
  if (!pointer ||
      ((_.addressing_model() == spv::AddressingModel::Logical) &&
       ((!_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
        (_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpLoad Pointer <id> " << _.getIdName(pointer_id)
           << " is not a logical pointer.";
  }

  const auto pointer_type = _.FindDef(pointer->type_id());
  if (!pointer_type ||
      (pointer_type->opcode() != spv::Op::OpTypePointer &&
       pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpLoad type for pointer <id> " << _.getIdName(pointer_id)
           << " is not a pointer type.";
  }

  if (pointer_type->opcode() == spv::Op::OpTypePointer) {
    const auto pointee_type =
        _.FindDef(pointer_type->GetOperandAs<uint32_t>(2));
    if (!pointee_type || result_type->id() != pointee_type->id()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpLoad Result Type <id> " << _.getIdName(inst->type_id())
             << " does not match Pointer <id> " << _.getIdName(pointer->id())
             << "s type.";
    }
  }

  if (!_.options()->before_hlsl_legalization &&
      _.ContainsRuntimeArray(inst->type_id())) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Cannot load a runtime-sized array";
  }

  if (auto error = CheckMemoryAccess(_, inst, 3)) return error;

  if (_.HasCapability(spv::Capability::Shader) &&
      _.ContainsLimitedUseIntOrFloatType(inst->type_id()) &&
      result_type->opcode() != spv::Op::OpTypePointer) {
    if (result_type->opcode() != spv::Op::OpTypeInt &&
        result_type->opcode() != spv::Op::OpTypeFloat &&
        result_type->opcode() != spv::Op::OpTypeVector &&
        result_type->opcode() != spv::Op::OpTypeMatrix) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "8- or 16-bit loads must be a scalar, vector or matrix type";
    }
  }

  _.RegisterQCOMImageProcessingTextureConsumer(pointer_id, inst, nullptr);

  return SPV_SUCCESS;
}

spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
  const auto pointer_index = 0;
  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  const auto pointer = _.FindDef(pointer_id);
  if (!pointer ||
      (_.addressing_model() == spv::AddressingModel::Logical &&
       ((!_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
        (_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpStore Pointer <id> " << _.getIdName(pointer_id)
           << " is not a logical pointer.";
  }
  const auto pointer_type = _.FindDef(pointer->type_id());
  if (!pointer_type ||
      (pointer_type->opcode() != spv::Op::OpTypePointer &&
       pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpStore type for pointer <id> " << _.getIdName(pointer_id)
           << " is not a pointer type.";
  }

  Instruction* type = nullptr;
  if (pointer_type->opcode() == spv::Op::OpTypePointer) {
    const auto type_id = pointer_type->GetOperandAs<uint32_t>(2);
    type = _.FindDef(type_id);
    if (!type || spv::Op::OpTypeVoid == type->opcode()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
             << "s type is void.";
    }
  }

  // validate storage class
  {
    uint32_t data_type;
    spv::StorageClass storage_class;
    if (!_.GetPointerTypeInfo(pointer_type->id(), &data_type, &storage_class)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
             << " is not pointer type";
    }

    if (storage_class == spv::StorageClass::UniformConstant ||
        storage_class == spv::StorageClass::Input ||
        storage_class == spv::StorageClass::PushConstant) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
             << " storage class is read-only";
    } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "ShaderRecordBufferKHR Storage Class variables are read only";
    } else if (storage_class == spv::StorageClass::HitAttributeKHR) {
      std::string errorVUID = _.VkErrorID(4703);
      _.function(inst->function()->id())
          ->RegisterExecutionModelLimitation(
              [errorVUID](spv::ExecutionModel model, std::string* message) {
                if (model == spv::ExecutionModel::AnyHitKHR ||
                    model == spv::ExecutionModel::ClosestHitKHR) {
                  if (message) {
                    *message =
                        errorVUID +
                        "HitAttributeKHR Storage Class variables are read only "
                        "with AnyHitKHR and ClosestHitKHR";
                  }
                  return false;
                }
                return true;
              });
    }

    if (spvIsVulkanEnv(_.context()->target_env) &&
        storage_class == spv::StorageClass::Uniform) {
      auto base_ptr = _.TracePointer(pointer);
      if (base_ptr->opcode() == spv::Op::OpVariable) {
        // If it's not a variable a different check should catch the problem.
        auto base_type = _.FindDef(base_ptr->GetOperandAs<uint32_t>(0));
        // Get the pointed-to type.
        base_type = _.FindDef(base_type->GetOperandAs<uint32_t>(2u));
        if (base_type->opcode() == spv::Op::OpTypeArray ||
            base_type->opcode() == spv::Op::OpTypeRuntimeArray) {
          base_type = _.FindDef(base_type->GetOperandAs<uint32_t>(1u));
        }
        if (_.HasDecoration(base_type->id(), spv::Decoration::Block)) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << _.VkErrorID(6925)
                 << "In the Vulkan environment, cannot store to Uniform Blocks";
        }
      }
    }
  }

  const auto object_index = 1;
  const auto object_id = inst->GetOperandAs<uint32_t>(object_index);
  const auto object = _.FindDef(object_id);
  if (!object || !object->type_id()) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpStore Object <id> " << _.getIdName(object_id)
           << " is not an object.";
  }
  const auto object_type = _.FindDef(object->type_id());
  if (!object_type || spv::Op::OpTypeVoid == object_type->opcode()) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpStore Object <id> " << _.getIdName(object_id)
           << "s type is void.";
  }

  if (type && (type->id() != object_type->id())) {
    if (!_.options()->relax_struct_store ||
        type->opcode() != spv::Op::OpTypeStruct ||
        object_type->opcode() != spv::Op::OpTypeStruct) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
             << "s type does not match Object <id> "
             << _.getIdName(object->id()) << "s type.";
    }

    // TODO: Check for layout compatible matricies and arrays as well.
    if (!AreLayoutCompatibleStructs(_, type, object_type)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
             << "s layout does not match Object <id> "
             << _.getIdName(object->id()) << "s layout.";
    }
  }

  if (auto error = CheckMemoryAccess(_, inst, 2)) return error;

  if (_.HasCapability(spv::Capability::Shader) &&
      _.ContainsLimitedUseIntOrFloatType(inst->type_id()) &&
      object_type->opcode() != spv::Op::OpTypePointer) {
    if (object_type->opcode() != spv::Op::OpTypeInt &&
        object_type->opcode() != spv::Op::OpTypeFloat &&
        object_type->opcode() != spv::Op::OpTypeVector &&
        object_type->opcode() != spv::Op::OpTypeMatrix) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "8- or 16-bit stores must be a scalar, vector or matrix type";
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env) &&
      !_.options()->before_hlsl_legalization) {
    const auto isForbiddenType = [](const Instruction* type_inst) {
      auto opcode = type_inst->opcode();
      return opcode == spv::Op::OpTypeImage ||
             opcode == spv::Op::OpTypeSampler ||
             opcode == spv::Op::OpTypeSampledImage ||
             opcode == spv::Op::OpTypeAccelerationStructureKHR;
    };
    if (_.ContainsType(object_type->id(), isForbiddenType)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << _.VkErrorID(6924)
             << "Cannot store to OpTypeImage, OpTypeSampler, "
                "OpTypeSampledImage, or OpTypeAccelerationStructureKHR objects";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateCopyMemoryMemoryAccess(ValidationState_t& _,
                                            const Instruction* inst) {
  assert(inst->opcode() == spv::Op::OpCopyMemory ||
         inst->opcode() == spv::Op::OpCopyMemorySized);
  const uint32_t first_access_index =
      inst->opcode() == spv::Op::OpCopyMemory ? 2 : 3;
  if (inst->operands().size() > first_access_index) {
    if (auto error = CheckMemoryAccess(_, inst, first_access_index))
      return error;

    const auto first_access = inst->GetOperandAs<uint32_t>(first_access_index);
    const uint32_t second_access_index =
        first_access_index + MemoryAccessNumWords(first_access);
    if (inst->operands().size() > second_access_index) {
      if (_.features().copy_memory_permits_two_memory_accesses) {
        if (auto error = CheckMemoryAccess(_, inst, second_access_index))
          return error;

        // In the two-access form in SPIR-V 1.4 and later:
        //  - the first is the target (write) access and it can't have
        //  make-visible.
        //  - the second is the source (read) access and it can't have
        //  make-available.
        if (first_access &
            uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Target memory access must not include "
                    "MakePointerVisibleKHR";
        }
        const auto second_access =
            inst->GetOperandAs<uint32_t>(second_access_index);
        if (second_access &
            uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Source memory access must not include "
                    "MakePointerAvailableKHR";
        }
      } else {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << spvOpcodeString(static_cast<spv::Op>(inst->opcode()))
               << " with two memory access operands requires SPIR-V 1.4 or "
                  "later";
      }
    }
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) {
  const auto target_index = 0;
  const auto target_id = inst->GetOperandAs<uint32_t>(target_index);
  const auto target = _.FindDef(target_id);
  if (!target) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Target operand <id> " << _.getIdName(target_id)
           << " is not defined.";
  }

  const auto source_index = 1;
  const auto source_id = inst->GetOperandAs<uint32_t>(source_index);
  const auto source = _.FindDef(source_id);
  if (!source) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Source operand <id> " << _.getIdName(source_id)
           << " is not defined.";
  }

  const auto target_pointer_type = _.FindDef(target->type_id());
  if (!target_pointer_type ||
      (target_pointer_type->opcode() != spv::Op::OpTypePointer &&
       target_pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Target operand <id> " << _.getIdName(target_id)
           << " is not a pointer.";
  }

  const auto source_pointer_type = _.FindDef(source->type_id());
  if (!source_pointer_type ||
      (source_pointer_type->opcode() != spv::Op::OpTypePointer &&
       source_pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Source operand <id> " << _.getIdName(source_id)
           << " is not a pointer.";
  }

  if (inst->opcode() == spv::Op::OpCopyMemory) {
    const bool target_typed =
        target_pointer_type->opcode() == spv::Op::OpTypePointer;
    const bool source_typed =
        source_pointer_type->opcode() == spv::Op::OpTypePointer;
    Instruction* target_type = nullptr;
    Instruction* source_type = nullptr;
    if (target_typed) {
      target_type = _.FindDef(target_pointer_type->GetOperandAs<uint32_t>(2));

      if (!target_type || target_type->opcode() == spv::Op::OpTypeVoid) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Target operand <id> " << _.getIdName(target_id)
               << " cannot be a void pointer.";
      }
    }

    if (source_typed) {
      source_type = _.FindDef(source_pointer_type->GetOperandAs<uint32_t>(2));
      if (!source_type || source_type->opcode() == spv::Op::OpTypeVoid) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Source operand <id> " << _.getIdName(source_id)
               << " cannot be a void pointer.";
      }
    }

    if (target_type && source_type && target_type->id() != source_type->id()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Target <id> " << _.getIdName(source_id)
             << "s type does not match Source <id> "
             << _.getIdName(source_type->id()) << "s type.";
    }

    if (!target_type && !source_type) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "One of Source or Target must be a typed pointer";
    }

    if (auto error = CheckMemoryAccess(_, inst, 2)) return error;
  } else {
    const auto size_id = inst->GetOperandAs<uint32_t>(2);
    const auto size = _.FindDef(size_id);
    if (!size) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Size operand <id> " << _.getIdName(size_id)
             << " is not defined.";
    }

    const auto size_type = _.FindDef(size->type_id());
    if (!_.IsIntScalarType(size_type->id())) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Size operand <id> " << _.getIdName(size_id)
             << " must be a scalar integer type.";
    }
    bool is_zero = true;
    switch (size->opcode()) {
      case spv::Op::OpConstantNull:
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Size operand <id> " << _.getIdName(size_id)
               << " cannot be a constant zero.";
      case spv::Op::OpConstant:
        if (size_type->word(3) == 1 &&
            size->word(size->words().size() - 1) & 0x80000000) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "Size operand <id> " << _.getIdName(size_id)
                 << " cannot have the sign bit set to 1.";
        }
        for (size_t i = 3; is_zero && i < size->words().size(); ++i) {
          is_zero &= (size->word(i) == 0);
        }
        if (is_zero) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "Size operand <id> " << _.getIdName(size_id)
                 << " cannot be a constant zero.";
        }
        break;
      default:
        // Cannot infer any other opcodes.
        break;
    }

    if (_.HasCapability(spv::Capability::Shader)) {
      bool is_int = false;
      bool is_const = false;
      uint32_t value = 0;
      std::tie(is_int, is_const, value) = _.EvalInt32IfConst(size_id);
      if (is_const) {
        if (value % 4 != 0) {
          const auto source_sc =
              source_pointer_type->GetOperandAs<spv::StorageClass>(1);
          const auto target_sc =
              target_pointer_type->GetOperandAs<spv::StorageClass>(1);
          const bool int8 = _.HasCapability(spv::Capability::Int8);
          const bool ubo_int8 = _.HasCapability(
              spv::Capability::UniformAndStorageBuffer8BitAccess);
          const bool ssbo_int8 =
              _.HasCapability(spv::Capability::StorageBuffer8BitAccess) ||
              ubo_int8;
          const bool pc_int8 =
              _.HasCapability(spv::Capability::StoragePushConstant8);
          const bool wg_int8 = _.HasCapability(
              spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR);
          const bool int16 = _.HasCapability(spv::Capability::Int16) || int8;
          const bool ubo_int16 =
              _.HasCapability(
                  spv::Capability::UniformAndStorageBuffer16BitAccess) ||
              ubo_int8;
          const bool ssbo_int16 =
              _.HasCapability(spv::Capability::StorageBuffer16BitAccess) ||
              ubo_int16 || ssbo_int8;
          const bool pc_int16 =
              _.HasCapability(spv::Capability::StoragePushConstant16) ||
              pc_int8;
          const bool io_int16 =
              _.HasCapability(spv::Capability::StorageInputOutput16);
          const bool wg_int16 = _.HasCapability(
              spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR);

          bool source_int16_match = false;
          bool target_int16_match = false;
          bool source_int8_match = false;
          bool target_int8_match = false;
          switch (source_sc) {
            case spv::StorageClass::StorageBuffer:
              source_int16_match = ssbo_int16;
              source_int8_match = ssbo_int8;
              break;
            case spv::StorageClass::Uniform:
              source_int16_match = ubo_int16;
              source_int8_match = ubo_int8;
              break;
            case spv::StorageClass::PushConstant:
              source_int16_match = pc_int16;
              source_int8_match = pc_int8;
              break;
            case spv::StorageClass::Input:
            case spv::StorageClass::Output:
              source_int16_match = io_int16;
              break;
            case spv::StorageClass::Workgroup:
              source_int16_match = wg_int16;
              source_int8_match = wg_int8;
              break;
            default:
              break;
          }
          switch (target_sc) {
            case spv::StorageClass::StorageBuffer:
              target_int16_match = ssbo_int16;
              target_int8_match = ssbo_int8;
              break;
            case spv::StorageClass::Uniform:
              target_int16_match = ubo_int16;
              target_int8_match = ubo_int8;
              break;
            case spv::StorageClass::PushConstant:
              target_int16_match = pc_int16;
              target_int8_match = pc_int8;
              break;
            // Input is read-only so it cannot be the target pointer.
            case spv::StorageClass::Output:
              target_int16_match = io_int16;
              break;
            case spv::StorageClass::Workgroup:
              target_int16_match = wg_int16;
              target_int8_match = wg_int8;
              break;
            default:
              break;
          }
          if (!int8 && !int16 && !(source_int16_match && target_int16_match)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Size must be a multiple of 4";
          }
          if (value % 2 != 0) {
            if (!int8 && !(source_int8_match && target_int8_match)) {
              return _.diag(SPV_ERROR_INVALID_ID, inst)
                     << "Size must be a multiple of 2";
            }
          }
        }
      }
    }

    if (auto error = CheckMemoryAccess(_, inst, 3)) return error;
  }
  if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error;

  // Get past the pointers to avoid checking a pointer copy.
  if (target_pointer_type->opcode() == spv::Op::OpTypePointer) {
    auto sub_type = _.FindDef(target_pointer_type->GetOperandAs<uint32_t>(2));
    while (sub_type->opcode() == spv::Op::OpTypePointer) {
      sub_type = _.FindDef(sub_type->GetOperandAs<uint32_t>(2));
    }
    if (_.HasCapability(spv::Capability::Shader) &&
        _.ContainsLimitedUseIntOrFloatType(sub_type->id())) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Cannot copy memory of objects containing 8- or 16-bit types";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateAccessChain(ValidationState_t& _,
                                 const Instruction* inst) {
  std::string instr_name =
      "Op" + std::string(spvOpcodeString(static_cast<spv::Op>(inst->opcode())));

  const bool untyped_pointer = spvOpcodeGeneratesUntypedPointer(inst->opcode());

  // The result type must be OpTypePointer for regular access chains and an
  // OpTypeUntypedPointerKHR for untyped access chains.
  auto result_type = _.FindDef(inst->type_id());
  if (untyped_pointer) {
    if (!result_type ||
        spv::Op::OpTypeUntypedPointerKHR != result_type->opcode()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "The Result Type of " << instr_name << " <id> "
             << _.getIdName(inst->id())
             << " must be OpTypeUntypedPointerKHR. Found Op"
             << spvOpcodeString(static_cast<spv::Op>(result_type->opcode()))
             << ".";
    }
  } else {
    if (!result_type || spv::Op::OpTypePointer != result_type->opcode()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "The Result Type of " << instr_name << " <id> "
             << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op"
             << spvOpcodeString(static_cast<spv::Op>(result_type->opcode()))
             << ".";
    }
  }

  if (untyped_pointer) {
    // Base type must be a non-pointer type.
    const auto base_type = _.FindDef(inst->GetOperandAs<uint32_t>(2));
    if (!base_type || !spvOpcodeGeneratesType(base_type->opcode()) ||
        base_type->opcode() == spv::Op::OpTypePointer ||
        base_type->opcode() == spv::Op::OpTypeUntypedPointerKHR) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Base type must be a non-pointer type";
    }

    const auto ContainsBlock = [&_](const Instruction* type_inst) {
      if (type_inst->opcode() == spv::Op::OpTypeStruct) {
        if (_.HasDecoration(type_inst->id(), spv::Decoration::Block) ||
            _.HasDecoration(type_inst->id(), spv::Decoration::BufferBlock)) {
          return true;
        }
      }
      return false;
    };

    // Block (and BufferBlock) arrays cannot be reinterpreted via untyped access
    // chains.
    const bool base_type_block_array =
        base_type->opcode() == spv::Op::OpTypeArray &&
        _.ContainsType(base_type->id(), ContainsBlock,
                       /* traverse_all_types = */ false);

    const auto base_index = untyped_pointer ? 3 : 2;
    const auto base_id = inst->GetOperandAs<uint32_t>(base_index);
    auto base = _.FindDef(base_id);
    // Strictly speaking this misses trivial access chains and function
    // parameter chasing, but that would be a significant complication in the
    // traversal.
    while (base->opcode() == spv::Op::OpCopyObject) {
      base = _.FindDef(base->GetOperandAs<uint32_t>(2));
    }
    const Instruction* base_data_type = nullptr;
    if (base->opcode() == spv::Op::OpVariable) {
      const auto ptr_type = _.FindDef(base->type_id());
      base_data_type = _.FindDef(ptr_type->GetOperandAs<uint32_t>(2));
    } else if (base->opcode() == spv::Op::OpUntypedVariableKHR) {
      if (base->operands().size() > 3) {
        base_data_type = _.FindDef(base->GetOperandAs<uint32_t>(3));
      }
    }

    if (base_data_type) {
      const bool base_block_array =
          base_data_type->opcode() == spv::Op::OpTypeArray &&
          _.ContainsType(base_data_type->id(), ContainsBlock,
                         /* traverse_all_types = */ false);

      if (base_type_block_array != base_block_array) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Both Base Type and Base must be Block or BufferBlock arrays "
                  "or neither can be";
      } else if (base_type_block_array && base_block_array &&
                 base_type->id() != base_data_type->id()) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "If Base or Base Type is a Block or BufferBlock array, the "
                  "other must also be the same array";
      }
    }
  }

  // Base must be a pointer, pointing to the base of a composite object.
  const auto base_index = untyped_pointer ? 3 : 2;
  const auto base_id = inst->GetOperandAs<uint32_t>(base_index);
  const auto base = _.FindDef(base_id);
  const auto base_type = _.FindDef(base->type_id());
  if (!base_type || !(spv::Op::OpTypePointer == base_type->opcode() ||
                      (untyped_pointer && spv::Op::OpTypeUntypedPointerKHR ==
                                              base_type->opcode()))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Base <id> " << _.getIdName(base_id) << " in " << instr_name
           << " instruction must be a pointer.";
  }

  // The result pointer storage class and base pointer storage class must match.
  // Word 2 of OpTypePointer is the Storage Class.
  auto result_type_storage_class = result_type->word(2);
  auto base_type_storage_class = base_type->word(2);
  if (result_type_storage_class != base_type_storage_class) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "The result pointer storage class and base "
              "pointer storage class in "
           << instr_name << " do not match.";
  }

  // The type pointed to by OpTypePointer (word 3) must be a composite type.
  auto type_pointee = untyped_pointer
                          ? _.FindDef(inst->GetOperandAs<uint32_t>(2))
                          : _.FindDef(base_type->word(3));

  // Check Universal Limit (SPIR-V Spec. Section 2.17).
  // The number of indexes passed to OpAccessChain may not exceed 255
  // The instruction includes 4 words + N words (for N indexes)
  size_t num_indexes = inst->words().size() - 4;
  if (inst->opcode() == spv::Op::OpPtrAccessChain ||
      inst->opcode() == spv::Op::OpInBoundsPtrAccessChain ||
      inst->opcode() == spv::Op::OpUntypedPtrAccessChainKHR ||
      inst->opcode() == spv::Op::OpUntypedInBoundsPtrAccessChainKHR) {
    // In pointer access chains, the element operand is required, but not
    // counted as an index.
    --num_indexes;
  }
  const size_t num_indexes_limit =
      _.options()->universal_limits_.max_access_chain_indexes;
  if (num_indexes > num_indexes_limit) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "The number of indexes in " << instr_name << " may not exceed "
           << num_indexes_limit << ". Found " << num_indexes << " indexes.";
  }
  // Indexes walk the type hierarchy to the desired depth, potentially down to
  // scalar granularity. The first index in Indexes will select the top-level
  // member/element/component/element of the base composite. All composite
  // constituents use zero-based numbering, as described by their OpType...
  // instruction. The second index will apply similarly to that result, and so
  // on. Once any non-composite type is reached, there must be no remaining
  // (unused) indexes.
  auto starting_index = untyped_pointer ? 5 : 4;
  if (inst->opcode() == spv::Op::OpPtrAccessChain ||
      inst->opcode() == spv::Op::OpInBoundsPtrAccessChain ||
      inst->opcode() == spv::Op::OpUntypedPtrAccessChainKHR ||
      inst->opcode() == spv::Op::OpUntypedInBoundsPtrAccessChainKHR) {
    ++starting_index;
  }
  for (size_t i = starting_index; i < inst->words().size(); ++i) {
    const uint32_t cur_word = inst->words()[i];
    // Earlier ID checks ensure that cur_word definition exists.
    auto cur_word_instr = _.FindDef(cur_word);
    // The index must be a scalar integer type (See OpAccessChain in the Spec.)
    auto index_type = _.FindDef(cur_word_instr->type_id());
    if (!index_type || spv::Op::OpTypeInt != index_type->opcode()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Indexes passed to " << instr_name
             << " must be of type integer.";
    }
    switch (type_pointee->opcode()) {
      case spv::Op::OpTypeMatrix:
      case spv::Op::OpTypeVector:
      case spv::Op::OpTypeCooperativeVectorNV:
      case spv::Op::OpTypeCooperativeMatrixNV:
      case spv::Op::OpTypeCooperativeMatrixKHR:
      case spv::Op::OpTypeArray:
      case spv::Op::OpTypeRuntimeArray:
      case spv::Op::OpTypeNodePayloadArrayAMDX: {
        // In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV,
        // OpTypeCooperativeVectorNV, OpTypeArray, and OpTypeRuntimeArray, word
        // 2 is the Element Type.
        type_pointee = _.FindDef(type_pointee->word(2));
        break;
      }
      case spv::Op::OpTypeStruct: {
        // In case of structures, there is an additional constraint on the
        // index: the index must be an OpConstant.
        int64_t cur_index;
        if (!_.EvalConstantValInt64(cur_word, &cur_index)) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "The <id> passed to " << instr_name << " to index "
                 << _.getIdName(cur_word)
                 << " into a "
                    "structure must be an OpConstant.";
        }

        // The index points to the struct member we want, therefore, the index
        // should be less than the number of struct members.
        const int64_t num_struct_members =
            static_cast<int64_t>(type_pointee->words().size() - 2);
        if (cur_index >= num_struct_members || cur_index < 0) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "Index " << _.getIdName(cur_word)
                 << " is out of bounds: " << instr_name << " cannot find index "
                 << cur_index << " into the structure <id> "
                 << _.getIdName(type_pointee->id()) << ". This structure has "
                 << num_struct_members << " members. Largest valid index is "
                 << num_struct_members - 1 << ".";
        }
        // Struct members IDs start at word 2 of OpTypeStruct.
        const size_t word_index = static_cast<size_t>(cur_index) + 2;
        auto structMemberId = type_pointee->word(word_index);
        type_pointee = _.FindDef(structMemberId);
        break;
      }
      default: {
        // Give an error. reached non-composite type while indexes still remain.
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << instr_name
               << " reached non-composite type while indexes "
                  "still remain to be traversed.";
      }
    }
  }

  if (!untyped_pointer) {
    // Result type is a pointer. Find out what it's pointing to.
    // This will be used to make sure the indexing results in the same type.
    // OpTypePointer word 3 is the type being pointed to.
    const auto result_type_pointee = _.FindDef(result_type->word(3));
    // At this point, we have fully walked down from the base using the indeces.
    // The type being pointed to should be the same as the result type.
    if (type_pointee->id() != result_type_pointee->id()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << instr_name << " result type (Op"
             << spvOpcodeString(
                    static_cast<spv::Op>(result_type_pointee->opcode()))
             << ") does not match the type that results from indexing into the "
                "base "
                "<id> (Op"
             << spvOpcodeString(static_cast<spv::Op>(type_pointee->opcode()))
             << ").";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateRawAccessChain(ValidationState_t& _,
                                    const Instruction* inst) {
  std::string instr_name = "Op" + std::string(spvOpcodeString(inst->opcode()));

  // The result type must be OpTypePointer.
  const auto result_type = _.FindDef(inst->type_id());
  if (spv::Op::OpTypePointer != result_type->opcode()) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "The Result Type of " << instr_name << " <id> "
           << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op"
           << spvOpcodeString(result_type->opcode()) << '.';
  }

  // The pointed storage class must be valid.
  const auto storage_class = result_type->GetOperandAs<spv::StorageClass>(1);
  if (storage_class != spv::StorageClass::StorageBuffer &&
      storage_class != spv::StorageClass::PhysicalStorageBuffer &&
      storage_class != spv::StorageClass::Uniform) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "The Result Type of " << instr_name << " <id> "
           << _.getIdName(inst->id())
           << " must point to a storage class of "
              "StorageBuffer, PhysicalStorageBuffer, or Uniform.";
  }

  // The pointed type must not be one in the list below.
  const auto result_type_pointee =
      _.FindDef(result_type->GetOperandAs<uint32_t>(2));
  if (result_type_pointee->opcode() == spv::Op::OpTypeArray ||
      result_type_pointee->opcode() == spv::Op::OpTypeMatrix ||
      result_type_pointee->opcode() == spv::Op::OpTypeStruct) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "The Result Type of " << instr_name << " <id> "
           << _.getIdName(inst->id())
           << " must not point to "
              "OpTypeArray, OpTypeMatrix, or OpTypeStruct.";
  }

  // Validate Stride is a OpConstant.
  const auto stride = _.FindDef(inst->GetOperandAs<uint32_t>(3));
  if (stride->opcode() != spv::Op::OpConstant) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "The Stride of " << instr_name << " <id> "
           << _.getIdName(inst->id()) << " must be OpConstant. Found Op"
           << spvOpcodeString(stride->opcode()) << '.';
  }
  // Stride type must be OpTypeInt
  const auto stride_type = _.FindDef(stride->type_id());
  if (stride_type->opcode() != spv::Op::OpTypeInt) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "The type of Stride of " << instr_name << " <id> "
           << _.getIdName(inst->id()) << " must be OpTypeInt. Found Op"
           << spvOpcodeString(stride_type->opcode()) << '.';
  }

  // Index and Offset type must be OpTypeInt with a width of 32
  const auto ValidateType = [&](const char* name,
                                int operandIndex) -> spv_result_t {
    const auto value = _.FindDef(inst->GetOperandAs<uint32_t>(operandIndex));
    const auto value_type = _.FindDef(value->type_id());
    if (value_type->opcode() != spv::Op::OpTypeInt) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "The type of " << name << " of " << instr_name << " <id> "
             << _.getIdName(inst->id()) << " must be OpTypeInt. Found Op"
             << spvOpcodeString(value_type->opcode()) << '.';
    }
    const auto width = value_type->GetOperandAs<uint32_t>(1);
    if (width != 32) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "The integer width of " << name << " of " << instr_name
             << " <id> " << _.getIdName(inst->id()) << " must be 32. Found "
             << width << '.';
    }
    return SPV_SUCCESS;
  };
  spv_result_t result;
  result = ValidateType("Index", 4);
  if (result != SPV_SUCCESS) {
    return result;
  }
  result = ValidateType("Offset", 5);
  if (result != SPV_SUCCESS) {
    return result;
  }

  uint32_t access_operands = 0;
  if (inst->operands().size() >= 7) {
    access_operands = inst->GetOperandAs<uint32_t>(6);
  }
  if (access_operands &
      uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) {
    uint64_t stride_value = 0;
    if (_.EvalConstantValUint64(stride->id(), &stride_value) &&
        stride_value == 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Stride must not be zero when per-element robustness is used.";
    }
  }
  if (access_operands &
          uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerComponentNV) ||
      access_operands &
          uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) {
    if (storage_class == spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Storage class cannot be PhysicalStorageBuffer when "
                "raw access chain robustness is used.";
    }
  }
  if (access_operands &
          uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerComponentNV) &&
      access_operands &
          uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Per-component robustness and per-element robustness are "
              "mutually exclusive.";
  }

  return SPV_SUCCESS;
}

spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
                                    const Instruction* inst) {
  if (_.addressing_model() == spv::AddressingModel::Logical &&
      inst->opcode() == spv::Op::OpPtrAccessChain) {
    if (!_.features().variable_pointers) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Generating variable pointers requires capability "
             << "VariablePointers or VariablePointersStorageBuffer";
    }
  }

  // Need to call first, will make sure Base is a valid ID
  if (auto error = ValidateAccessChain(_, inst)) return error;

  const bool untyped_pointer = spvOpcodeGeneratesUntypedPointer(inst->opcode());

  const auto base_idx = untyped_pointer ? 3 : 2;
  const auto base = _.FindDef(inst->GetOperandAs<uint32_t>(base_idx));
  const auto base_type = _.FindDef(base->type_id());
  const auto base_type_storage_class =
      base_type->GetOperandAs<spv::StorageClass>(1);

  const auto element_idx = untyped_pointer ? 4 : 3;
  const auto element = _.FindDef(inst->GetOperandAs<uint32_t>(element_idx));
  const auto element_type = _.FindDef(element->type_id());
  if (!element_type || element_type->opcode() != spv::Op::OpTypeInt) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Element must be an integer";
  }
  uint64_t element_val = 0;
  if (_.EvalConstantValUint64(element->id(), &element_val)) {
    if (element_val != 0) {
      const auto interp_type =
          untyped_pointer ? _.FindDef(inst->GetOperandAs<uint32_t>(2))
                          : _.FindDef(base_type->GetOperandAs<uint32_t>(2));
      if (interp_type->opcode() == spv::Op::OpTypeStruct &&
          (_.HasDecoration(interp_type->id(), spv::Decoration::Block) ||
           _.HasDecoration(interp_type->id(), spv::Decoration::BufferBlock))) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Element must be 0 if the interpretation type is a Block- or "
                  "BufferBlock-decorated structure";
      }
    }
  }

  if (_.HasCapability(spv::Capability::Shader) &&
      (base_type_storage_class == spv::StorageClass::Uniform ||
       base_type_storage_class == spv::StorageClass::StorageBuffer ||
       base_type_storage_class == spv::StorageClass::PhysicalStorageBuffer ||
       base_type_storage_class == spv::StorageClass::PushConstant ||
       (_.HasCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) &&
        base_type_storage_class == spv::StorageClass::Workgroup)) &&
      !_.HasDecoration(base_type->id(), spv::Decoration::ArrayStride)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "OpPtrAccessChain must have a Base whose type is decorated "
              "with ArrayStride";
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    const auto untyped_cap =
        untyped_pointer && _.HasCapability(spv::Capability::UntypedPointersKHR);
    if (base_type_storage_class == spv::StorageClass::Workgroup) {
      if (!_.HasCapability(spv::Capability::VariablePointers) && !untyped_cap) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(7651)
               << "OpPtrAccessChain Base operand pointing to Workgroup "
                  "storage class must use VariablePointers capability";
      }
    } else if (base_type_storage_class == spv::StorageClass::StorageBuffer) {
      if (!_.features().variable_pointers && !untyped_cap) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(7652)
               << "OpPtrAccessChain Base operand pointing to StorageBuffer "
                  "storage class must use VariablePointers or "
                  "VariablePointersStorageBuffer capability";
      }
    } else if (base_type_storage_class !=
                   spv::StorageClass::PhysicalStorageBuffer &&
               !untyped_cap) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(7650)
             << "OpPtrAccessChain Base operand must point to Workgroup, "
                "StorageBuffer, or PhysicalStorageBuffer storage class";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateArrayLength(ValidationState_t& state,
                                 const Instruction* inst) {
  std::string instr_name =
      "Op" + std::string(spvOpcodeString(static_cast<spv::Op>(inst->opcode())));

  // Result type must be a 32-bit unsigned int.
  auto result_type = state.FindDef(inst->type_id());
  if (result_type->opcode() != spv::Op::OpTypeInt ||
      result_type->GetOperandAs<uint32_t>(1) != 32 ||
      result_type->GetOperandAs<uint32_t>(2) != 0) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Result Type of " << instr_name << " <id> "
           << state.getIdName(inst->id())
           << " must be OpTypeInt with width 32 and signedness 0.";
  }

  const bool untyped = inst->opcode() == spv::Op::OpUntypedArrayLengthKHR;
  auto pointer_ty_id = state.GetOperandTypeId(inst, (untyped ? 3 : 2));
  auto pointer_ty = state.FindDef(pointer_ty_id);
  if (untyped) {
    if (pointer_ty->opcode() != spv::Op::OpTypeUntypedPointerKHR) {
      return state.diag(SPV_ERROR_INVALID_ID, inst)
             << "Pointer must be an untyped pointer";
    }
  } else if (pointer_ty->opcode() != spv::Op::OpTypePointer) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Structure's type in " << instr_name << " <id> "
           << state.getIdName(inst->id())
           << " must be a pointer to an OpTypeStruct.";
  }

  Instruction* structure_type = nullptr;
  if (untyped) {
    structure_type = state.FindDef(inst->GetOperandAs<uint32_t>(2));
  } else {
    structure_type = state.FindDef(pointer_ty->GetOperandAs<uint32_t>(2));
  }

  if (structure_type->opcode() != spv::Op::OpTypeStruct) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Structure's type in " << instr_name << " <id> "
           << state.getIdName(inst->id())
           << " must be a pointer to an OpTypeStruct.";
  }

  auto num_of_members = structure_type->operands().size() - 1;
  auto last_member =
      state.FindDef(structure_type->GetOperandAs<uint32_t>(num_of_members));
  if (last_member->opcode() != spv::Op::OpTypeRuntimeArray) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Structure's last member in " << instr_name << " <id> "
           << state.getIdName(inst->id()) << " must be an OpTypeRuntimeArray.";
  }

  // The array member must the index of the last element (the run time
  // array).
  const auto index = untyped ? 4 : 3;
  if (inst->GetOperandAs<uint32_t>(index) != num_of_members - 1) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The array member in " << instr_name << " <id> "
           << state.getIdName(inst->id())
           << " must be the last member of the struct.";
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state,
                                               const Instruction* inst) {
  std::string instr_name =
      "Op" + std::string(spvOpcodeString(static_cast<spv::Op>(inst->opcode())));

  // Result type must be a 32-bit unsigned int.
  auto result_type = state.FindDef(inst->type_id());
  if (result_type->opcode() != spv::Op::OpTypeInt ||
      result_type->GetOperandAs<uint32_t>(1) != 32 ||
      result_type->GetOperandAs<uint32_t>(2) != 0) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Result Type of " << instr_name << " <id> "
           << state.getIdName(inst->id())
           << " must be OpTypeInt with width 32 and signedness 0.";
  }

  bool isKhr = inst->opcode() == spv::Op::OpCooperativeMatrixLengthKHR;
  auto type_id = inst->GetOperandAs<uint32_t>(2);
  auto type = state.FindDef(type_id);
  if (isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The type in " << instr_name << " <id> "
           << state.getIdName(type_id)
           << " must be OpTypeCooperativeMatrixKHR.";
  } else if (!isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The type in " << instr_name << " <id> "
           << state.getIdName(type_id) << " must be OpTypeCooperativeMatrixNV.";
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
                                                  const Instruction* inst) {
  uint32_t type_id;
  const char* opname;
  if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) {
    type_id = inst->type_id();
    opname = "spv::Op::OpCooperativeMatrixLoadNV";
  } else {
    // get Object operand's type
    type_id = _.FindDef(inst->GetOperandAs<uint32_t>(1))->type_id();
    opname = "spv::Op::OpCooperativeMatrixStoreNV";
  }

  auto matrix_type = _.FindDef(type_id);

  if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) {
    if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeMatrixLoadNV Result Type <id> "
             << _.getIdName(type_id) << " is not a cooperative matrix type.";
    } else {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeMatrixStoreNV Object type <id> "
             << _.getIdName(type_id) << " is not a cooperative matrix type.";
    }
  }

  const auto pointer_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 2u : 0u;
  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  const auto pointer = _.FindDef(pointer_id);
  if (!pointer ||
      ((_.addressing_model() == spv::AddressingModel::Logical) &&
       ((!_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
        (_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer_id)
           << " is not a logical pointer.";
  }

  const auto pointer_type_id = pointer->type_id();
  const auto pointer_type = _.FindDef(pointer_type_id);
  if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " type for pointer <id> " << _.getIdName(pointer_id)
           << " is not a pointer type.";
  }

  const auto storage_class_index = 1u;
  const auto storage_class =
      pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);

  if (storage_class != spv::StorageClass::Workgroup &&
      storage_class != spv::StorageClass::StorageBuffer &&
      storage_class != spv::StorageClass::PhysicalStorageBuffer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " storage class for pointer type <id> "
           << _.getIdName(pointer_type_id)
           << " is not Workgroup or StorageBuffer.";
  }

  const auto pointee_id = pointer_type->GetOperandAs<uint32_t>(2);
  const auto pointee_type = _.FindDef(pointee_id);
  if (!pointee_type || !(_.IsIntScalarOrVectorType(pointee_id) ||
                         _.IsFloatScalarOrVectorType(pointee_id))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer->id())
           << "s Type must be a scalar or vector type.";
  }

  const auto stride_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 3u : 2u;
  const auto stride_id = inst->GetOperandAs<uint32_t>(stride_index);
  const auto stride = _.FindDef(stride_id);
  if (!stride || !_.IsIntScalarType(stride->type_id())) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Stride operand <id> " << _.getIdName(stride_id)
           << " must be a scalar integer type.";
  }

  const auto colmajor_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 4u : 3u;
  const auto colmajor_id = inst->GetOperandAs<uint32_t>(colmajor_index);
  const auto colmajor = _.FindDef(colmajor_id);
  if (!colmajor || !_.IsBoolScalarType(colmajor->type_id()) ||
      !(spvOpcodeIsConstant(colmajor->opcode()) ||
        spvOpcodeIsSpecConstant(colmajor->opcode()))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Column Major operand <id> " << _.getIdName(colmajor_id)
           << " must be a boolean constant instruction.";
  }

  const auto memory_access_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 5u : 4u;
  if (inst->operands().size() > memory_access_index) {
    if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
      return error;
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _,
                                                   const Instruction* inst) {
  uint32_t type_id;
  const char* opname;
  if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
    type_id = inst->type_id();
    opname = "spv::Op::OpCooperativeMatrixLoadKHR";
  } else {
    // get Object operand's type
    type_id = _.FindDef(inst->GetOperandAs<uint32_t>(1))->type_id();
    opname = "spv::Op::OpCooperativeMatrixStoreKHR";
  }

  auto matrix_type = _.FindDef(type_id);

  if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) {
    if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeMatrixLoadKHR Result Type <id> "
             << _.getIdName(type_id) << " is not a cooperative matrix type.";
    } else {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeMatrixStoreKHR Object type <id> "
             << _.getIdName(type_id) << " is not a cooperative matrix type.";
    }
  }

  const auto pointer_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 2u : 0u;
  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  const auto pointer = _.FindDef(pointer_id);
  if (!pointer ||
      ((_.addressing_model() == spv::AddressingModel::Logical) &&
       ((!_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
        (_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer_id)
           << " is not a logical pointer.";
  }

  const auto pointer_type_id = pointer->type_id();
  const auto pointer_type = _.FindDef(pointer_type_id);
  if (!pointer_type ||
      !(pointer_type->opcode() == spv::Op::OpTypePointer ||
        pointer_type->opcode() == spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " type for pointer <id> " << _.getIdName(pointer_id)
           << " is not a pointer type.";
  }

  const bool untyped =
      pointer_type->opcode() == spv::Op::OpTypeUntypedPointerKHR;
  const auto storage_class_index = 1u;
  const auto storage_class =
      pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (storage_class != spv::StorageClass::Workgroup &&
        storage_class != spv::StorageClass::StorageBuffer &&
        storage_class != spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << _.VkErrorID(8973) << opname
             << " storage class for pointer type <id> "
             << _.getIdName(pointer_type_id)
             << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer.";
    }
  }

  if (!untyped) {
    const auto pointee_id = pointer_type->GetOperandAs<uint32_t>(2);
    const auto pointee_type = _.FindDef(pointee_id);
    if (!pointee_type || !(_.IsIntScalarOrVectorType(pointee_id) ||
                           _.IsFloatScalarOrVectorType(pointee_id))) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opname << " Pointer <id> " << _.getIdName(pointer->id())
             << "s Type must be a scalar or vector type.";
    }
  }

  const auto layout_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 3u : 2u;
  const auto layout_id = inst->GetOperandAs<uint32_t>(layout_index);
  const auto layout_inst = _.FindDef(layout_id);
  if (!layout_inst || !_.IsIntScalarType(layout_inst->type_id()) ||
      !spvOpcodeIsConstant(layout_inst->opcode())) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "MemoryLayout operand <id> " << _.getIdName(layout_id)
           << " must be a 32-bit integer constant instruction.";
  }

  bool stride_required = false;
  uint64_t layout;
  if (_.EvalConstantValUint64(layout_id, &layout)) {
    stride_required =
        (layout == (uint64_t)spv::CooperativeMatrixLayout::RowMajorKHR) ||
        (layout == (uint64_t)spv::CooperativeMatrixLayout::ColumnMajorKHR);
  }

  const auto stride_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 4u : 3u;
  if (inst->operands().size() > stride_index) {
    const auto stride_id = inst->GetOperandAs<uint32_t>(stride_index);
    const auto stride = _.FindDef(stride_id);
    if (!stride || !_.IsIntScalarType(stride->type_id())) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Stride operand <id> " << _.getIdName(stride_id)
             << " must be a scalar integer type.";
    }
  } else if (stride_required) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "MemoryLayout " << layout << " requires a Stride.";
  }

  const auto memory_access_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 5u : 4u;
  if (inst->operands().size() > memory_access_index) {
    if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
      return error;
  }

  return SPV_SUCCESS;
}

// Returns the number of instruction words taken up by a tensor addressing
// operands argument and its implied operands.
int TensorAddressingOperandsNumWords(spv::TensorAddressingOperandsMask mask) {
  int result = 1;  // Count the mask
  if ((mask & spv::TensorAddressingOperandsMask::TensorView) !=
      spv::TensorAddressingOperandsMask::MaskNone)
    ++result;
  if ((mask & spv::TensorAddressingOperandsMask::DecodeFunc) !=
      spv::TensorAddressingOperandsMask::MaskNone)
    ++result;
  return result;
}

spv_result_t ValidateCooperativeMatrixLoadStoreTensorNV(
    ValidationState_t& _, const Instruction* inst) {
  uint32_t type_id;
  const char* opname;
  if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
    type_id = inst->type_id();
    opname = "spv::Op::OpCooperativeMatrixLoadTensorNV";
  } else {
    // get Object operand's type
    type_id = _.FindDef(inst->GetOperandAs<uint32_t>(1))->type_id();
    opname = "spv::Op::OpCooperativeMatrixStoreTensorNV";
  }

  auto matrix_type = _.FindDef(type_id);

  if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) {
    if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeMatrixLoadTensorNV Result Type <id> "
             << _.getIdName(type_id) << " is not a cooperative matrix type.";
    } else {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeMatrixStoreTensorNV Object type <id> "
             << _.getIdName(type_id) << " is not a cooperative matrix type.";
    }
  }

  const auto pointer_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 2u : 0u;
  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  const auto pointer = _.FindDef(pointer_id);
  if (!pointer ||
      ((_.addressing_model() == spv::AddressingModel::Logical) &&
       ((!_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
        (_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer_id)
           << " is not a logical pointer.";
  }

  const auto pointer_type_id = pointer->type_id();
  const auto pointer_type = _.FindDef(pointer_type_id);
  if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " type for pointer <id> " << _.getIdName(pointer_id)
           << " is not a pointer type.";
  }

  const auto storage_class_index = 1u;
  const auto storage_class =
      pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);

  if (storage_class != spv::StorageClass::Workgroup &&
      storage_class != spv::StorageClass::StorageBuffer &&
      storage_class != spv::StorageClass::PhysicalStorageBuffer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << _.VkErrorID(8973) << opname
           << " storage class for pointer type <id> "
           << _.getIdName(pointer_type_id)
           << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer.";
  }

  if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
    const auto object_index = 3;
    const auto object_id = inst->GetOperandAs<uint32_t>(object_index);
    const auto object = _.FindDef(object_id);
    if (!object || object->type_id() != type_id) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opname << " Object <id> " << _.getIdName(object_id)
             << " type does not match Result Type.";
    }
  }

  const auto tensor_layout_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 4u : 2u;
  const auto tensor_layout_id =
      inst->GetOperandAs<uint32_t>(tensor_layout_index);
  const auto tensor_layout = _.FindDef(tensor_layout_id);
  if (!tensor_layout || _.FindDef(tensor_layout->type_id())->opcode() !=
                            spv::Op::OpTypeTensorLayoutNV) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " TensorLayout <id> " << _.getIdName(tensor_layout_id)
           << " does not have a tensor layout type.";
  }

  const auto memory_access_index =
      (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 5u : 3u;
  if (inst->operands().size() > memory_access_index) {
    if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
      return error;
  }

  const auto memory_access_mask =
      inst->GetOperandAs<uint32_t>(memory_access_index);
  const auto tensor_operands_index =
      memory_access_index + MemoryAccessNumWords(memory_access_mask);
  const auto tensor_operands =
      inst->GetOperandAs<spv::TensorAddressingOperandsMask>(
          tensor_operands_index);

  if (inst->operands().size() <
      tensor_operands_index +
          TensorAddressingOperandsNumWords(tensor_operands)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " not enough tensor addressing operands.";
  }

  uint32_t tensor_operand_index = tensor_operands_index + 1;
  if ((tensor_operands & spv::TensorAddressingOperandsMask::TensorView) !=
      spv::TensorAddressingOperandsMask::MaskNone) {
    const auto tensor_view_id =
        inst->GetOperandAs<uint32_t>(tensor_operand_index);
    const auto tensor_view = _.FindDef(tensor_view_id);
    if (!tensor_view || _.FindDef(tensor_view->type_id())->opcode() !=
                            spv::Op::OpTypeTensorViewNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opname << " TensorView <id> " << _.getIdName(tensor_view_id)
             << " does not have a tensor view type.";
    }

    tensor_operand_index++;
  }

  if ((tensor_operands & spv::TensorAddressingOperandsMask::DecodeFunc) !=
      spv::TensorAddressingOperandsMask::MaskNone) {
    if (inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpCooperativeMatrixStoreTensorNV does not support DecodeFunc.";
    }
    const auto decode_func_id =
        inst->GetOperandAs<uint32_t>(tensor_operand_index);
    const auto decode_func = _.FindDef(decode_func_id);

    if (!decode_func || decode_func->opcode() != spv::Op::OpFunction) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
             << " is not a function.";
    }

    const auto component_type_index = 1;
    const auto component_type_id =
        matrix_type->GetOperandAs<uint32_t>(component_type_index);

    const auto function_type =
        _.FindDef(decode_func->GetOperandAs<uint32_t>(3));
    if (function_type->GetOperandAs<uint32_t>(1) != component_type_id) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
             << " return type must match matrix component type.";
    }

    const auto decode_ptr_type_id = function_type->GetOperandAs<uint32_t>(2);
    const auto decode_ptr_type = _.FindDef(decode_ptr_type_id);
    auto decode_storage_class =
        decode_ptr_type->GetOperandAs<spv::StorageClass>(storage_class_index);

    if (decode_storage_class != spv::StorageClass::PhysicalStorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
             << " first parameter must be pointer to PhysicalStorageBuffer.";
    }

    const auto tensor_layout_type = _.FindDef(tensor_layout->type_id());

    for (uint32_t param = 3; param < 5; ++param) {
      const auto param_type_id = function_type->GetOperandAs<uint32_t>(param);
      const auto param_type = _.FindDef(param_type_id);
      if (param_type->opcode() != spv::Op::OpTypeArray) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
               << " second/third parameter must be array of 32-bit integer "
                  "with "
               << " dimension equal to the tensor dimension.";
      }
      const auto length_index = 2u;
      uint64_t array_length;
      if (_.EvalConstantValUint64(
              param_type->GetOperandAs<uint32_t>(length_index),
              &array_length)) {
        const auto tensor_layout_dim_id =
            tensor_layout_type->GetOperandAs<uint32_t>(1);
        uint64_t dim_value;
        if (_.EvalConstantValUint64(tensor_layout_dim_id, &dim_value)) {
          if (array_length != dim_value) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << opname << " DecodeFunc <id> "
                   << _.getIdName(decode_func_id)
                   << " second/third parameter must be array of 32-bit integer "
                      "with "
                   << " dimension equal to the tensor dimension.";
          }
        }
      }
    }

    tensor_operand_index++;
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateInt32Operand(ValidationState_t& _, const Instruction* inst,
                                  uint32_t operand_index,
                                  const char* opcode_name,
                                  const char* operand_name) {
  const auto type_id =
      _.FindDef(inst->GetOperandAs<uint32_t>(operand_index))->type_id();
  if (!_.IsIntScalarType(type_id) || _.GetBitWidth(type_id) != 32) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " " << operand_name << " type <id> "
           << _.getIdName(type_id) << " is not a 32 bit integer.";
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeVectorPointer(ValidationState_t& _,
                                              const Instruction* inst,
                                              const char* opname,
                                              uint32_t pointer_index) {
  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  const auto pointer = _.FindDef(pointer_id);
  if (!pointer ||
      ((_.addressing_model() == spv::AddressingModel::Logical) &&
       ((!_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
        (_.features().variable_pointers &&
         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer_id)
           << " is not a logical pointer.";
  }

  const auto pointer_type_id = pointer->type_id();
  const auto pointer_type = _.FindDef(pointer_type_id);
  if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " type for pointer <id> " << _.getIdName(pointer_id)
           << " is not a pointer type.";
  }

  const auto storage_class_index = 1u;
  const auto storage_class =
      pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);

  if (storage_class != spv::StorageClass::Workgroup &&
      storage_class != spv::StorageClass::StorageBuffer &&
      storage_class != spv::StorageClass::PhysicalStorageBuffer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " storage class for pointer type <id> "
           << _.getIdName(pointer_type_id)
           << " is not Workgroup or StorageBuffer.";
  }

  const auto pointee_id = pointer_type->GetOperandAs<uint32_t>(2);
  const auto pointee_type = _.FindDef(pointee_id);
  if (!pointee_type ||
      (pointee_type->opcode() != spv::Op::OpTypeArray &&
       pointee_type->opcode() != spv::Op::OpTypeRuntimeArray)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer->id())
           << "s Type must be an array type.";
  }

  const auto array_elem_type_id = pointee_type->GetOperandAs<uint32_t>(1);
  auto array_elem_type = _.FindDef(array_elem_type_id);
  if (!array_elem_type || !(_.IsIntScalarOrVectorType(array_elem_type_id) ||
                            _.IsFloatScalarOrVectorType(array_elem_type_id))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opname << " Pointer <id> " << _.getIdName(pointer->id())
           << "s Type must be an array of scalar or vector type.";
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeVectorLoadStoreNV(ValidationState_t& _,
                                                  const Instruction* inst) {
  uint32_t type_id;
  const char* opname;
  if (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) {
    type_id = inst->type_id();
    opname = "spv::Op::OpCooperativeVectorLoadNV";
  } else {
    // get Object operand's type
    type_id = _.FindDef(inst->GetOperandAs<uint32_t>(2))->type_id();
    opname = "spv::Op::OpCooperativeVectorStoreNV";
  }

  auto vector_type = _.FindDef(type_id);

  if (vector_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
    if (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeVectorLoadNV Result Type <id> "
             << _.getIdName(type_id) << " is not a cooperative vector type.";
    } else {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "spv::Op::OpCooperativeVectorStoreNV Object type <id> "
             << _.getIdName(type_id) << " is not a cooperative vector type.";
    }
  }

  const auto pointer_index =
      (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) ? 2u : 0u;

  if (auto error =
          ValidateCooperativeVectorPointer(_, inst, opname, pointer_index)) {
    return error;
  }

  const auto memory_access_index =
      (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) ? 4u : 3u;
  if (inst->operands().size() > memory_access_index) {
    if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
      return error;
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeVectorOuterProductNV(ValidationState_t& _,
                                                     const Instruction* inst) {
  const auto pointer_index = 0u;
  const auto opcode_name =
      "spv::Op::OpCooperativeVectorOuterProductAccumulateNV";

  if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
                                                    pointer_index)) {
    return error;
  }

  auto type_id = _.FindDef(inst->GetOperandAs<uint32_t>(2))->type_id();
  auto a_type = _.FindDef(type_id);

  if (a_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " A type <id> " << _.getIdName(type_id)
           << " is not a cooperative vector type.";
  }

  type_id = _.FindDef(inst->GetOperandAs<uint32_t>(3))->type_id();
  auto b_type = _.FindDef(type_id);

  if (b_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " B type <id> " << _.getIdName(type_id)
           << " is not a cooperative vector type.";
  }

  const auto a_component_type_id = a_type->GetOperandAs<uint32_t>(1);
  const auto b_component_type_id = b_type->GetOperandAs<uint32_t>(1);

  if (a_component_type_id != b_component_type_id) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " A and B component types "
           << _.getIdName(a_component_type_id) << " and "
           << _.getIdName(b_component_type_id) << " do not match.";
  }

  if (auto error = ValidateInt32Operand(_, inst, 1, opcode_name, "Offset")) {
    return error;
  }

  if (auto error =
          ValidateInt32Operand(_, inst, 4, opcode_name, "MemoryLayout")) {
    return error;
  }

  if (auto error = ValidateInt32Operand(_, inst, 5, opcode_name,
                                        "MatrixInterpretation")) {
    return error;
  }

  if (inst->operands().size() > 6) {
    if (auto error =
            ValidateInt32Operand(_, inst, 6, opcode_name, "MatrixStride")) {
      return error;
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeVectorReduceSumNV(ValidationState_t& _,
                                                  const Instruction* inst) {
  const auto opcode_name = "spv::Op::OpCooperativeVectorReduceSumAccumulateNV";
  const auto pointer_index = 0u;

  if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
                                                    pointer_index)) {
    return error;
  }

  auto type_id = _.FindDef(inst->GetOperandAs<uint32_t>(2))->type_id();
  auto v_type = _.FindDef(type_id);

  if (v_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " V type <id> " << _.getIdName(type_id)
           << " is not a cooperative vector type.";
  }

  if (auto error = ValidateInt32Operand(_, inst, 1, opcode_name, "Offset")) {
    return error;
  }

  return SPV_SUCCESS;
}

bool InterpretationIsPacked(spv::ComponentType interp) {
  switch (interp) {
    case spv::ComponentType::SignedInt8PackedNV:
    case spv::ComponentType::UnsignedInt8PackedNV:
      return true;
    default:
      return false;
  }
}

using std::get;

spv_result_t ValidateCooperativeVectorMatrixMulNV(ValidationState_t& _,
                                                  const Instruction* inst) {
  const bool has_bias =
      inst->opcode() == spv::Op::OpCooperativeVectorMatrixMulAddNV;
  const auto opcode_name = has_bias
                               ? "spv::Op::OpCooperativeVectorMatrixMulAddNV"
                               : "spv::Op::OpCooperativeVectorMatrixMulNV";

  const auto bias_offset = has_bias ? 3 : 0;

  const auto result_type_index = 0u;
  const auto input_index = 2u;
  const auto input_interpretation_index = 3u;
  const auto matrix_index = 4u;
  const auto matrix_interpretation_index = 6u;
  const auto bias_index = 7u;
  const auto bias_interpretation_index = 9u;
  const auto m_index = 7u + bias_offset;
  const auto k_index = 8u + bias_offset;
  const auto memory_layout_index = 9u + bias_offset;
  const auto transpose_index = 10u + bias_offset;

  const auto result_type_id = inst->GetOperandAs<uint32_t>(result_type_index);
  const auto input_id = inst->GetOperandAs<uint32_t>(input_index);
  const auto input_interpretation_id =
      inst->GetOperandAs<uint32_t>(input_interpretation_index);
  const auto matrix_interpretation_id =
      inst->GetOperandAs<uint32_t>(matrix_interpretation_index);
  const auto bias_interpretation_id =
      inst->GetOperandAs<uint32_t>(bias_interpretation_index);
  const auto m_id = inst->GetOperandAs<uint32_t>(m_index);
  const auto k_id = inst->GetOperandAs<uint32_t>(k_index);
  const auto memory_layout_id =
      inst->GetOperandAs<uint32_t>(memory_layout_index);
  const auto transpose_id = inst->GetOperandAs<uint32_t>(transpose_index);

  if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
                                                    matrix_index)) {
    return error;
  }

  if (inst->opcode() == spv::Op::OpCooperativeVectorMatrixMulAddNV) {
    if (auto error = ValidateCooperativeVectorPointer(_, inst, opcode_name,
                                                      bias_index)) {
      return error;
    }
  }

  const auto result_type = _.FindDef(result_type_id);

  if (result_type->opcode() != spv::Op::OpTypeCooperativeVectorNV) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " result type <id> " << _.getIdName(result_type_id)
           << " is not a cooperative vector type.";
  }

  const auto result_component_type_id = result_type->GetOperandAs<uint32_t>(1u);
  if (!(_.IsIntScalarType(result_component_type_id) &&
        _.GetBitWidth(result_component_type_id) == 32) &&
      !(_.IsFloatScalarType(result_component_type_id) &&
        (_.GetBitWidth(result_component_type_id) == 32 ||
         _.GetBitWidth(result_component_type_id) == 16))) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " result component type <id> "
           << _.getIdName(result_component_type_id)
           << " is not a 32 bit int or 16/32 bit float.";
  }

  const auto m_eval = _.EvalInt32IfConst(m_id);
  const auto rc_eval =
      _.EvalInt32IfConst(result_type->GetOperandAs<uint32_t>(2u));
  if (get<1>(m_eval) && get<1>(rc_eval) && get<2>(m_eval) != get<2>(rc_eval)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " result type number of components "
           << get<2>(rc_eval) << " does not match M " << get<2>(m_eval);
  }

  const auto k_eval = _.EvalInt32IfConst(k_id);

  const auto input = _.FindDef(input_id);
  const auto input_type = _.FindDef(input->type_id());
  const auto input_num_components_id = input_type->GetOperandAs<uint32_t>(2u);

  auto input_interp_eval = _.EvalInt32IfConst(input_interpretation_id);
  if (get<1>(input_interp_eval) &&
      !InterpretationIsPacked(spv::ComponentType{get<2>(input_interp_eval)})) {
    const auto inc_eval = _.EvalInt32IfConst(input_num_components_id);
    if (get<1>(inc_eval) && get<1>(k_eval) &&
        get<2>(inc_eval) != get<2>(k_eval)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opcode_name << " input number of components "
             << get<2>(inc_eval) << " does not match K " << get<2>(k_eval);
    }
  }

  if (!_.IsBoolScalarType(_.FindDef(transpose_id)->type_id())) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " Transpose <id> " << _.getIdName(transpose_id)
           << " is not a scalar boolean.";
  }

  const auto check_constant = [&](uint32_t id,
                                  const char* operand_name) -> spv_result_t {
    if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << opcode_name << " " << operand_name << " <id> "
             << _.getIdName(id) << " is not a constant instruction.";
    }
    return SPV_SUCCESS;
  };

  if (auto error =
          check_constant(input_interpretation_id, "InputInterpretation")) {
    return error;
  }
  if (auto error =
          check_constant(matrix_interpretation_id, "MatrixInterpretation")) {
    return error;
  }
  if (has_bias) {
    if (auto error =
            check_constant(bias_interpretation_id, "BiasInterpretation")) {
      return error;
    }
  }
  if (auto error = check_constant(m_id, "M")) {
    return error;
  }
  if (auto error = check_constant(k_id, "K")) {
    return error;
  }
  if (auto error = check_constant(memory_layout_id, "MemoryLayout")) {
    return error;
  }
  if (auto error = check_constant(transpose_id, "Transpose")) {
    return error;
  }

  if (auto error = ValidateInt32Operand(_, inst, input_interpretation_index,
                                        opcode_name, "InputInterpretation")) {
    return error;
  }
  if (auto error = ValidateInt32Operand(_, inst, matrix_interpretation_index,
                                        opcode_name, "MatrixInterpretation")) {
    return error;
  }
  if (has_bias) {
    if (auto error = ValidateInt32Operand(_, inst, bias_interpretation_index,
                                          opcode_name, "BiasInterpretation")) {
      return error;
    }
  }
  if (auto error = ValidateInt32Operand(_, inst, m_index, opcode_name, "M")) {
    return error;
  }
  if (auto error = ValidateInt32Operand(_, inst, k_index, opcode_name, "K")) {
    return error;
  }
  if (auto error = ValidateInt32Operand(_, inst, memory_layout_index,
                                        opcode_name, "MemoryLayout")) {
    return error;
  }

  return SPV_SUCCESS;
}

spv_result_t ValidatePtrComparison(ValidationState_t& _,
                                   const Instruction* inst) {
  if (_.addressing_model() == spv::AddressingModel::Logical &&
      !_.features().variable_pointers) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Instruction cannot for logical addressing model be used without "
              "a variable pointers capability";
  }

  const auto result_type = _.FindDef(inst->type_id());
  if (inst->opcode() == spv::Op::OpPtrDiff) {
    if (!result_type || result_type->opcode() != spv::Op::OpTypeInt) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Result Type must be an integer scalar";
    }
  } else {
    if (!result_type || result_type->opcode() != spv::Op::OpTypeBool) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Result Type must be OpTypeBool";
    }
  }

  const auto op1 = _.FindDef(inst->GetOperandAs<uint32_t>(2u));
  const auto op2 = _.FindDef(inst->GetOperandAs<uint32_t>(3u));
  const auto op1_type = _.FindDef(op1->type_id());
  const auto op2_type = _.FindDef(op2->type_id());
  if (!op1_type || (op1_type->opcode() != spv::Op::OpTypePointer &&
                    op1_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Operand type must be a pointer";
  }

  if (!op2_type || (op2_type->opcode() != spv::Op::OpTypePointer &&
                    op2_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Operand type must be a pointer";
  }

  if (inst->opcode() == spv::Op::OpPtrDiff) {
    if (op1->type_id() != op2->type_id()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "The types of Operand 1 and Operand 2 must match";
    }
  } else {
    const auto either_untyped =
        op1_type->opcode() == spv::Op::OpTypeUntypedPointerKHR ||
        op2_type->opcode() == spv::Op::OpTypeUntypedPointerKHR;
    if (either_untyped) {
      const auto sc1 = op1_type->GetOperandAs<spv::StorageClass>(1);
      const auto sc2 = op2_type->GetOperandAs<spv::StorageClass>(1);
      if (sc1 != sc2) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Pointer storage classes must match";
      }
    } else if (op1->type_id() != op2->type_id()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "The types of Operand 1 and Operand 2 must match";
    }
  }

  spv::StorageClass sc = op1_type->GetOperandAs<spv::StorageClass>(1u);
  if (_.addressing_model() == spv::AddressingModel::Logical) {
    if (sc != spv::StorageClass::Workgroup &&
        sc != spv::StorageClass::StorageBuffer) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Invalid pointer storage class";
    }

    if (sc == spv::StorageClass::Workgroup &&
        !_.HasCapability(spv::Capability::VariablePointers)) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Workgroup storage class pointer requires VariablePointers "
                "capability to be specified";
    }
  } else if (sc == spv::StorageClass::PhysicalStorageBuffer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Cannot use a pointer in the PhysicalStorageBuffer storage class";
  }

  return SPV_SUCCESS;
}

}  // namespace

spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) {
  switch (inst->opcode()) {
    case spv::Op::OpVariable:
    case spv::Op::OpUntypedVariableKHR:
      if (auto error = ValidateVariable(_, inst)) return error;
      break;
    case spv::Op::OpLoad:
      if (auto error = ValidateLoad(_, inst)) return error;
      break;
    case spv::Op::OpStore:
      if (auto error = ValidateStore(_, inst)) return error;
      break;
    case spv::Op::OpCopyMemory:
    case spv::Op::OpCopyMemorySized:
      if (auto error = ValidateCopyMemory(_, inst)) return error;
      break;
    case spv::Op::OpPtrAccessChain:
    case spv::Op::OpUntypedPtrAccessChainKHR:
    case spv::Op::OpUntypedInBoundsPtrAccessChainKHR:
      if (auto error = ValidatePtrAccessChain(_, inst)) return error;
      break;
    case spv::Op::OpAccessChain:
    case spv::Op::OpInBoundsAccessChain:
    case spv::Op::OpInBoundsPtrAccessChain:
    case spv::Op::OpUntypedAccessChainKHR:
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
      if (auto error = ValidateAccessChain(_, inst)) return error;
      break;
    case spv::Op::OpRawAccessChainNV:
      if (auto error = ValidateRawAccessChain(_, inst)) return error;
      break;
    case spv::Op::OpArrayLength:
    case spv::Op::OpUntypedArrayLengthKHR:
      if (auto error = ValidateArrayLength(_, inst)) return error;
      break;
    case spv::Op::OpCooperativeMatrixLoadNV:
    case spv::Op::OpCooperativeMatrixStoreNV:
      if (auto error = ValidateCooperativeMatrixLoadStoreNV(_, inst))
        return error;
      break;
    case spv::Op::OpCooperativeMatrixLengthKHR:
    case spv::Op::OpCooperativeMatrixLengthNV:
      if (auto error = ValidateCooperativeMatrixLengthNV(_, inst)) return error;
      break;
    case spv::Op::OpCooperativeMatrixLoadKHR:
    case spv::Op::OpCooperativeMatrixStoreKHR:
      if (auto error = ValidateCooperativeMatrixLoadStoreKHR(_, inst))
        return error;
      break;
    case spv::Op::OpCooperativeMatrixLoadTensorNV:
    case spv::Op::OpCooperativeMatrixStoreTensorNV:
      if (auto error = ValidateCooperativeMatrixLoadStoreTensorNV(_, inst))
        return error;
      break;
    case spv::Op::OpCooperativeVectorLoadNV:
    case spv::Op::OpCooperativeVectorStoreNV:
      if (auto error = ValidateCooperativeVectorLoadStoreNV(_, inst))
        return error;
      break;
    case spv::Op::OpCooperativeVectorOuterProductAccumulateNV:
      if (auto error = ValidateCooperativeVectorOuterProductNV(_, inst))
        return error;
      break;
    case spv::Op::OpCooperativeVectorReduceSumAccumulateNV:
      if (auto error = ValidateCooperativeVectorReduceSumNV(_, inst))
        return error;
      break;
    case spv::Op::OpCooperativeVectorMatrixMulNV:
    case spv::Op::OpCooperativeVectorMatrixMulAddNV:
      if (auto error = ValidateCooperativeVectorMatrixMulNV(_, inst))
        return error;
      break;
    case spv::Op::OpPtrEqual:
    case spv::Op::OpPtrNotEqual:
    case spv::Op::OpPtrDiff:
      if (auto error = ValidatePtrComparison(_, inst)) return error;
      break;
    case spv::Op::OpImageTexelPointer:
    case spv::Op::OpGenericPtrMemSemantics:
    default:
      break;
  }

  return SPV_SUCCESS;
}
}  // namespace val
}  // namespace spvtools
