// 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<Instruction*, Instruction*> GetPointerTypes(ValidationState_t& _,
                                                      const Instruction* inst) {
  Instruction* dst_pointer_type = nullptr;
  Instruction* src_pointer_type = nullptr;
  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));
      dst_pointer_type = _.FindDef(load_pointer->type_id());
      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));
      dst_pointer_type = _.FindDef(store_pointer->type_id());
      break;
    }
    // Spec: "Matching Storage Class is not required"
    case spv::Op::OpCopyMemory:
    case spv::Op::OpCopyMemorySized: {
      auto dst_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(0));
      dst_pointer_type = _.FindDef(dst_pointer->type_id());
      auto src_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(1));
      src_pointer_type = _.FindDef(src_pointer->type_id());
      break;
    }
    default:
      break;
  }

  return std::make_pair(dst_pointer_type, src_pointer_type);
}

// 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) {
  Instruction* dst_pointer_type = nullptr;
  Instruction* src_pointer_type = nullptr;  // only used for OpCopyMemory
  std::tie(dst_pointer_type, src_pointer_type) = GetPointerTypes(_, inst);

  const spv::StorageClass dst_sc =
      dst_pointer_type ? dst_pointer_type->GetOperandAs<spv::StorageClass>(1)
                       : spv::StorageClass::Max;
  const spv::StorageClass src_sc =
      src_pointer_type ? src_pointer_type->GetOperandAs<spv::StorageClass>(1)
                       : spv::StorageClass::Max;

  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.";
    }

    uint32_t largest_scalar = 0;
    if (dst_sc == spv::StorageClass::PhysicalStorageBuffer) {
      if (dst_pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR) {
        largest_scalar =
            _.GetLargestScalarType(dst_pointer_type->GetOperandAs<uint32_t>(2));
      } else if (inst->type_id() != 0) {
        largest_scalar = _.GetLargestScalarType(inst->type_id());
      } else {
        // TODO need to handle cases like OpStore and OpCopyMemorySized which
        // don't have a result type
      }
    }
    // TODO - Handle Untyped in OpCopyMemory
    if (src_sc == spv::StorageClass::PhysicalStorageBuffer &&
        src_pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR) {
      largest_scalar = std::max(
          largest_scalar,
          _.GetLargestScalarType(src_pointer_type->GetOperandAs<uint32_t>(2)));
    }
    if (aligned_value < largest_scalar) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << _.VkErrorID(6314) << "Memory accesses Aligned operand value "
             << aligned_value << " is too small, the largest scalar type is "
             << largest_scalar << " bytes.";
    }
  }

  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)
               << _.VkErrorID(11167)
               << "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::HitObjectAttributeEXT &&
      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 ||
       _.addressing_model() == spv::AddressingModel::PhysicalStorageBuffer64) &&
      !_.options()->relax_logical_pointer) {
    if (pointee && (pointee->opcode() == spv::Op::OpTypePointer ||
                    pointee->opcode() == spv::Op::OpTypeUntypedPointerKHR)) {
      const auto sc = pointee->GetOperandAs<spv::StorageClass>(1u);
      if (sc != spv::StorageClass::PhysicalStorageBuffer) {
        if (sc != spv::StorageClass::StorageBuffer &&
            sc != spv::StorageClass::Workgroup) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "In Logical addressing, variables can only allocate a "
                    "pointer to the StorageBuffer or Workgroup storage classes";
        } else if (!_.HasCapability(
                       spv::Capability::VariablePointersStorageBuffer) &&
                   sc == spv::StorageClass::StorageBuffer) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "In Logical addressing, variables can only allocate a "
                    "storage buffer pointer if the "
                    "VariablePointersStorageBuffer capability is declared";
        } else if (!_.HasCapability(spv::Capability::VariablePointers) &&
                   sc == spv::StorageClass::Workgroup) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "In Logical addressing, variables can only allocate a "
                    "workgroup pointer if the VariablePointers capability is "
                    "declared";
        } 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::HitObjectAttributeEXT) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "OpVariable, <id> " << _.getIdName(inst->id())
             << ", initializer are not allowed for HitObjectAttributeEXT";
    }
  }

  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 RuntimeDescriptorArray capability.
    if (value_type && value_type->opcode() == spv::Op::OpTypeRuntimeArray) {
      if (!_.HasCapability(spv::Capability::RuntimeDescriptorArray)) {
        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, unless the "
                  "RuntimeDescriptorArray Capability is declared";
      } 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 RuntimeDescriptorArray, 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
    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) {
          // BufferBlock Uniform were always allowed.
          //
          // Block Uniform use to be invalid, but Vulkan added
          // VK_EXT_shader_uniform_buffer_unsized_array and now this is
          // validated at runtime
          //
          // The uniform must have either the Block or BufferBlock decoration
          // (see VUID-StandaloneSpirv-Uniform-06676)
        } 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(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) {
  const spv::Op opcode = 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 Op" << spvOpcodeString(opcode) << " <id> "
             << _.getIdName(inst->id())
             << " must be OpTypeUntypedPointerKHR. Found Op"
             << spvOpcodeString(result_type->opcode()) << ".";
    }
  } else {
    if (!result_type || spv::Op::OpTypePointer != result_type->opcode()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
             << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op"
             << spvOpcodeString(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 Op"
           << spvOpcodeString(opcode) << " 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 Op"
           << spvOpcodeString(opcode) << " 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 Op" << spvOpcodeString(opcode)
           << " 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 Op" << spvOpcodeString(opcode)
             << " must be of type integer.";
    }

    // Logical pointer restrictions: any constant index with a signed integer
    // type must not have its sign bit set.
    if (!_.options()->relax_logical_pointer &&
        (_.addressing_model() == spv::AddressingModel::Logical ||
         _.addressing_model() ==
             spv::AddressingModel::PhysicalStorageBuffer64) &&
        result_type_storage_class !=
            static_cast<uint32_t>(spv::StorageClass::PhysicalStorageBuffer)) {
      if (index_type->GetOperandAs<uint32_t>(2) == 1) {
        int64_t val = 0;
        if (_.EvalConstantValInt64(cur_word, &val)) {
          if (val < 0) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Index at word " << i << " may not have a negative value";
          }
        }
      }
    }

    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 Op" << spvOpcodeString(opcode)
                 << " 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: Op"
                 << spvOpcodeString(opcode) << " 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)
               << "Op" << spvOpcodeString(opcode)
               << " 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)
             << "Op" << spvOpcodeString(opcode) << " result type (Op"
             << spvOpcodeString(result_type_pointee->opcode())
             << ") does not match the type that results from indexing into the "
                "base "
                "<id> (Op"
             << spvOpcodeString(type_pointee->opcode()) << ").";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateRawAccessChain(ValidationState_t& _,
                                    const Instruction* inst) {
  const spv::Op opcode = 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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode)
             << " <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 Op"
             << spvOpcodeString(opcode) << " <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) {
  // 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) {
  const spv::Op opcode = inst->opcode();

  // Result type must be a 32- or 64-bit unsigned int.
  // 64-bit requires CapabilityShader64BitIndexingEXT or a pipeline/shader
  // flag and is validated in VVL.
  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>(1) == 64) ||
      result_type->GetOperandAs<uint32_t>(2) != 0) {
    return state.diag(SPV_ERROR_INVALID_ID, inst)
           << "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
           << state.getIdName(inst->id())
           << " must be OpTypeInt with width 32 or 64 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 Op" << spvOpcodeString(opcode)
           << " <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 Op" << spvOpcodeString(opcode)
           << " <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 Op" << spvOpcodeString(opcode)
           << " <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 Op" << spvOpcodeString(opcode) << " <id> "
           << state.getIdName(inst->id())
           << " must be the last member of the struct.";
  }

  if (spvIsVulkanEnv(state.context()->target_env)) {
    const auto storage_class = pointer_ty->GetOperandAs<spv::StorageClass>(1);
    if (storage_class == spv::StorageClass::Uniform &&
        state.HasDecoration(structure_type->id(), spv::Decoration::Block)) {
      return state.diag(SPV_ERROR_INVALID_ID, inst)
             << state.VkErrorID(11805) << "Op" << spvOpcodeString(opcode)
             << " must not be used on the OpTypeRuntimeArray inside a Uniform "
                "block";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state,
                                               const Instruction* inst) {
  const spv::Op opcode = 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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode) << " <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 Op" << spvOpcodeString(opcode) << " <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;
  bool layout_requires_constant_stride = false;
  uint64_t layout;
  if (_.EvalConstantValUint64(layout_id, &layout)) {
    const bool is_arm_layout =
        (layout ==
         (uint64_t)spv::CooperativeMatrixLayout::RowBlockedInterleavedARM) ||
        (layout ==
         (uint64_t)spv::CooperativeMatrixLayout::ColumnBlockedInterleavedARM);

    if (is_arm_layout) {
      if (!_.HasCapability(spv::Capability::CooperativeMatrixLayoutsARM)) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Using the RowBlockedInterleavedARM or "
                  "ColumnBlockedInterleavedARM MemoryLayout requires the "
                  "CooperativeMatrixLayoutsARM capability be declared";
      }
    }

    stride_required =
        (layout == (uint64_t)spv::CooperativeMatrixLayout::RowMajorKHR) ||
        (layout == (uint64_t)spv::CooperativeMatrixLayout::ColumnMajorKHR) ||
        is_arm_layout;
    layout_requires_constant_stride = is_arm_layout;
  }

  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_inst = _.FindDef(stride_id);
    if (!stride_inst || !_.IsIntScalarType(stride_inst->type_id())) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "Stride operand <id> " << _.getIdName(stride_id)
             << " must be a scalar integer type.";
    }
    // Check SPV_ARM_cooperative_matrix_layouts constraints
    if (layout_requires_constant_stride &&
        !spvOpcodeIsConstant(stride_inst->opcode())) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << "MemoryLayout " << layout
             << " requires Stride come from a constant instruction.";
    }
    if (layout_requires_constant_stride) {
      uint64_t stride;
      if (_.EvalConstantValUint64(stride_id, &stride)) {
        if ((layout ==
             (uint64_t)
                 spv::CooperativeMatrixLayout::RowBlockedInterleavedARM) ||
            (layout ==
             (uint64_t)
                 spv::CooperativeMatrixLayout::ColumnBlockedInterleavedARM)) {
          if ((stride != 1) && (stride != 2) && (stride != 4)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "MemoryLayout " << layout
                   << " requires Stride be 1, 2, or 4.";
          }
        }
        const uint32_t elty_id = matrix_type->GetOperandAs<uint32_t>(1);
        const uint32_t rows_id = matrix_type->GetOperandAs<uint32_t>(3);
        const uint32_t cols_id = matrix_type->GetOperandAs<uint32_t>(4);
        uint64_t rows = 0, cols = 0;
        _.EvalConstantValUint64(rows_id, &rows);
        _.EvalConstantValUint64(cols_id, &cols);
        uint32_t sizeof_component_in_bytes = _.GetBitWidth(elty_id) / 8;
        uint64_t rows_required_multiple = 4;
        uint64_t cols_required_multiple = 16 / sizeof_component_in_bytes;

        if (layout ==
            (uint64_t)spv::CooperativeMatrixLayout::RowBlockedInterleavedARM) {
          cols_required_multiple *= stride;
        }
        if (layout ==
            (uint64_t)
                spv::CooperativeMatrixLayout::ColumnBlockedInterleavedARM) {
          rows_required_multiple *= stride;
        }
        if ((rows != 0) && (rows % rows_required_multiple != 0)) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "MemoryLayout " << layout << " with a Stride of " << stride
                 << " requires that the number of rows be a multiple of "
                 << rows_required_multiple;
        }
        if ((cols != 0) && (cols % cols_required_multiple != 0)) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "MemoryLayout " << layout << " with a Stride of " << stride
                 << " requires that the number of columns be a multiple of "
                 << cols_required_multiple;
        }
      }
    }
  } 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 ValidateInt32Or64Operand(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 || _.GetBitWidth(type_id) == 64)) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << opcode_name << " " << operand_name << " type <id> "
           << _.getIdName(type_id) << " is not a 32 or 64 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;

  const auto offset_index =
      (inst->opcode() == spv::Op::OpCooperativeVectorLoadNV) ? 3u : 1u;

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

  if (auto error =
          ValidateInt32Or64Operand(_, inst, offset_index, opname, "Offset")) {
    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 =
          ValidateInt32Or64Operand(_, 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 =
          ValidateInt32Or64Operand(_, 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_offset_index = 5u;
  const auto matrix_interpretation_index = 6u;
  const auto bias_index = 7u;
  const auto bias_offset_index = 8u;
  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;
  }

  if (auto error = ValidateInt32Or64Operand(_, inst, matrix_offset_index,
                                            opcode_name, "MatrixOffset")) {
    return error;
  }
  if (has_bias) {
    if (auto error = ValidateInt32Or64Operand(_, inst, bias_offset_index,
                                              opcode_name, "BiasOffset")) {
      return error;
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidatePtrComparison(ValidationState_t& _,
                                   const Instruction* inst) {
  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());
  spv::StorageClass sc = op1_type->GetOperandAs<spv::StorageClass>(1u);
  if ((_.addressing_model() == spv::AddressingModel::Logical ||
       _.addressing_model() == spv::AddressingModel::PhysicalStorageBuffer64) &&
      sc != spv::StorageClass::PhysicalStorageBuffer &&
      !_.features().variable_pointers) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Instruction on logical pointers cannot 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";
    }
  }

  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";
    }
  }

  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
