// Copyright 2020 The Tint Authors.  //
// 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 "src/writer/spirv/builder.h"

#include <algorithm>
#include <limits>
#include <utility>

#include "spirv/unified1/GLSL.std.450.h"
#include "src/ast/call_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/internal_attribute.h"
#include "src/ast/override_attribute.h"
#include "src/ast/traverse_expressions.h"
#include "src/sem/array.h"
#include "src/sem/atomic_type.h"
#include "src/sem/builtin.h"
#include "src/sem/call.h"
#include "src/sem/depth_multisampled_texture_type.h"
#include "src/sem/depth_texture_type.h"
#include "src/sem/function.h"
#include "src/sem/member_accessor_expression.h"
#include "src/sem/module.h"
#include "src/sem/multisampled_texture_type.h"
#include "src/sem/reference_type.h"
#include "src/sem/sampled_texture_type.h"
#include "src/sem/statement.h"
#include "src/sem/struct.h"
#include "src/sem/type_constructor.h"
#include "src/sem/type_conversion.h"
#include "src/sem/variable.h"
#include "src/sem/vector_type.h"
#include "src/transform/add_empty_entry_point.h"
#include "src/transform/add_spirv_block_attribute.h"
#include "src/transform/canonicalize_entry_point_io.h"
#include "src/transform/external_texture_transform.h"
#include "src/transform/fold_constants.h"
#include "src/transform/for_loop_to_loop.h"
#include "src/transform/manager.h"
#include "src/transform/remove_unreachable_statements.h"
#include "src/transform/simplify_pointers.h"
#include "src/transform/unshadow.h"
#include "src/transform/var_for_dynamic_index.h"
#include "src/transform/vectorize_scalar_matrix_constructors.h"
#include "src/transform/zero_init_workgroup_memory.h"
#include "src/utils/defer.h"
#include "src/utils/map.h"
#include "src/writer/append_vector.h"

namespace tint {
namespace writer {
namespace spirv {
namespace {

using BuiltinType = sem::BuiltinType;

const char kGLSLstd450[] = "GLSL.std.450";

uint32_t size_of(const InstructionList& instructions) {
  uint32_t size = 0;
  for (const auto& inst : instructions)
    size += inst.word_length();

  return size;
}

uint32_t pipeline_stage_to_execution_model(ast::PipelineStage stage) {
  SpvExecutionModel model = SpvExecutionModelVertex;

  switch (stage) {
    case ast::PipelineStage::kFragment:
      model = SpvExecutionModelFragment;
      break;
    case ast::PipelineStage::kVertex:
      model = SpvExecutionModelVertex;
      break;
    case ast::PipelineStage::kCompute:
      model = SpvExecutionModelGLCompute;
      break;
    case ast::PipelineStage::kNone:
      model = SpvExecutionModelMax;
      break;
  }
  return model;
}

bool LastIsFallthrough(const ast::BlockStatement* stmts) {
  return !stmts->Empty() && stmts->Last()->Is<ast::FallthroughStatement>();
}

/// Returns the matrix type that is `type` or that is wrapped by
/// one or more levels of an arrays inside of `type`.
/// @param type the given type, which must not be null
/// @returns the nested matrix type, or nullptr if none
const sem::Matrix* GetNestedMatrixType(const sem::Type* type) {
  while (auto* arr = type->As<sem::Array>()) {
    type = arr->ElemType();
  }
  return type->As<sem::Matrix>();
}

uint32_t builtin_to_glsl_method(const sem::Builtin* builtin) {
  switch (builtin->Type()) {
    case BuiltinType::kAcos:
      return GLSLstd450Acos;
    case BuiltinType::kAsin:
      return GLSLstd450Asin;
    case BuiltinType::kAtan:
      return GLSLstd450Atan;
    case BuiltinType::kAtan2:
      return GLSLstd450Atan2;
    case BuiltinType::kCeil:
      return GLSLstd450Ceil;
    case BuiltinType::kClamp:
      if (builtin->ReturnType()->is_float_scalar_or_vector()) {
        return GLSLstd450NClamp;
      } else if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
        return GLSLstd450UClamp;
      } else {
        return GLSLstd450SClamp;
      }
    case BuiltinType::kCos:
      return GLSLstd450Cos;
    case BuiltinType::kCosh:
      return GLSLstd450Cosh;
    case BuiltinType::kCross:
      return GLSLstd450Cross;
    case BuiltinType::kDegrees:
      return GLSLstd450Degrees;
    case BuiltinType::kDeterminant:
      return GLSLstd450Determinant;
    case BuiltinType::kDistance:
      return GLSLstd450Distance;
    case BuiltinType::kExp:
      return GLSLstd450Exp;
    case BuiltinType::kExp2:
      return GLSLstd450Exp2;
    case BuiltinType::kFaceForward:
      return GLSLstd450FaceForward;
    case BuiltinType::kFloor:
      return GLSLstd450Floor;
    case BuiltinType::kFma:
      return GLSLstd450Fma;
    case BuiltinType::kFract:
      return GLSLstd450Fract;
    case BuiltinType::kFrexp:
      return GLSLstd450FrexpStruct;
    case BuiltinType::kInverseSqrt:
      return GLSLstd450InverseSqrt;
    case BuiltinType::kLdexp:
      return GLSLstd450Ldexp;
    case BuiltinType::kLength:
      return GLSLstd450Length;
    case BuiltinType::kLog:
      return GLSLstd450Log;
    case BuiltinType::kLog2:
      return GLSLstd450Log2;
    case BuiltinType::kMax:
      if (builtin->ReturnType()->is_float_scalar_or_vector()) {
        return GLSLstd450NMax;
      } else if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
        return GLSLstd450UMax;
      } else {
        return GLSLstd450SMax;
      }
    case BuiltinType::kMin:
      if (builtin->ReturnType()->is_float_scalar_or_vector()) {
        return GLSLstd450NMin;
      } else if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
        return GLSLstd450UMin;
      } else {
        return GLSLstd450SMin;
      }
    case BuiltinType::kMix:
      return GLSLstd450FMix;
    case BuiltinType::kModf:
      return GLSLstd450ModfStruct;
    case BuiltinType::kNormalize:
      return GLSLstd450Normalize;
    case BuiltinType::kPack4x8snorm:
      return GLSLstd450PackSnorm4x8;
    case BuiltinType::kPack4x8unorm:
      return GLSLstd450PackUnorm4x8;
    case BuiltinType::kPack2x16snorm:
      return GLSLstd450PackSnorm2x16;
    case BuiltinType::kPack2x16unorm:
      return GLSLstd450PackUnorm2x16;
    case BuiltinType::kPack2x16float:
      return GLSLstd450PackHalf2x16;
    case BuiltinType::kPow:
      return GLSLstd450Pow;
    case BuiltinType::kRadians:
      return GLSLstd450Radians;
    case BuiltinType::kReflect:
      return GLSLstd450Reflect;
    case BuiltinType::kRefract:
      return GLSLstd450Refract;
    case BuiltinType::kRound:
      return GLSLstd450RoundEven;
    case BuiltinType::kSign:
      return GLSLstd450FSign;
    case BuiltinType::kSin:
      return GLSLstd450Sin;
    case BuiltinType::kSinh:
      return GLSLstd450Sinh;
    case BuiltinType::kSmoothStep:
      return GLSLstd450SmoothStep;
    case BuiltinType::kSqrt:
      return GLSLstd450Sqrt;
    case BuiltinType::kStep:
      return GLSLstd450Step;
    case BuiltinType::kTan:
      return GLSLstd450Tan;
    case BuiltinType::kTanh:
      return GLSLstd450Tanh;
    case BuiltinType::kTrunc:
      return GLSLstd450Trunc;
    case BuiltinType::kUnpack4x8snorm:
      return GLSLstd450UnpackSnorm4x8;
    case BuiltinType::kUnpack4x8unorm:
      return GLSLstd450UnpackUnorm4x8;
    case BuiltinType::kUnpack2x16snorm:
      return GLSLstd450UnpackSnorm2x16;
    case BuiltinType::kUnpack2x16unorm:
      return GLSLstd450UnpackUnorm2x16;
    case BuiltinType::kUnpack2x16float:
      return GLSLstd450UnpackHalf2x16;
    default:
      break;
  }
  return 0;
}

/// @return the vector element type if ty is a vector, otherwise return ty.
const sem::Type* ElementTypeOf(const sem::Type* ty) {
  if (auto* v = ty->As<sem::Vector>()) {
    return v->type();
  }
  return ty;
}

}  // namespace

SanitizedResult Sanitize(const Program* in,
                         bool emit_vertex_point_size,
                         bool disable_workgroup_init) {
  transform::Manager manager;
  transform::DataMap data;

  manager.Add<transform::Unshadow>();
  if (!disable_workgroup_init) {
    manager.Add<transform::ZeroInitWorkgroupMemory>();
  }
  manager.Add<transform::RemoveUnreachableStatements>();
  manager.Add<transform::SimplifyPointers>();  // Required for arrayLength()
  manager.Add<transform::FoldConstants>();
  manager.Add<transform::ExternalTextureTransform>();
  manager.Add<transform::VectorizeScalarMatrixConstructors>();
  manager.Add<transform::ForLoopToLoop>();  // Must come after
                                            // ZeroInitWorkgroupMemory
  manager.Add<transform::CanonicalizeEntryPointIO>();
  manager.Add<transform::AddEmptyEntryPoint>();
  manager.Add<transform::AddSpirvBlockAttribute>();
  manager.Add<transform::VarForDynamicIndex>();

  data.Add<transform::CanonicalizeEntryPointIO::Config>(
      transform::CanonicalizeEntryPointIO::Config(
          transform::CanonicalizeEntryPointIO::ShaderStyle::kSpirv, 0xFFFFFFFF,
          emit_vertex_point_size));

  SanitizedResult result;
  result.program = std::move(manager.Run(in, data).program);
  return result;
}

Builder::AccessorInfo::AccessorInfo() : source_id(0), source_type(nullptr) {}

Builder::AccessorInfo::~AccessorInfo() {}

Builder::Builder(const Program* program)
    : builder_(ProgramBuilder::Wrap(program)), scope_stack_({}) {}

Builder::~Builder() = default;

bool Builder::Build() {
  push_capability(SpvCapabilityShader);

  push_memory_model(spv::Op::OpMemoryModel,
                    {Operand::Int(SpvAddressingModelLogical),
                     Operand::Int(SpvMemoryModelGLSL450)});

  for (auto* var : builder_.AST().GlobalVariables()) {
    if (!GenerateGlobalVariable(var)) {
      return false;
    }
  }

  auto* mod = builder_.Sem().Module();
  for (auto* decl : mod->DependencyOrderedDeclarations()) {
    if (auto* func = decl->As<ast::Function>()) {
      if (!GenerateFunction(func)) {
        return false;
      }
    }
  }

  return true;
}

Operand Builder::result_op() {
  return Operand::Int(next_id());
}

uint32_t Builder::total_size() const {
  // The 5 covers the magic, version, generator, id bound and reserved.
  uint32_t size = 5;

  size += size_of(capabilities_);
  size += size_of(extensions_);
  size += size_of(ext_imports_);
  size += size_of(memory_model_);
  size += size_of(entry_points_);
  size += size_of(execution_modes_);
  size += size_of(debug_);
  size += size_of(annotations_);
  size += size_of(types_);
  for (const auto& func : functions_) {
    size += func.word_length();
  }

  return size;
}

void Builder::iterate(std::function<void(const Instruction&)> cb) const {
  for (const auto& inst : capabilities_) {
    cb(inst);
  }
  for (const auto& inst : extensions_) {
    cb(inst);
  }
  for (const auto& inst : ext_imports_) {
    cb(inst);
  }
  for (const auto& inst : memory_model_) {
    cb(inst);
  }
  for (const auto& inst : entry_points_) {
    cb(inst);
  }
  for (const auto& inst : execution_modes_) {
    cb(inst);
  }
  for (const auto& inst : debug_) {
    cb(inst);
  }
  for (const auto& inst : annotations_) {
    cb(inst);
  }
  for (const auto& inst : types_) {
    cb(inst);
  }
  for (const auto& func : functions_) {
    func.iterate(cb);
  }
}

void Builder::push_capability(uint32_t cap) {
  if (capability_set_.count(cap) == 0) {
    capability_set_.insert(cap);
    capabilities_.push_back(
        Instruction{spv::Op::OpCapability, {Operand::Int(cap)}});
  }
}

bool Builder::GenerateLabel(uint32_t id) {
  if (!push_function_inst(spv::Op::OpLabel, {Operand::Int(id)})) {
    return false;
  }
  current_label_id_ = id;
  return true;
}

bool Builder::GenerateAssignStatement(const ast::AssignmentStatement* assign) {
  if (assign->lhs->Is<ast::PhonyExpression>()) {
    auto rhs_id = GenerateExpression(assign->rhs);
    if (rhs_id == 0) {
      return false;
    }
    return true;
  } else {
    auto lhs_id = GenerateExpression(assign->lhs);
    if (lhs_id == 0) {
      return false;
    }
    auto rhs_id = GenerateExpressionWithLoadIfNeeded(assign->rhs);
    if (rhs_id == 0) {
      return false;
    }
    return GenerateStore(lhs_id, rhs_id);
  }
}

bool Builder::GenerateBreakStatement(const ast::BreakStatement*) {
  if (merge_stack_.empty()) {
    error_ = "Attempted to break without a merge block";
    return false;
  }
  if (!push_function_inst(spv::Op::OpBranch,
                          {Operand::Int(merge_stack_.back())})) {
    return false;
  }
  return true;
}

bool Builder::GenerateContinueStatement(const ast::ContinueStatement*) {
  if (continue_stack_.empty()) {
    error_ = "Attempted to continue without a continue block";
    return false;
  }
  if (!push_function_inst(spv::Op::OpBranch,
                          {Operand::Int(continue_stack_.back())})) {
    return false;
  }
  return true;
}

// TODO(dsinclair): This is generating an OpKill but the semantics of kill
// haven't been defined for WGSL yet. So, this may need to change.
// https://github.com/gpuweb/gpuweb/issues/676
bool Builder::GenerateDiscardStatement(const ast::DiscardStatement*) {
  if (!push_function_inst(spv::Op::OpKill, {})) {
    return false;
  }
  return true;
}

bool Builder::GenerateEntryPoint(const ast::Function* func, uint32_t id) {
  auto stage = pipeline_stage_to_execution_model(func->PipelineStage());
  if (stage == SpvExecutionModelMax) {
    error_ = "Unknown pipeline stage provided";
    return false;
  }

  OperandList operands = {
      Operand::Int(stage), Operand::Int(id),
      Operand::String(builder_.Symbols().NameFor(func->symbol))};

  auto* func_sem = builder_.Sem().Get(func);
  for (const auto* var : func_sem->TransitivelyReferencedGlobals()) {
    // For SPIR-V 1.3 we only output Input/output variables. If we update to
    // SPIR-V 1.4 or later this should be all variables.
    if (var->StorageClass() != ast::StorageClass::kInput &&
        var->StorageClass() != ast::StorageClass::kOutput) {
      continue;
    }

    uint32_t var_id = scope_stack_.Get(var->Declaration()->symbol);
    if (var_id == 0) {
      error_ = "unable to find ID for global variable: " +
               builder_.Symbols().NameFor(var->Declaration()->symbol);
      return false;
    }

    operands.push_back(Operand::Int(var_id));
  }
  push_entry_point(spv::Op::OpEntryPoint, operands);

  return true;
}

bool Builder::GenerateExecutionModes(const ast::Function* func, uint32_t id) {
  auto* func_sem = builder_.Sem().Get(func);

  // WGSL fragment shader origin is upper left
  if (func->PipelineStage() == ast::PipelineStage::kFragment) {
    push_execution_mode(
        spv::Op::OpExecutionMode,
        {Operand::Int(id), Operand::Int(SpvExecutionModeOriginUpperLeft)});
  } else if (func->PipelineStage() == ast::PipelineStage::kCompute) {
    auto& wgsize = func_sem->WorkgroupSize();

    // Check if the workgroup_size uses pipeline-overridable constants.
    if (wgsize[0].overridable_const || wgsize[1].overridable_const ||
        wgsize[2].overridable_const) {
      if (has_overridable_workgroup_size_) {
        // Only one stage can have a pipeline-overridable workgroup size.
        // TODO(crbug.com/tint/810): Use LocalSizeId to handle this scenario.
        TINT_ICE(Writer, builder_.Diagnostics())
            << "multiple stages using pipeline-overridable workgroup sizes";
      }
      has_overridable_workgroup_size_ = true;

      auto* vec3_u32 =
          builder_.create<sem::Vector>(builder_.create<sem::U32>(), 3);
      uint32_t vec3_u32_type_id = GenerateTypeIfNeeded(vec3_u32);
      if (vec3_u32_type_id == 0) {
        return 0;
      }

      OperandList wgsize_ops;
      auto wgsize_result = result_op();
      wgsize_ops.push_back(Operand::Int(vec3_u32_type_id));
      wgsize_ops.push_back(wgsize_result);

      // Generate OpConstant instructions for each dimension.
      for (int i = 0; i < 3; i++) {
        auto constant = ScalarConstant::U32(wgsize[i].value);
        if (wgsize[i].overridable_const) {
          // Make the constant specializable.
          auto* sem_const = builder_.Sem().Get<sem::GlobalVariable>(
              wgsize[i].overridable_const);
          if (!sem_const->IsOverridable()) {
            TINT_ICE(Writer, builder_.Diagnostics())
                << "expected a pipeline-overridable constant";
          }
          constant.is_spec_op = true;
          constant.constant_id = sem_const->ConstantId();
        }

        auto result = GenerateConstantIfNeeded(constant);
        wgsize_ops.push_back(Operand::Int(result));
      }

      // Generate the WorkgroupSize builtin.
      push_type(spv::Op::OpSpecConstantComposite, wgsize_ops);
      push_annot(spv::Op::OpDecorate,
                 {wgsize_result, Operand::Int(SpvDecorationBuiltIn),
                  Operand::Int(SpvBuiltInWorkgroupSize)});
    } else {
      // Not overridable, so just use OpExecutionMode LocalSize.
      uint32_t x = wgsize[0].value;
      uint32_t y = wgsize[1].value;
      uint32_t z = wgsize[2].value;
      push_execution_mode(
          spv::Op::OpExecutionMode,
          {Operand::Int(id), Operand::Int(SpvExecutionModeLocalSize),
           Operand::Int(x), Operand::Int(y), Operand::Int(z)});
    }
  }

  for (auto builtin : func_sem->TransitivelyReferencedBuiltinVariables()) {
    if (builtin.second->builtin == ast::Builtin::kFragDepth) {
      push_execution_mode(
          spv::Op::OpExecutionMode,
          {Operand::Int(id), Operand::Int(SpvExecutionModeDepthReplacing)});
    }
  }

  return true;
}

uint32_t Builder::GenerateExpression(const ast::Expression* expr) {
  return Switch(
      expr,
      [&](const ast::IndexAccessorExpression* a) {  //
        return GenerateAccessorExpression(a);
      },
      [&](const ast::BinaryExpression* b) {  //
        return GenerateBinaryExpression(b);
      },
      [&](const ast::BitcastExpression* b) {  //
        return GenerateBitcastExpression(b);
      },
      [&](const ast::CallExpression* c) {  //
        return GenerateCallExpression(c);
      },
      [&](const ast::IdentifierExpression* i) {  //
        return GenerateIdentifierExpression(i);
      },
      [&](const ast::LiteralExpression* l) {  //
        return GenerateLiteralIfNeeded(nullptr, l);
      },
      [&](const ast::MemberAccessorExpression* m) {  //
        return GenerateAccessorExpression(m);
      },
      [&](const ast::UnaryOpExpression* u) {  //
        return GenerateUnaryOpExpression(u);
      },
      [&](Default) -> uint32_t {
        error_ =
            "unknown expression type: " + std::string(expr->TypeInfo().name);
        return 0;
      });
}

bool Builder::GenerateFunction(const ast::Function* func_ast) {
  auto* func = builder_.Sem().Get(func_ast);

  uint32_t func_type_id = GenerateFunctionTypeIfNeeded(func);
  if (func_type_id == 0) {
    return false;
  }

  auto func_op = result_op();
  auto func_id = func_op.to_i();

  push_debug(spv::Op::OpName,
             {Operand::Int(func_id),
              Operand::String(builder_.Symbols().NameFor(func_ast->symbol))});

  auto ret_id = GenerateTypeIfNeeded(func->ReturnType());
  if (ret_id == 0) {
    return false;
  }

  scope_stack_.Push();
  TINT_DEFER(scope_stack_.Pop());

  auto definition_inst = Instruction{
      spv::Op::OpFunction,
      {Operand::Int(ret_id), func_op, Operand::Int(SpvFunctionControlMaskNone),
       Operand::Int(func_type_id)}};

  InstructionList params;
  for (auto* param : func->Parameters()) {
    auto param_op = result_op();
    auto param_id = param_op.to_i();

    auto param_type_id = GenerateTypeIfNeeded(param->Type());
    if (param_type_id == 0) {
      return false;
    }

    push_debug(spv::Op::OpName, {Operand::Int(param_id),
                                 Operand::String(builder_.Symbols().NameFor(
                                     param->Declaration()->symbol))});
    params.push_back(Instruction{spv::Op::OpFunctionParameter,
                                 {Operand::Int(param_type_id), param_op}});

    scope_stack_.Set(param->Declaration()->symbol, param_id);
  }

  push_function(Function{definition_inst, result_op(), std::move(params)});

  for (auto* stmt : func_ast->body->statements) {
    if (!GenerateStatement(stmt)) {
      return false;
    }
  }

  if (InsideBasicBlock()) {
    if (func->ReturnType()->Is<sem::Void>()) {
      push_function_inst(spv::Op::OpReturn, {});
    } else {
      auto zero = GenerateConstantNullIfNeeded(func->ReturnType());
      push_function_inst(spv::Op::OpReturnValue, {Operand::Int(zero)});
    }
  }

  if (func_ast->IsEntryPoint()) {
    if (!GenerateEntryPoint(func_ast, func_id)) {
      return false;
    }
    if (!GenerateExecutionModes(func_ast, func_id)) {
      return false;
    }
  }

  func_symbol_to_id_[func_ast->symbol] = func_id;

  return true;
}

uint32_t Builder::GenerateFunctionTypeIfNeeded(const sem::Function* func) {
  return utils::GetOrCreate(
      func_sig_to_id_, func->Signature(), [&]() -> uint32_t {
        auto func_op = result_op();
        auto func_type_id = func_op.to_i();

        auto ret_id = GenerateTypeIfNeeded(func->ReturnType());
        if (ret_id == 0) {
          return 0;
        }

        OperandList ops = {func_op, Operand::Int(ret_id)};
        for (auto* param : func->Parameters()) {
          auto param_type_id = GenerateTypeIfNeeded(param->Type());
          if (param_type_id == 0) {
            return 0;
          }
          ops.push_back(Operand::Int(param_type_id));
        }

        push_type(spv::Op::OpTypeFunction, std::move(ops));
        return func_type_id;
      });
}

bool Builder::GenerateFunctionVariable(const ast::Variable* var) {
  uint32_t init_id = 0;
  if (var->constructor) {
    init_id = GenerateExpressionWithLoadIfNeeded(var->constructor);
    if (init_id == 0) {
      return false;
    }
  }

  if (var->is_const) {
    if (!var->constructor) {
      error_ = "missing constructor for constant";
      return false;
    }
    scope_stack_.Set(var->symbol, init_id);
    spirv_id_to_variable_[init_id] = var;
    return true;
  }

  auto result = result_op();
  auto var_id = result.to_i();
  auto sc = ast::StorageClass::kFunction;
  auto* type = builder_.Sem().Get(var)->Type();
  auto type_id = GenerateTypeIfNeeded(type);
  if (type_id == 0) {
    return false;
  }

  push_debug(spv::Op::OpName,
             {Operand::Int(var_id),
              Operand::String(builder_.Symbols().NameFor(var->symbol))});

  // TODO(dsinclair) We could detect if the constructor is fully const and emit
  // an initializer value for the variable instead of doing the OpLoad.
  auto null_id = GenerateConstantNullIfNeeded(type->UnwrapRef());
  if (null_id == 0) {
    return 0;
  }
  push_function_var({Operand::Int(type_id), result,
                     Operand::Int(ConvertStorageClass(sc)),
                     Operand::Int(null_id)});

  if (var->constructor) {
    if (!GenerateStore(var_id, init_id)) {
      return false;
    }
  }

  scope_stack_.Set(var->symbol, var_id);
  spirv_id_to_variable_[var_id] = var;

  return true;
}

bool Builder::GenerateStore(uint32_t to, uint32_t from) {
  return push_function_inst(spv::Op::OpStore,
                            {Operand::Int(to), Operand::Int(from)});
}

bool Builder::GenerateGlobalVariable(const ast::Variable* var) {
  auto* sem = builder_.Sem().Get(var);
  auto* type = sem->Type()->UnwrapRef();

  uint32_t init_id = 0;
  if (var->constructor) {
    init_id = GenerateConstructorExpression(var, var->constructor);
    if (init_id == 0) {
      return false;
    }
  }

  if (var->is_const) {
    if (!var->constructor) {
      // Constants must have an initializer unless they have an override
      // attribute.
      if (!ast::HasAttribute<ast::OverrideAttribute>(var->attributes)) {
        error_ = "missing constructor for constant";
        return false;
      }

      // SPIR-V requires specialization constants to have initializers.
      if (type->Is<sem::F32>()) {
        ast::FloatLiteralExpression l(ProgramID(), Source{}, 0.0f);
        init_id = GenerateLiteralIfNeeded(var, &l);
      } else if (type->Is<sem::U32>()) {
        ast::UintLiteralExpression l(ProgramID(), Source{}, 0);
        init_id = GenerateLiteralIfNeeded(var, &l);
      } else if (type->Is<sem::I32>()) {
        ast::SintLiteralExpression l(ProgramID(), Source{}, 0);
        init_id = GenerateLiteralIfNeeded(var, &l);
      } else if (type->Is<sem::Bool>()) {
        ast::BoolLiteralExpression l(ProgramID(), Source{}, false);
        init_id = GenerateLiteralIfNeeded(var, &l);
      } else {
        error_ = "invalid type for pipeline constant ID, must be scalar";
        return false;
      }
      if (init_id == 0) {
        return 0;
      }
    }
    push_debug(spv::Op::OpName,
               {Operand::Int(init_id),
                Operand::String(builder_.Symbols().NameFor(var->symbol))});

    scope_stack_.Set(var->symbol, init_id);
    spirv_id_to_variable_[init_id] = var;
    return true;
  }

  auto result = result_op();
  auto var_id = result.to_i();

  auto sc = sem->StorageClass() == ast::StorageClass::kNone
                ? ast::StorageClass::kPrivate
                : sem->StorageClass();

  auto type_id = GenerateTypeIfNeeded(sem->Type());
  if (type_id == 0) {
    return false;
  }

  push_debug(spv::Op::OpName,
             {Operand::Int(var_id),
              Operand::String(builder_.Symbols().NameFor(var->symbol))});

  OperandList ops = {Operand::Int(type_id), result,
                     Operand::Int(ConvertStorageClass(sc))};

  if (var->constructor) {
    ops.push_back(Operand::Int(init_id));
  } else {
    auto* st = type->As<sem::StorageTexture>();
    if (st || type->Is<sem::Struct>()) {
      // type is a sem::Struct or a sem::StorageTexture
      auto access = st ? st->access() : sem->Access();
      switch (access) {
        case ast::Access::kWrite:
          push_annot(
              spv::Op::OpDecorate,
              {Operand::Int(var_id), Operand::Int(SpvDecorationNonReadable)});
          break;
        case ast::Access::kRead:
          push_annot(
              spv::Op::OpDecorate,
              {Operand::Int(var_id), Operand::Int(SpvDecorationNonWritable)});
          break;
        case ast::Access::kUndefined:
        case ast::Access::kReadWrite:
          break;
      }
    }
    if (!type->Is<sem::Sampler>()) {
      // If we don't have a constructor and we're an Output or Private
      // variable, then WGSL requires that we zero-initialize.
      if (sem->StorageClass() == ast::StorageClass::kPrivate ||
          sem->StorageClass() == ast::StorageClass::kOutput) {
        init_id = GenerateConstantNullIfNeeded(type);
        if (init_id == 0) {
          return 0;
        }
        ops.push_back(Operand::Int(init_id));
      }
    }
  }

  push_type(spv::Op::OpVariable, std::move(ops));

  for (auto* attr : var->attributes) {
    bool ok = Switch(
        attr,
        [&](const ast::BuiltinAttribute* builtin) {
          push_annot(spv::Op::OpDecorate,
                     {Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
                      Operand::Int(ConvertBuiltin(builtin->builtin,
                                                  sem->StorageClass()))});
          return true;
        },
        [&](const ast::LocationAttribute* location) {
          push_annot(spv::Op::OpDecorate,
                     {Operand::Int(var_id), Operand::Int(SpvDecorationLocation),
                      Operand::Int(location->value)});
          return true;
        },
        [&](const ast::InterpolateAttribute* interpolate) {
          AddInterpolationDecorations(var_id, interpolate->type,
                                      interpolate->sampling);
          return true;
        },
        [&](const ast::InvariantAttribute*) {
          push_annot(
              spv::Op::OpDecorate,
              {Operand::Int(var_id), Operand::Int(SpvDecorationInvariant)});
          return true;
        },
        [&](const ast::BindingAttribute* binding) {
          push_annot(spv::Op::OpDecorate,
                     {Operand::Int(var_id), Operand::Int(SpvDecorationBinding),
                      Operand::Int(binding->value)});
          return true;
        },
        [&](const ast::GroupAttribute* group) {
          push_annot(
              spv::Op::OpDecorate,
              {Operand::Int(var_id), Operand::Int(SpvDecorationDescriptorSet),
               Operand::Int(group->value)});
          return true;
        },
        [&](const ast::OverrideAttribute*) {
          return true;  // Spec constants are handled elsewhere
        },
        [&](const ast::InternalAttribute*) {
          return true;  // ignored
        },
        [&](Default) {
          error_ = "unknown attribute";
          return false;
        });
    if (!ok) {
      return false;
    }
  }

  scope_stack_.Set(var->symbol, var_id);
  spirv_id_to_variable_[var_id] = var;
  return true;
}

bool Builder::GenerateIndexAccessor(const ast::IndexAccessorExpression* expr,
                                    AccessorInfo* info) {
  auto idx_id = GenerateExpressionWithLoadIfNeeded(expr->index);
  if (idx_id == 0) {
    return 0;
  }

  // If the source is a reference, we access chain into it.
  // In the future, pointers may support access-chaining.
  // See https://github.com/gpuweb/gpuweb/pull/1580
  if (info->source_type->Is<sem::Reference>()) {
    info->access_chain_indices.push_back(idx_id);
    info->source_type = TypeOf(expr);
    return true;
  }

  auto result_type_id = GenerateTypeIfNeeded(TypeOf(expr));
  if (result_type_id == 0) {
    return false;
  }

  // We don't have a pointer, so we can just directly extract the value.
  auto extract = result_op();
  auto extract_id = extract.to_i();

  // If the index is compile-time constant, we use OpCompositeExtract.
  auto* idx = builder_.Sem().Get(expr->index);
  if (auto idx_constval = idx->ConstantValue()) {
    if (!push_function_inst(
            spv::Op::OpCompositeExtract,
            {
                Operand::Int(result_type_id),
                extract,
                Operand::Int(info->source_id),
                Operand::Int(idx_constval.ElementAs<uint32_t>(0)),
            })) {
      return false;
    }

    info->source_id = extract_id;
    info->source_type = TypeOf(expr);

    return true;
  }

  // If the source is a vector, we use OpVectorExtractDynamic.
  if (info->source_type->Is<sem::Vector>()) {
    if (!push_function_inst(
            spv::Op::OpVectorExtractDynamic,
            {Operand::Int(result_type_id), extract,
             Operand::Int(info->source_id), Operand::Int(idx_id)})) {
      return false;
    }

    info->source_id = extract_id;
    info->source_type = TypeOf(expr);

    return true;
  }

  TINT_ICE(Writer, builder_.Diagnostics())
      << "unsupported index accessor expression";
  return false;
}

bool Builder::GenerateMemberAccessor(const ast::MemberAccessorExpression* expr,
                                     AccessorInfo* info) {
  auto* expr_sem = builder_.Sem().Get(expr);
  auto* expr_type = expr_sem->Type();

  if (auto* access = expr_sem->As<sem::StructMemberAccess>()) {
    uint32_t idx = access->Member()->Index();

    if (info->source_type->Is<sem::Reference>()) {
      auto idx_id = GenerateConstantIfNeeded(ScalarConstant::U32(idx));
      if (idx_id == 0) {
        return 0;
      }
      info->access_chain_indices.push_back(idx_id);
      info->source_type = expr_type;
    } else {
      auto result_type_id = GenerateTypeIfNeeded(expr_type);
      if (result_type_id == 0) {
        return false;
      }

      auto extract = result_op();
      auto extract_id = extract.to_i();
      if (!push_function_inst(
              spv::Op::OpCompositeExtract,
              {Operand::Int(result_type_id), extract,
               Operand::Int(info->source_id), Operand::Int(idx)})) {
        return false;
      }

      info->source_id = extract_id;
      info->source_type = expr_type;
    }

    return true;
  }

  if (auto* swizzle = expr_sem->As<sem::Swizzle>()) {
    // Single element swizzle is either an access chain or a composite extract
    auto& indices = swizzle->Indices();
    if (indices.size() == 1) {
      if (info->source_type->Is<sem::Reference>()) {
        auto idx_id = GenerateConstantIfNeeded(ScalarConstant::U32(indices[0]));
        if (idx_id == 0) {
          return 0;
        }
        info->access_chain_indices.push_back(idx_id);
      } else {
        auto result_type_id = GenerateTypeIfNeeded(expr_type);
        if (result_type_id == 0) {
          return 0;
        }

        auto extract = result_op();
        auto extract_id = extract.to_i();
        if (!push_function_inst(
                spv::Op::OpCompositeExtract,
                {Operand::Int(result_type_id), extract,
                 Operand::Int(info->source_id), Operand::Int(indices[0])})) {
          return false;
        }

        info->source_id = extract_id;
        info->source_type = expr_type;
      }
      return true;
    }

    // Store the type away as it may change if we run the access chain
    auto* incoming_type = info->source_type;

    // Multi-item extract is a VectorShuffle. We have to emit any existing
    // access chain data, then load the access chain and shuffle that.
    if (!info->access_chain_indices.empty()) {
      auto result_type_id = GenerateTypeIfNeeded(info->source_type);
      if (result_type_id == 0) {
        return 0;
      }
      auto extract = result_op();
      auto extract_id = extract.to_i();

      OperandList ops = {Operand::Int(result_type_id), extract,
                         Operand::Int(info->source_id)};
      for (auto id : info->access_chain_indices) {
        ops.push_back(Operand::Int(id));
      }

      if (!push_function_inst(spv::Op::OpAccessChain, ops)) {
        return false;
      }

      info->source_id = GenerateLoadIfNeeded(expr_type, extract_id);
      info->source_type = expr_type->UnwrapRef();
      info->access_chain_indices.clear();
    }

    auto result_type_id = GenerateTypeIfNeeded(expr_type);
    if (result_type_id == 0) {
      return false;
    }

    auto vec_id = GenerateLoadIfNeeded(incoming_type, info->source_id);

    auto result = result_op();
    auto result_id = result.to_i();

    OperandList ops = {Operand::Int(result_type_id), result,
                       Operand::Int(vec_id), Operand::Int(vec_id)};

    for (auto idx : indices) {
      ops.push_back(Operand::Int(idx));
    }

    if (!push_function_inst(spv::Op::OpVectorShuffle, ops)) {
      return false;
    }
    info->source_id = result_id;
    info->source_type = expr_type;
    return true;
  }

  TINT_ICE(Writer, builder_.Diagnostics())
      << "unhandled member index type: " << expr_sem->TypeInfo().name;
  return false;
}

uint32_t Builder::GenerateAccessorExpression(const ast::Expression* expr) {
  if (!expr->IsAnyOf<ast::IndexAccessorExpression,
                     ast::MemberAccessorExpression>()) {
    TINT_ICE(Writer, builder_.Diagnostics()) << "expression is not an accessor";
    return 0;
  }

  // Gather a list of all the member and index accessors that are in this chain.
  // The list is built in reverse order as that's the order we need to access
  // the chain.
  std::vector<const ast::Expression*> accessors;
  const ast::Expression* source = expr;
  while (true) {
    if (auto* array = source->As<ast::IndexAccessorExpression>()) {
      accessors.insert(accessors.begin(), source);
      source = array->object;
    } else if (auto* member = source->As<ast::MemberAccessorExpression>()) {
      accessors.insert(accessors.begin(), source);
      source = member->structure;
    } else {
      break;
    }
  }

  AccessorInfo info;
  info.source_id = GenerateExpression(source);
  if (info.source_id == 0) {
    return 0;
  }
  info.source_type = TypeOf(source);

  // Note: Dynamic index on array and matrix values (lets) should have been
  // promoted to storage with the VarForDynamicIndex transform.

  for (auto* accessor : accessors) {
    bool ok = Switch(
        accessor,
        [&](const ast::IndexAccessorExpression* array) {
          return GenerateIndexAccessor(array, &info);
        },
        [&](const ast::MemberAccessorExpression* member) {
          return GenerateMemberAccessor(member, &info);
        },
        [&](Default) {
          error_ = "invalid accessor in list: " +
                   std::string(accessor->TypeInfo().name);
          return false;
        });
    if (!ok) {
      return false;
    }
  }

  if (!info.access_chain_indices.empty()) {
    auto* type = TypeOf(expr);
    auto result_type_id = GenerateTypeIfNeeded(type);
    if (result_type_id == 0) {
      return 0;
    }

    auto result = result_op();
    auto result_id = result.to_i();

    OperandList ops = {Operand::Int(result_type_id), result,
                       Operand::Int(info.source_id)};
    for (auto id : info.access_chain_indices) {
      ops.push_back(Operand::Int(id));
    }

    if (!push_function_inst(spv::Op::OpAccessChain, ops)) {
      return false;
    }
    info.source_id = result_id;
  }

  return info.source_id;
}

uint32_t Builder::GenerateIdentifierExpression(
    const ast::IdentifierExpression* expr) {
  uint32_t val = scope_stack_.Get(expr->symbol);
  if (val == 0) {
    error_ = "unable to find variable with identifier: " +
             builder_.Symbols().NameFor(expr->symbol);
  }
  return val;
}

uint32_t Builder::GenerateExpressionWithLoadIfNeeded(
    const sem::Expression* expr) {
  // The semantic node directly knows both the AST node and the resolved type.
  if (const auto id = GenerateExpression(expr->Declaration())) {
    return GenerateLoadIfNeeded(expr->Type(), id);
  }
  return 0;
}

uint32_t Builder::GenerateExpressionWithLoadIfNeeded(
    const ast::Expression* expr) {
  if (const auto id = GenerateExpression(expr)) {
    // Perform a lookup to get the resolved type.
    return GenerateLoadIfNeeded(TypeOf(expr), id);
  }
  return 0;
}

uint32_t Builder::GenerateLoadIfNeeded(const sem::Type* type, uint32_t id) {
  if (auto* ref = type->As<sem::Reference>()) {
    type = ref->StoreType();
  } else {
    return id;
  }

  auto type_id = GenerateTypeIfNeeded(type);
  auto result = result_op();
  auto result_id = result.to_i();
  if (!push_function_inst(spv::Op::OpLoad,
                          {Operand::Int(type_id), result, Operand::Int(id)})) {
    return 0;
  }
  return result_id;
}

uint32_t Builder::GenerateUnaryOpExpression(
    const ast::UnaryOpExpression* expr) {
  auto result = result_op();
  auto result_id = result.to_i();

  spv::Op op = spv::Op::OpNop;
  switch (expr->op) {
    case ast::UnaryOp::kComplement:
      op = spv::Op::OpNot;
      break;
    case ast::UnaryOp::kNegation:
      if (TypeOf(expr)->is_float_scalar_or_vector()) {
        op = spv::Op::OpFNegate;
      } else {
        op = spv::Op::OpSNegate;
      }
      break;
    case ast::UnaryOp::kNot:
      op = spv::Op::OpLogicalNot;
      break;
    case ast::UnaryOp::kAddressOf:
    case ast::UnaryOp::kIndirection:
      // Address-of converts a reference to a pointer, and dereference converts
      // a pointer to a reference. These are the same thing in SPIR-V, so this
      // is a no-op.
      return GenerateExpression(expr->expr);
  }

  auto val_id = GenerateExpressionWithLoadIfNeeded(expr->expr);
  if (val_id == 0) {
    return 0;
  }

  auto type_id = GenerateTypeIfNeeded(TypeOf(expr));
  if (type_id == 0) {
    return 0;
  }

  if (!push_function_inst(
          op, {Operand::Int(type_id), result, Operand::Int(val_id)})) {
    return false;
  }

  return result_id;
}

uint32_t Builder::GetGLSLstd450Import() {
  auto where = import_name_to_id_.find(kGLSLstd450);
  if (where != import_name_to_id_.end()) {
    return where->second;
  }

  // It doesn't exist yet. Generate it.
  auto result = result_op();
  auto id = result.to_i();

  push_ext_import(spv::Op::OpExtInstImport,
                  {result, Operand::String(kGLSLstd450)});

  // Remember it for later.
  import_name_to_id_[kGLSLstd450] = id;
  return id;
}

uint32_t Builder::GenerateConstructorExpression(const ast::Variable* var,
                                                const ast::Expression* expr) {
  if (auto* literal = expr->As<ast::LiteralExpression>()) {
    return GenerateLiteralIfNeeded(var, literal);
  }
  if (auto* call = builder_.Sem().Get<sem::Call>(expr)) {
    if (call->Target()->IsAnyOf<sem::TypeConstructor, sem::TypeConversion>()) {
      return GenerateTypeConstructorOrConversion(call, var);
    }
  }
  error_ = "unknown constructor expression";
  return 0;
}

bool Builder::IsConstructorConst(const ast::Expression* expr) {
  bool is_const = true;
  ast::TraverseExpressions(expr, builder_.Diagnostics(),
                           [&](const ast::Expression* e) {
                             if (e->Is<ast::LiteralExpression>()) {
                               return ast::TraverseAction::Descend;
                             }
                             if (auto* ce = e->As<ast::CallExpression>()) {
                               auto* call = builder_.Sem().Get(ce);
                               if (call->Target()->Is<sem::TypeConstructor>()) {
                                 return ast::TraverseAction::Descend;
                               }
                             }

                             is_const = false;
                             return ast::TraverseAction::Stop;
                           });
  return is_const;
}

uint32_t Builder::GenerateTypeConstructorOrConversion(
    const sem::Call* call,
    const ast::Variable* var) {
  auto& args = call->Arguments();
  auto* global_var = builder_.Sem().Get<sem::GlobalVariable>(var);
  auto* result_type = call->Type();

  // Generate the zero initializer if there are no values provided.
  if (args.empty()) {
    if (global_var && global_var->IsOverridable()) {
      auto constant_id = global_var->ConstantId();
      if (result_type->Is<sem::I32>()) {
        return GenerateConstantIfNeeded(
            ScalarConstant::I32(0).AsSpecOp(constant_id));
      }
      if (result_type->Is<sem::U32>()) {
        return GenerateConstantIfNeeded(
            ScalarConstant::U32(0).AsSpecOp(constant_id));
      }
      if (result_type->Is<sem::F32>()) {
        return GenerateConstantIfNeeded(
            ScalarConstant::F32(0).AsSpecOp(constant_id));
      }
      if (result_type->Is<sem::Bool>()) {
        return GenerateConstantIfNeeded(
            ScalarConstant::Bool(false).AsSpecOp(constant_id));
      }
    }
    return GenerateConstantNullIfNeeded(result_type->UnwrapRef());
  }

  std::ostringstream out;
  out << "__const_" << result_type->FriendlyName(builder_.Symbols()) << "_";

  result_type = result_type->UnwrapRef();
  bool constructor_is_const = IsConstructorConst(call->Declaration());
  if (has_error()) {
    return 0;
  }

  bool can_cast_or_copy = result_type->is_scalar();

  if (auto* res_vec = result_type->As<sem::Vector>()) {
    if (res_vec->type()->is_scalar()) {
      auto* value_type = args[0]->Type()->UnwrapRef();
      if (auto* val_vec = value_type->As<sem::Vector>()) {
        if (val_vec->type()->is_scalar()) {
          can_cast_or_copy = res_vec->Width() == val_vec->Width();
        }
      }
    }
  }

  if (can_cast_or_copy) {
    return GenerateCastOrCopyOrPassthrough(result_type, args[0]->Declaration(),
                                           global_var);
  }

  auto type_id = GenerateTypeIfNeeded(result_type);
  if (type_id == 0) {
    return 0;
  }

  bool result_is_constant_composite = constructor_is_const;
  bool result_is_spec_composite = false;

  if (auto* vec = result_type->As<sem::Vector>()) {
    result_type = vec->type();
  }

  OperandList ops;
  for (auto* e : args) {
    uint32_t id = 0;
    id = GenerateExpressionWithLoadIfNeeded(e);
    if (id == 0) {
      return 0;
    }

    auto* value_type = e->Type()->UnwrapRef();
    // If the result and value types are the same we can just use the object.
    // If the result is not a vector then we should have validated that the
    // value type is a correctly sized vector so we can just use it directly.
    if (result_type == value_type || result_type->Is<sem::Matrix>() ||
        result_type->Is<sem::Array>() || result_type->Is<sem::Struct>()) {
      out << "_" << id;

      ops.push_back(Operand::Int(id));
      continue;
    }

    // Both scalars, but not the same type so we need to generate a conversion
    // of the value.
    if (value_type->is_scalar() && result_type->is_scalar()) {
      id = GenerateCastOrCopyOrPassthrough(result_type, args[0]->Declaration(),
                                           global_var);
      out << "_" << id;
      ops.push_back(Operand::Int(id));
      continue;
    }

    // When handling vectors as the values there a few cases to take into
    // consideration:
    //  1. Module scoped vec3<f32>(vec2<f32>(1, 2), 3)  -> OpSpecConstantOp
    //  2. Function scoped vec3<f32>(vec2<f32>(1, 2), 3) ->  OpCompositeExtract
    //  3. Either array<vec3<f32>, 1>(vec3<f32>(1, 2, 3))  -> use the ID.
    //       -> handled above
    //
    // For cases 1 and 2, if the type is different we also may need to insert
    // a type cast.
    if (auto* vec = value_type->As<sem::Vector>()) {
      auto* vec_type = vec->type();

      auto value_type_id = GenerateTypeIfNeeded(vec_type);
      if (value_type_id == 0) {
        return 0;
      }

      for (uint32_t i = 0; i < vec->Width(); ++i) {
        auto extract = result_op();
        auto extract_id = extract.to_i();

        if (!global_var) {
          // A non-global initializer. Case 2.
          if (!push_function_inst(spv::Op::OpCompositeExtract,
                                  {Operand::Int(value_type_id), extract,
                                   Operand::Int(id), Operand::Int(i)})) {
            return false;
          }

          // We no longer have a constant composite, but have to do a
          // composite construction as these calls are inside a function.
          result_is_constant_composite = false;
        } else {
          // A global initializer, must use OpSpecConstantOp. Case 1.
          auto idx_id = GenerateConstantIfNeeded(ScalarConstant::U32(i));
          if (idx_id == 0) {
            return 0;
          }
          push_type(spv::Op::OpSpecConstantOp,
                    {Operand::Int(value_type_id), extract,
                     Operand::Int(SpvOpCompositeExtract), Operand::Int(id),
                     Operand::Int(idx_id)});

          result_is_spec_composite = true;
        }

        out << "_" << extract_id;
        ops.push_back(Operand::Int(extract_id));
      }
    } else {
      error_ = "Unhandled type cast value type";
      return 0;
    }
  }

  // For a single-value vector initializer, splat the initializer value.
  auto* const init_result_type = call->Type()->UnwrapRef();
  if (args.size() == 1 && init_result_type->is_scalar_vector() &&
      args[0]->Type()->UnwrapRef()->is_scalar()) {
    size_t vec_size = init_result_type->As<sem::Vector>()->Width();
    for (size_t i = 0; i < (vec_size - 1); ++i) {
      ops.push_back(ops[0]);
    }
  }

  auto str = out.str();
  auto val = type_constructor_to_id_.find(str);
  if (val != type_constructor_to_id_.end()) {
    return val->second;
  }

  auto result = result_op();
  ops.insert(ops.begin(), result);
  ops.insert(ops.begin(), Operand::Int(type_id));

  type_constructor_to_id_[str] = result.to_i();

  if (result_is_spec_composite) {
    push_type(spv::Op::OpSpecConstantComposite, ops);
  } else if (result_is_constant_composite) {
    push_type(spv::Op::OpConstantComposite, ops);
  } else {
    if (!push_function_inst(spv::Op::OpCompositeConstruct, ops)) {
      return 0;
    }
  }

  return result.to_i();
}

uint32_t Builder::GenerateCastOrCopyOrPassthrough(
    const sem::Type* to_type,
    const ast::Expression* from_expr,
    bool is_global_init) {
  // This should not happen as we rely on constant folding to obviate
  // casts/conversions for module-scope variables
  if (is_global_init) {
    TINT_ICE(Writer, builder_.Diagnostics())
        << "Module-level conversions are not supported. Conversions should "
           "have already been constant-folded by the FoldConstants transform.";
    return 0;
  }

  auto elem_type_of = [](const sem::Type* t) -> const sem::Type* {
    if (t->is_scalar()) {
      return t;
    }
    if (auto* v = t->As<sem::Vector>()) {
      return v->type();
    }
    return nullptr;
  };

  auto result = result_op();
  auto result_id = result.to_i();

  auto result_type_id = GenerateTypeIfNeeded(to_type);
  if (result_type_id == 0) {
    return 0;
  }

  auto val_id = GenerateExpressionWithLoadIfNeeded(from_expr);
  if (val_id == 0) {
    return 0;
  }

  auto* from_type = TypeOf(from_expr)->UnwrapRef();

  spv::Op op = spv::Op::OpNop;
  if ((from_type->Is<sem::I32>() && to_type->Is<sem::F32>()) ||
      (from_type->is_signed_integer_vector() && to_type->is_float_vector())) {
    op = spv::Op::OpConvertSToF;
  } else if ((from_type->Is<sem::U32>() && to_type->Is<sem::F32>()) ||
             (from_type->is_unsigned_integer_vector() &&
              to_type->is_float_vector())) {
    op = spv::Op::OpConvertUToF;
  } else if ((from_type->Is<sem::F32>() && to_type->Is<sem::I32>()) ||
             (from_type->is_float_vector() &&
              to_type->is_signed_integer_vector())) {
    op = spv::Op::OpConvertFToS;
  } else if ((from_type->Is<sem::F32>() && to_type->Is<sem::U32>()) ||
             (from_type->is_float_vector() &&
              to_type->is_unsigned_integer_vector())) {
    op = spv::Op::OpConvertFToU;
  } else if ((from_type->Is<sem::Bool>() && to_type->Is<sem::Bool>()) ||
             (from_type->Is<sem::U32>() && to_type->Is<sem::U32>()) ||
             (from_type->Is<sem::I32>() && to_type->Is<sem::I32>()) ||
             (from_type->Is<sem::F32>() && to_type->Is<sem::F32>()) ||
             (from_type->Is<sem::Vector>() && (from_type == to_type))) {
    return val_id;
  } else if ((from_type->Is<sem::I32>() && to_type->Is<sem::U32>()) ||
             (from_type->Is<sem::U32>() && to_type->Is<sem::I32>()) ||
             (from_type->is_signed_integer_vector() &&
              to_type->is_unsigned_integer_vector()) ||
             (from_type->is_unsigned_integer_vector() &&
              to_type->is_integer_scalar_or_vector())) {
    op = spv::Op::OpBitcast;
  } else if ((from_type->is_numeric_scalar() && to_type->Is<sem::Bool>()) ||
             (from_type->is_numeric_vector() && to_type->is_bool_vector())) {
    // Convert scalar (vector) to bool (vector)

    // Return the result of comparing from_expr with zero
    uint32_t zero = GenerateConstantNullIfNeeded(from_type);
    const auto* from_elem_type = elem_type_of(from_type);
    op = from_elem_type->is_integer_scalar() ? spv::Op::OpINotEqual
                                             : spv::Op::OpFUnordNotEqual;
    if (!push_function_inst(
            op, {Operand::Int(result_type_id), Operand::Int(result_id),
                 Operand::Int(val_id), Operand::Int(zero)})) {
      return 0;
    }

    return result_id;
  } else if (from_type->is_bool_scalar_or_vector() &&
             to_type->is_numeric_scalar_or_vector()) {
    // Convert bool scalar/vector to numeric scalar/vector.
    // Use the bool to select between 1 (if true) and 0 (if false).

    const auto* to_elem_type = elem_type_of(to_type);
    uint32_t one_id;
    uint32_t zero_id;
    if (to_elem_type->Is<sem::F32>()) {
      ast::FloatLiteralExpression one(ProgramID(), Source{}, 1.0f);
      ast::FloatLiteralExpression zero(ProgramID(), Source{}, 0.0f);
      one_id = GenerateLiteralIfNeeded(nullptr, &one);
      zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
    } else if (to_elem_type->Is<sem::U32>()) {
      ast::UintLiteralExpression one(ProgramID(), Source{}, 1);
      ast::UintLiteralExpression zero(ProgramID(), Source{}, 0);
      one_id = GenerateLiteralIfNeeded(nullptr, &one);
      zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
    } else if (to_elem_type->Is<sem::I32>()) {
      ast::SintLiteralExpression one(ProgramID(), Source{}, 1);
      ast::SintLiteralExpression zero(ProgramID(), Source{}, 0);
      one_id = GenerateLiteralIfNeeded(nullptr, &one);
      zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
    } else {
      error_ = "invalid destination type for bool conversion";
      return false;
    }
    if (auto* to_vec = to_type->As<sem::Vector>()) {
      // Splat the scalars into vectors.
      one_id = GenerateConstantVectorSplatIfNeeded(to_vec, one_id);
      zero_id = GenerateConstantVectorSplatIfNeeded(to_vec, zero_id);
    }
    if (!one_id || !zero_id) {
      return false;
    }

    op = spv::Op::OpSelect;
    if (!push_function_inst(
            op, {Operand::Int(result_type_id), Operand::Int(result_id),
                 Operand::Int(val_id), Operand::Int(one_id),
                 Operand::Int(zero_id)})) {
      return 0;
    }

    return result_id;
  } else {
    TINT_ICE(Writer, builder_.Diagnostics()) << "Invalid from_type";
  }

  if (op == spv::Op::OpNop) {
    error_ = "unable to determine conversion type for cast, from: " +
             from_type->type_name() + " to: " + to_type->type_name();
    return 0;
  }

  if (!push_function_inst(
          op, {Operand::Int(result_type_id), result, Operand::Int(val_id)})) {
    return 0;
  }

  return result_id;
}

uint32_t Builder::GenerateLiteralIfNeeded(const ast::Variable* var,
                                          const ast::LiteralExpression* lit) {
  ScalarConstant constant;

  auto* global = builder_.Sem().Get<sem::GlobalVariable>(var);
  if (global && global->IsOverridable()) {
    constant.is_spec_op = true;
    constant.constant_id = global->ConstantId();
  }

  Switch(
      lit,
      [&](const ast::BoolLiteralExpression* l) {
        constant.kind = ScalarConstant::Kind::kBool;
        constant.value.b = l->value;
      },
      [&](const ast::SintLiteralExpression* sl) {
        constant.kind = ScalarConstant::Kind::kI32;
        constant.value.i32 = sl->value;
      },
      [&](const ast::UintLiteralExpression* ul) {
        constant.kind = ScalarConstant::Kind::kU32;
        constant.value.u32 = ul->value;
      },
      [&](const ast::FloatLiteralExpression* fl) {
        constant.kind = ScalarConstant::Kind::kF32;
        constant.value.f32 = fl->value;
      },
      [&](Default) { error_ = "unknown literal type"; });

  if (!error_.empty()) {
    return false;
  }

  return GenerateConstantIfNeeded(constant);
}

uint32_t Builder::GenerateConstantIfNeeded(const ScalarConstant& constant) {
  auto it = const_to_id_.find(constant);
  if (it != const_to_id_.end()) {
    return it->second;
  }

  uint32_t type_id = 0;

  switch (constant.kind) {
    case ScalarConstant::Kind::kU32: {
      type_id = GenerateTypeIfNeeded(builder_.create<sem::U32>());
      break;
    }
    case ScalarConstant::Kind::kI32: {
      type_id = GenerateTypeIfNeeded(builder_.create<sem::I32>());
      break;
    }
    case ScalarConstant::Kind::kF32: {
      type_id = GenerateTypeIfNeeded(builder_.create<sem::F32>());
      break;
    }
    case ScalarConstant::Kind::kBool: {
      type_id = GenerateTypeIfNeeded(builder_.create<sem::Bool>());
      break;
    }
  }

  if (type_id == 0) {
    return 0;
  }

  auto result = result_op();
  auto result_id = result.to_i();

  if (constant.is_spec_op) {
    push_annot(spv::Op::OpDecorate,
               {Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
                Operand::Int(constant.constant_id)});
  }

  switch (constant.kind) {
    case ScalarConstant::Kind::kU32: {
      push_type(
          constant.is_spec_op ? spv::Op::OpSpecConstant : spv::Op::OpConstant,
          {Operand::Int(type_id), result, Operand::Int(constant.value.u32)});
      break;
    }
    case ScalarConstant::Kind::kI32: {
      push_type(
          constant.is_spec_op ? spv::Op::OpSpecConstant : spv::Op::OpConstant,
          {Operand::Int(type_id), result, Operand::Int(constant.value.i32)});
      break;
    }
    case ScalarConstant::Kind::kF32: {
      push_type(
          constant.is_spec_op ? spv::Op::OpSpecConstant : spv::Op::OpConstant,
          {Operand::Int(type_id), result, Operand::Float(constant.value.f32)});
      break;
    }
    case ScalarConstant::Kind::kBool: {
      if (constant.value.b) {
        push_type(constant.is_spec_op ? spv::Op::OpSpecConstantTrue
                                      : spv::Op::OpConstantTrue,
                  {Operand::Int(type_id), result});
      } else {
        push_type(constant.is_spec_op ? spv::Op::OpSpecConstantFalse
                                      : spv::Op::OpConstantFalse,
                  {Operand::Int(type_id), result});
      }
      break;
    }
  }

  const_to_id_[constant] = result_id;
  return result_id;
}

uint32_t Builder::GenerateConstantNullIfNeeded(const sem::Type* type) {
  auto type_id = GenerateTypeIfNeeded(type);
  if (type_id == 0) {
    return 0;
  }

  auto name = type->type_name();

  auto it = const_null_to_id_.find(name);
  if (it != const_null_to_id_.end()) {
    return it->second;
  }

  auto result = result_op();
  auto result_id = result.to_i();

  push_type(spv::Op::OpConstantNull, {Operand::Int(type_id), result});

  const_null_to_id_[name] = result_id;
  return result_id;
}

uint32_t Builder::GenerateConstantVectorSplatIfNeeded(const sem::Vector* type,
                                                      uint32_t value_id) {
  auto type_id = GenerateTypeIfNeeded(type);
  if (type_id == 0 || value_id == 0) {
    return 0;
  }

  uint64_t key = (static_cast<uint64_t>(type->Width()) << 32) + value_id;
  return utils::GetOrCreate(const_splat_to_id_, key, [&] {
    auto result = result_op();
    auto result_id = result.to_i();

    OperandList ops;
    ops.push_back(Operand::Int(type_id));
    ops.push_back(result);
    for (uint32_t i = 0; i < type->Width(); i++) {
      ops.push_back(Operand::Int(value_id));
    }
    push_type(spv::Op::OpConstantComposite, ops);

    const_splat_to_id_[key] = result_id;
    return result_id;
  });
}

uint32_t Builder::GenerateShortCircuitBinaryExpression(
    const ast::BinaryExpression* expr) {
  auto lhs_id = GenerateExpressionWithLoadIfNeeded(expr->lhs);
  if (lhs_id == 0) {
    return false;
  }

  // Get the ID of the basic block where control flow will diverge. It's the
  // last basic block generated for the left-hand-side of the operator.
  auto original_label_id = current_label_id_;

  auto type_id = GenerateTypeIfNeeded(TypeOf(expr));
  if (type_id == 0) {
    return 0;
  }

  auto merge_block = result_op();
  auto merge_block_id = merge_block.to_i();

  auto block = result_op();
  auto block_id = block.to_i();

  auto true_block_id = block_id;
  auto false_block_id = merge_block_id;

  // For a logical or we want to only check the RHS if the LHS is failed.
  if (expr->IsLogicalOr()) {
    std::swap(true_block_id, false_block_id);
  }

  if (!push_function_inst(spv::Op::OpSelectionMerge,
                          {Operand::Int(merge_block_id),
                           Operand::Int(SpvSelectionControlMaskNone)})) {
    return 0;
  }
  if (!push_function_inst(spv::Op::OpBranchConditional,
                          {Operand::Int(lhs_id), Operand::Int(true_block_id),
                           Operand::Int(false_block_id)})) {
    return 0;
  }

  // Output block to check the RHS
  if (!GenerateLabel(block_id)) {
    return 0;
  }
  auto rhs_id = GenerateExpressionWithLoadIfNeeded(expr->rhs);
  if (rhs_id == 0) {
    return 0;
  }

  // Get the block ID of the last basic block generated for the right-hand-side
  // expression. That block will be an immediate predecessor to the merge block.
  auto rhs_block_id = current_label_id_;
  if (!push_function_inst(spv::Op::OpBranch, {Operand::Int(merge_block_id)})) {
    return 0;
  }

  // Output the merge block
  if (!GenerateLabel(merge_block_id)) {
    return 0;
  }

  auto result = result_op();
  auto result_id = result.to_i();

  if (!push_function_inst(spv::Op::OpPhi,
                          {Operand::Int(type_id), result, Operand::Int(lhs_id),
                           Operand::Int(original_label_id),
                           Operand::Int(rhs_id), Operand::Int(rhs_block_id)})) {
    return 0;
  }

  return result_id;
}

uint32_t Builder::GenerateSplat(uint32_t scalar_id, const sem::Type* vec_type) {
  // Create a new vector to splat scalar into
  auto splat_vector = result_op();
  auto* splat_vector_type = builder_.create<sem::Pointer>(
      vec_type, ast::StorageClass::kFunction, ast::Access::kReadWrite);
  push_function_var(
      {Operand::Int(GenerateTypeIfNeeded(splat_vector_type)), splat_vector,
       Operand::Int(ConvertStorageClass(ast::StorageClass::kFunction)),
       Operand::Int(GenerateConstantNullIfNeeded(vec_type))});

  // Splat scalar into vector
  auto splat_result = result_op();
  OperandList ops;
  ops.push_back(Operand::Int(GenerateTypeIfNeeded(vec_type)));
  ops.push_back(splat_result);
  for (size_t i = 0; i < vec_type->As<sem::Vector>()->Width(); ++i) {
    ops.push_back(Operand::Int(scalar_id));
  }
  if (!push_function_inst(spv::Op::OpCompositeConstruct, ops)) {
    return 0;
  }

  return splat_result.to_i();
}

uint32_t Builder::GenerateMatrixAddOrSub(uint32_t lhs_id,
                                         uint32_t rhs_id,
                                         const sem::Matrix* type,
                                         spv::Op op) {
  // Example addition of two matrices:
  // %31 = OpLoad %mat3v4float %m34
  // %32 = OpLoad %mat3v4float %m34
  // %33 = OpCompositeExtract %v4float %31 0
  // %34 = OpCompositeExtract %v4float %32 0
  // %35 = OpFAdd %v4float %33 %34
  // %36 = OpCompositeExtract %v4float %31 1
  // %37 = OpCompositeExtract %v4float %32 1
  // %38 = OpFAdd %v4float %36 %37
  // %39 = OpCompositeExtract %v4float %31 2
  // %40 = OpCompositeExtract %v4float %32 2
  // %41 = OpFAdd %v4float %39 %40
  // %42 = OpCompositeConstruct %mat3v4float %35 %38 %41

  auto* column_type = builder_.create<sem::Vector>(type->type(), type->rows());
  auto column_type_id = GenerateTypeIfNeeded(column_type);

  OperandList ops;

  for (uint32_t i = 0; i < type->columns(); ++i) {
    // Extract column `i` from lhs mat
    auto lhs_column_id = result_op();
    if (!push_function_inst(spv::Op::OpCompositeExtract,
                            {Operand::Int(column_type_id), lhs_column_id,
                             Operand::Int(lhs_id), Operand::Int(i)})) {
      return 0;
    }

    // Extract column `i` from rhs mat
    auto rhs_column_id = result_op();
    if (!push_function_inst(spv::Op::OpCompositeExtract,
                            {Operand::Int(column_type_id), rhs_column_id,
                             Operand::Int(rhs_id), Operand::Int(i)})) {
      return 0;
    }

    // Add or subtract the two columns
    auto result = result_op();
    if (!push_function_inst(op, {Operand::Int(column_type_id), result,
                                 lhs_column_id, rhs_column_id})) {
      return 0;
    }

    ops.push_back(result);
  }

  // Create the result matrix from the added/subtracted column vectors
  auto result_mat_id = result_op();
  ops.insert(ops.begin(), result_mat_id);
  ops.insert(ops.begin(), Operand::Int(GenerateTypeIfNeeded(type)));
  if (!push_function_inst(spv::Op::OpCompositeConstruct, ops)) {
    return 0;
  }

  return result_mat_id.to_i();
}

uint32_t Builder::GenerateBinaryExpression(const ast::BinaryExpression* expr) {
  // There is special logic for short circuiting operators.
  if (expr->IsLogicalAnd() || expr->IsLogicalOr()) {
    return GenerateShortCircuitBinaryExpression(expr);
  }

  auto lhs_id = GenerateExpressionWithLoadIfNeeded(expr->lhs);
  if (lhs_id == 0) {
    return 0;
  }

  auto rhs_id = GenerateExpressionWithLoadIfNeeded(expr->rhs);
  if (rhs_id == 0) {
    return 0;
  }

  auto result = result_op();
  auto result_id = result.to_i();

  auto type_id = GenerateTypeIfNeeded(TypeOf(expr));
  if (type_id == 0) {
    return 0;
  }

  // Handle int and float and the vectors of those types. Other types
  // should have been rejected by validation.
  auto* lhs_type = TypeOf(expr->lhs)->UnwrapRef();
  auto* rhs_type = TypeOf(expr->rhs)->UnwrapRef();

  // Handle matrix-matrix addition and subtraction
  if ((expr->IsAdd() || expr->IsSubtract()) && lhs_type->is_float_matrix() &&
      rhs_type->is_float_matrix()) {
    auto* lhs_mat = lhs_type->As<sem::Matrix>();
    auto* rhs_mat = rhs_type->As<sem::Matrix>();

    // This should already have been validated by resolver
    if (lhs_mat->rows() != rhs_mat->rows() ||
        lhs_mat->columns() != rhs_mat->columns()) {
      error_ = "matrices must have same dimensionality for add or subtract";
      return 0;
    }

    return GenerateMatrixAddOrSub(
        lhs_id, rhs_id, lhs_mat,
        expr->IsAdd() ? spv::Op::OpFAdd : spv::Op::OpFSub);
  }

  // For vector-scalar arithmetic operations, splat scalar into a vector. We
  // skip this for multiply as we can use OpVectorTimesScalar.
  const bool is_float_scalar_vector_multiply =
      expr->IsMultiply() &&
      ((lhs_type->is_float_scalar() && rhs_type->is_float_vector()) ||
       (lhs_type->is_float_vector() && rhs_type->is_float_scalar()));

  if (expr->IsArithmetic() && !is_float_scalar_vector_multiply) {
    if (lhs_type->Is<sem::Vector>() && rhs_type->is_numeric_scalar()) {
      uint32_t splat_vector_id = GenerateSplat(rhs_id, lhs_type);
      if (splat_vector_id == 0) {
        return 0;
      }
      rhs_id = splat_vector_id;
      rhs_type = lhs_type;

    } else if (lhs_type->is_numeric_scalar() && rhs_type->Is<sem::Vector>()) {
      uint32_t splat_vector_id = GenerateSplat(lhs_id, rhs_type);
      if (splat_vector_id == 0) {
        return 0;
      }
      lhs_id = splat_vector_id;
      lhs_type = rhs_type;
    }
  }

  bool lhs_is_float_or_vec = lhs_type->is_float_scalar_or_vector();
  bool lhs_is_bool_or_vec = lhs_type->is_bool_scalar_or_vector();
  bool lhs_is_integer_or_vec = lhs_type->is_integer_scalar_or_vector();
  bool lhs_is_unsigned = lhs_type->is_unsigned_scalar_or_vector();

  spv::Op op = spv::Op::OpNop;
  if (expr->IsAnd()) {
    if (lhs_is_integer_or_vec) {
      op = spv::Op::OpBitwiseAnd;
    } else if (lhs_is_bool_or_vec) {
      op = spv::Op::OpLogicalAnd;
    } else {
      error_ = "invalid and expression";
      return 0;
    }
  } else if (expr->IsAdd()) {
    op = lhs_is_float_or_vec ? spv::Op::OpFAdd : spv::Op::OpIAdd;
  } else if (expr->IsDivide()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFDiv;
    } else if (lhs_is_unsigned) {
      op = spv::Op::OpUDiv;
    } else {
      op = spv::Op::OpSDiv;
    }
  } else if (expr->IsEqual()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFOrdEqual;
    } else if (lhs_is_bool_or_vec) {
      op = spv::Op::OpLogicalEqual;
    } else if (lhs_is_integer_or_vec) {
      op = spv::Op::OpIEqual;
    } else {
      error_ = "invalid equal expression";
      return 0;
    }
  } else if (expr->IsGreaterThan()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFOrdGreaterThan;
    } else if (lhs_is_unsigned) {
      op = spv::Op::OpUGreaterThan;
    } else {
      op = spv::Op::OpSGreaterThan;
    }
  } else if (expr->IsGreaterThanEqual()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFOrdGreaterThanEqual;
    } else if (lhs_is_unsigned) {
      op = spv::Op::OpUGreaterThanEqual;
    } else {
      op = spv::Op::OpSGreaterThanEqual;
    }
  } else if (expr->IsLessThan()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFOrdLessThan;
    } else if (lhs_is_unsigned) {
      op = spv::Op::OpULessThan;
    } else {
      op = spv::Op::OpSLessThan;
    }
  } else if (expr->IsLessThanEqual()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFOrdLessThanEqual;
    } else if (lhs_is_unsigned) {
      op = spv::Op::OpULessThanEqual;
    } else {
      op = spv::Op::OpSLessThanEqual;
    }
  } else if (expr->IsModulo()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFRem;
    } else if (lhs_is_unsigned) {
      op = spv::Op::OpUMod;
    } else {
      op = spv::Op::OpSMod;
    }
  } else if (expr->IsMultiply()) {
    if (lhs_type->is_integer_scalar_or_vector()) {
      // If the left hand side is an integer then this _has_ to be OpIMul as
      // there there is no other integer multiplication.
      op = spv::Op::OpIMul;
    } else if (lhs_type->is_float_scalar() && rhs_type->is_float_scalar()) {
      // Float scalars multiply with OpFMul
      op = spv::Op::OpFMul;
    } else if (lhs_type->is_float_vector() && rhs_type->is_float_vector()) {
      // Float vectors must be validated to be the same size and then use OpFMul
      op = spv::Op::OpFMul;
    } else if (lhs_type->is_float_scalar() && rhs_type->is_float_vector()) {
      // Scalar * Vector we need to flip lhs and rhs types
      // because OpVectorTimesScalar expects <vector>, <scalar>
      std::swap(lhs_id, rhs_id);
      op = spv::Op::OpVectorTimesScalar;
    } else if (lhs_type->is_float_vector() && rhs_type->is_float_scalar()) {
      // float vector * scalar
      op = spv::Op::OpVectorTimesScalar;
    } else if (lhs_type->is_float_scalar() && rhs_type->is_float_matrix()) {
      // Scalar * Matrix we need to flip lhs and rhs types because
      // OpMatrixTimesScalar expects <matrix>, <scalar>
      std::swap(lhs_id, rhs_id);
      op = spv::Op::OpMatrixTimesScalar;
    } else if (lhs_type->is_float_matrix() && rhs_type->is_float_scalar()) {
      // float matrix * scalar
      op = spv::Op::OpMatrixTimesScalar;
    } else if (lhs_type->is_float_vector() && rhs_type->is_float_matrix()) {
      // float vector * matrix
      op = spv::Op::OpVectorTimesMatrix;
    } else if (lhs_type->is_float_matrix() && rhs_type->is_float_vector()) {
      // float matrix * vector
      op = spv::Op::OpMatrixTimesVector;
    } else if (lhs_type->is_float_matrix() && rhs_type->is_float_matrix()) {
      // float matrix * matrix
      op = spv::Op::OpMatrixTimesMatrix;
    } else {
      error_ = "invalid multiply expression";
      return 0;
    }
  } else if (expr->IsNotEqual()) {
    if (lhs_is_float_or_vec) {
      op = spv::Op::OpFOrdNotEqual;
    } else if (lhs_is_bool_or_vec) {
      op = spv::Op::OpLogicalNotEqual;
    } else if (lhs_is_integer_or_vec) {
      op = spv::Op::OpINotEqual;
    } else {
      error_ = "invalid not-equal expression";
      return 0;
    }
  } else if (expr->IsOr()) {
    if (lhs_is_integer_or_vec) {
      op = spv::Op::OpBitwiseOr;
    } else if (lhs_is_bool_or_vec) {
      op = spv::Op::OpLogicalOr;
    } else {
      error_ = "invalid and expression";
      return 0;
    }
  } else if (expr->IsShiftLeft()) {
    op = spv::Op::OpShiftLeftLogical;
  } else if (expr->IsShiftRight() && lhs_type->is_signed_scalar_or_vector()) {
    // A shift right with a signed LHS is an arithmetic shift.
    op = spv::Op::OpShiftRightArithmetic;
  } else if (expr->IsShiftRight()) {
    op = spv::Op::OpShiftRightLogical;
  } else if (expr->IsSubtract()) {
    op = lhs_is_float_or_vec ? spv::Op::OpFSub : spv::Op::OpISub;
  } else if (expr->IsXor()) {
    op = spv::Op::OpBitwiseXor;
  } else {
    error_ = "unknown binary expression";
    return 0;
  }

  if (!push_function_inst(op, {Operand::Int(type_id), result,
                               Operand::Int(lhs_id), Operand::Int(rhs_id)})) {
    return 0;
  }
  return result_id;
}

bool Builder::GenerateBlockStatement(const ast::BlockStatement* stmt) {
  scope_stack_.Push();
  TINT_DEFER(scope_stack_.Pop());
  return GenerateBlockStatementWithoutScoping(stmt);
}

bool Builder::GenerateBlockStatementWithoutScoping(
    const ast::BlockStatement* stmt) {
  for (auto* block_stmt : stmt->statements) {
    if (!GenerateStatement(block_stmt)) {
      return false;
    }
  }
  return true;
}

uint32_t Builder::GenerateCallExpression(const ast::CallExpression* expr) {
  auto* call = builder_.Sem().Get(expr);
  auto* target = call->Target();
  return Switch(
      target,
      [&](const sem::Function* func) {
        return GenerateFunctionCall(call, func);
      },
      [&](const sem::Builtin* builtin) {
        return GenerateBuiltinCall(call, builtin);
      },
      [&](const sem::TypeConversion*) {
        return GenerateTypeConstructorOrConversion(call, nullptr);
      },
      [&](const sem::TypeConstructor*) {
        return GenerateTypeConstructorOrConversion(call, nullptr);
      },
      [&](Default) -> uint32_t {
        TINT_ICE(Writer, builder_.Diagnostics())
            << "unhandled call target: " << target->TypeInfo().name;
        return 0;
      });
}

uint32_t Builder::GenerateFunctionCall(const sem::Call* call,
                                       const sem::Function*) {
  auto* expr = call->Declaration();
  auto* ident = expr->target.name;

  auto type_id = GenerateTypeIfNeeded(call->Type());
  if (type_id == 0) {
    return 0;
  }

  auto result = result_op();
  auto result_id = result.to_i();

  OperandList ops = {Operand::Int(type_id), result};

  auto func_id = func_symbol_to_id_[ident->symbol];
  if (func_id == 0) {
    error_ = "unable to find called function: " +
             builder_.Symbols().NameFor(ident->symbol);
    return 0;
  }
  ops.push_back(Operand::Int(func_id));

  size_t arg_idx = 0;
  for (auto* arg : expr->args) {
    auto id = GenerateExpressionWithLoadIfNeeded(arg);
    if (id == 0) {
      return 0;
    }
    ops.push_back(Operand::Int(id));
    arg_idx++;
  }

  if (!push_function_inst(spv::Op::OpFunctionCall, std::move(ops))) {
    return 0;
  }

  return result_id;
}

uint32_t Builder::GenerateBuiltinCall(const sem::Call* call,
                                      const sem::Builtin* builtin) {
  auto result = result_op();
  auto result_id = result.to_i();

  auto result_type_id = GenerateTypeIfNeeded(builtin->ReturnType());
  if (result_type_id == 0) {
    return 0;
  }

  if (builtin->IsFineDerivative() || builtin->IsCoarseDerivative()) {
    push_capability(SpvCapabilityDerivativeControl);
  }

  if (builtin->IsImageQuery()) {
    push_capability(SpvCapabilityImageQuery);
  }

  if (builtin->IsTexture()) {
    if (!GenerateTextureBuiltin(call, builtin, Operand::Int(result_type_id),
                                result)) {
      return 0;
    }
    return result_id;
  }

  if (builtin->IsBarrier()) {
    if (!GenerateControlBarrierBuiltin(builtin)) {
      return 0;
    }
    return result_id;
  }

  if (builtin->IsAtomic()) {
    if (!GenerateAtomicBuiltin(call, builtin, Operand::Int(result_type_id),
                               result)) {
      return 0;
    }
    return result_id;
  }

  // Generates the SPIR-V ID for the expression for the indexed call argument,
  // and loads it if necessary. Returns 0 on error.
  auto get_arg_as_value_id = [&](size_t i,
                                 bool generate_load = true) -> uint32_t {
    auto* arg = call->Arguments()[i];
    auto* param = builtin->Parameters()[i];
    auto val_id = GenerateExpression(arg->Declaration());
    if (val_id == 0) {
      return 0;
    }

    if (generate_load && !param->Type()->Is<sem::Pointer>()) {
      val_id = GenerateLoadIfNeeded(arg->Type(), val_id);
    }
    return val_id;
  };

  OperandList params = {Operand::Int(result_type_id), result};
  spv::Op op = spv::Op::OpNop;

  // Pushes the arguments for a GlslStd450 extended instruction, and sets op
  // to OpExtInst.
  auto glsl_std450 = [&](uint32_t inst_id) {
    auto set_id = GetGLSLstd450Import();
    params.push_back(Operand::Int(set_id));
    params.push_back(Operand::Int(inst_id));
    op = spv::Op::OpExtInst;
  };

  switch (builtin->Type()) {
    case BuiltinType::kAny:
      if (builtin->Parameters()[0]->Type()->Is<sem::Bool>()) {
        // any(v: bool) just resolves to v.
        return get_arg_as_value_id(0);
      }
      op = spv::Op::OpAny;
      break;
    case BuiltinType::kAll:
      if (builtin->Parameters()[0]->Type()->Is<sem::Bool>()) {
        // all(v: bool) just resolves to v.
        return get_arg_as_value_id(0);
      }
      op = spv::Op::OpAll;
      break;
    case BuiltinType::kArrayLength: {
      auto* address_of =
          call->Arguments()[0]->Declaration()->As<ast::UnaryOpExpression>();
      if (!address_of || address_of->op != ast::UnaryOp::kAddressOf) {
        error_ = "arrayLength() expected pointer to member access, got " +
                 std::string(address_of->TypeInfo().name);
        return 0;
      }
      auto* array_expr = address_of->expr;

      auto* accessor = array_expr->As<ast::MemberAccessorExpression>();
      if (!accessor) {
        error_ =
            "arrayLength() expected pointer to member access, got pointer to " +
            std::string(array_expr->TypeInfo().name);
        return 0;
      }

      auto struct_id = GenerateExpression(accessor->structure);
      if (struct_id == 0) {
        return 0;
      }
      params.push_back(Operand::Int(struct_id));

      auto* type = TypeOf(accessor->structure)->UnwrapRef();
      if (!type->Is<sem::Struct>()) {
        error_ =
            "invalid type (" + type->type_name() + ") for runtime array length";
        return 0;
      }
      // Runtime array must be the last member in the structure
      params.push_back(Operand::Int(uint32_t(
          type->As<sem::Struct>()->Declaration()->members.size() - 1)));

      if (!push_function_inst(spv::Op::OpArrayLength, params)) {
        return 0;
      }
      return result_id;
    }
    case BuiltinType::kCountOneBits:
      op = spv::Op::OpBitCount;
      break;
    case BuiltinType::kDot: {
      op = spv::Op::OpDot;
      auto* vec_ty = builtin->Parameters()[0]->Type()->As<sem::Vector>();
      if (vec_ty->type()->is_integer_scalar()) {
        // TODO(crbug.com/tint/1267): OpDot requires floating-point types, but
        // WGSL also supports integer types. SPV_KHR_integer_dot_product adds
        // support for integer vectors. Use it if it is available.
        auto el_ty = Operand::Int(GenerateTypeIfNeeded(vec_ty->type()));
        auto vec_a = Operand::Int(get_arg_as_value_id(0));
        auto vec_b = Operand::Int(get_arg_as_value_id(1));
        if (vec_a.to_i() == 0 || vec_b.to_i() == 0) {
          return 0;
        }

        auto sum = Operand::Int(0);
        for (uint32_t i = 0; i < vec_ty->Width(); i++) {
          auto a = result_op();
          auto b = result_op();
          auto mul = result_op();
          if (!push_function_inst(spv::Op::OpCompositeExtract,
                                  {el_ty, a, vec_a, Operand::Int(i)}) ||
              !push_function_inst(spv::Op::OpCompositeExtract,
                                  {el_ty, b, vec_b, Operand::Int(i)}) ||
              !push_function_inst(spv::Op::OpIMul, {el_ty, mul, a, b})) {
            return 0;
          }
          if (i == 0) {
            sum = mul;
          } else {
            auto prev_sum = sum;
            auto is_last_el = i == (vec_ty->Width() - 1);
            sum = is_last_el ? Operand::Int(result_id) : result_op();
            if (!push_function_inst(spv::Op::OpIAdd,
                                    {el_ty, sum, prev_sum, mul})) {
              return 0;
            }
          }
        }
        return result_id;
      }
      break;
    }
    case BuiltinType::kDpdx:
      op = spv::Op::OpDPdx;
      break;
    case BuiltinType::kDpdxCoarse:
      op = spv::Op::OpDPdxCoarse;
      break;
    case BuiltinType::kDpdxFine:
      op = spv::Op::OpDPdxFine;
      break;
    case BuiltinType::kDpdy:
      op = spv::Op::OpDPdy;
      break;
    case BuiltinType::kDpdyCoarse:
      op = spv::Op::OpDPdyCoarse;
      break;
    case BuiltinType::kDpdyFine:
      op = spv::Op::OpDPdyFine;
      break;
    case BuiltinType::kFwidth:
      op = spv::Op::OpFwidth;
      break;
    case BuiltinType::kFwidthCoarse:
      op = spv::Op::OpFwidthCoarse;
      break;
    case BuiltinType::kFwidthFine:
      op = spv::Op::OpFwidthFine;
      break;
    case BuiltinType::kIsInf:
      op = spv::Op::OpIsInf;
      break;
    case BuiltinType::kIsNan:
      op = spv::Op::OpIsNan;
      break;
    case BuiltinType::kIsFinite: {
      // Implemented as:   not(IsInf or IsNan)
      auto val_id = get_arg_as_value_id(0);
      if (!val_id) {
        return 0;
      }
      auto inf_result = result_op();
      auto nan_result = result_op();
      auto or_result = result_op();
      if (push_function_inst(spv::Op::OpIsInf,
                             {Operand::Int(result_type_id), inf_result,
                              Operand::Int(val_id)}) &&
          push_function_inst(spv::Op::OpIsNan,
                             {Operand::Int(result_type_id), nan_result,
                              Operand::Int(val_id)}) &&
          push_function_inst(spv::Op::OpLogicalOr,
                             {Operand::Int(result_type_id), or_result,
                              Operand::Int(inf_result.to_i()),
                              Operand::Int(nan_result.to_i())}) &&
          push_function_inst(spv::Op::OpLogicalNot,
                             {Operand::Int(result_type_id), result,
                              Operand::Int(or_result.to_i())})) {
        return result_id;
      }
      return 0;
    }
    case BuiltinType::kIsNormal: {
      // A normal number is finite, non-zero, and not subnormal.
      // Its exponent is neither of the extreme possible values.
      // Implemented as:
      //   exponent_bits = bitcast<u32>(f);
      //   clamped = uclamp(1,254,exponent_bits);
      //   result = (clamped == exponent_bits);
      //
      auto val_id = get_arg_as_value_id(0);
      if (!val_id) {
        return 0;
      }

      // These parameters are valid for IEEE 754 binary32
      const uint32_t kExponentMask = 0x7f80000;
      const uint32_t kMinNormalExponent = 0x0080000;
      const uint32_t kMaxNormalExponent = 0x7f00000;

      auto set_id = GetGLSLstd450Import();
      auto* u32 = builder_.create<sem::U32>();

      auto unsigned_id = GenerateTypeIfNeeded(u32);
      auto exponent_mask_id =
          GenerateConstantIfNeeded(ScalarConstant::U32(kExponentMask));
      auto min_exponent_id =
          GenerateConstantIfNeeded(ScalarConstant::U32(kMinNormalExponent));
      auto max_exponent_id =
          GenerateConstantIfNeeded(ScalarConstant::U32(kMaxNormalExponent));
      if (auto* fvec_ty = builtin->ReturnType()->As<sem::Vector>()) {
        // In the vector case, update the unsigned type to a vector type of the
        // same size, and create vector constants by replicating the scalars.
        // I expect backend compilers to fold these into unique constants, so
        // there is no loss of efficiency.
        auto* uvec_ty = builder_.create<sem::Vector>(u32, fvec_ty->Width());
        unsigned_id = GenerateTypeIfNeeded(uvec_ty);
        auto splat = [&](uint32_t scalar_id) -> uint32_t {
          auto splat_result = result_op();
          OperandList splat_params{Operand::Int(unsigned_id), splat_result};
          for (size_t i = 0; i < fvec_ty->Width(); i++) {
            splat_params.emplace_back(Operand::Int(scalar_id));
          }
          if (!push_function_inst(spv::Op::OpCompositeConstruct,
                                  std::move(splat_params))) {
            return 0;
          }
          return splat_result.to_i();
        };
        exponent_mask_id = splat(exponent_mask_id);
        min_exponent_id = splat(min_exponent_id);
        max_exponent_id = splat(max_exponent_id);
      }
      auto cast_result = result_op();
      auto exponent_bits_result = result_op();
      auto clamp_result = result_op();

      if (set_id && unsigned_id && exponent_mask_id && min_exponent_id &&
          max_exponent_id &&
          push_function_inst(
              spv::Op::OpBitcast,
              {Operand::Int(unsigned_id), cast_result, Operand::Int(val_id)}) &&
          push_function_inst(spv::Op::OpBitwiseAnd,
                             {Operand::Int(unsigned_id), exponent_bits_result,
                              Operand::Int(cast_result.to_i()),
                              Operand::Int(exponent_mask_id)}) &&
          push_function_inst(
              spv::Op::OpExtInst,
              {Operand::Int(unsigned_id), clamp_result, Operand::Int(set_id),
               Operand::Int(GLSLstd450UClamp),
               Operand::Int(exponent_bits_result.to_i()),
               Operand::Int(min_exponent_id), Operand::Int(max_exponent_id)}) &&
          push_function_inst(spv::Op::OpIEqual,
                             {Operand::Int(result_type_id), result,
                              Operand::Int(exponent_bits_result.to_i()),
                              Operand::Int(clamp_result.to_i())})) {
        return result_id;
      }
      return 0;
    }
    case BuiltinType::kMix: {
      auto std450 = Operand::Int(GetGLSLstd450Import());

      auto a_id = get_arg_as_value_id(0);
      auto b_id = get_arg_as_value_id(1);
      auto f_id = get_arg_as_value_id(2);
      if (!a_id || !b_id || !f_id) {
        return 0;
      }

      // If the interpolant is scalar but the objects are vectors, we need to
      // splat the interpolant into a vector of the same size.
      auto* result_vector_type = builtin->ReturnType()->As<sem::Vector>();
      if (result_vector_type && builtin->Parameters()[2]->Type()->is_scalar()) {
        f_id = GenerateSplat(f_id, builtin->Parameters()[0]->Type());
        if (f_id == 0) {
          return 0;
        }
      }

      if (!push_function_inst(spv::Op::OpExtInst,
                              {Operand::Int(result_type_id), result, std450,
                               Operand::Int(GLSLstd450FMix), Operand::Int(a_id),
                               Operand::Int(b_id), Operand::Int(f_id)})) {
        return 0;
      }
      return result_id;
    }
    case BuiltinType::kReverseBits:
      op = spv::Op::OpBitReverse;
      break;
    case BuiltinType::kSelect: {
      // Note: Argument order is different in WGSL and SPIR-V
      auto cond_id = get_arg_as_value_id(2);
      auto true_id = get_arg_as_value_id(1);
      auto false_id = get_arg_as_value_id(0);
      if (!cond_id || !true_id || !false_id) {
        return 0;
      }

      // If the condition is scalar but the objects are vectors, we need to
      // splat the condition into a vector of the same size.
      // TODO(jrprice): If we're targeting SPIR-V 1.4, we don't need to do this.
      auto* result_vector_type = builtin->ReturnType()->As<sem::Vector>();
      if (result_vector_type && builtin->Parameters()[2]->Type()->is_scalar()) {
        auto* bool_vec_ty = builder_.create<sem::Vector>(
            builder_.create<sem::Bool>(), result_vector_type->Width());
        if (!GenerateTypeIfNeeded(bool_vec_ty)) {
          return 0;
        }
        cond_id = GenerateSplat(cond_id, bool_vec_ty);
        if (cond_id == 0) {
          return 0;
        }
      }

      if (!push_function_inst(
              spv::Op::OpSelect,
              {Operand::Int(result_type_id), result, Operand::Int(cond_id),
               Operand::Int(true_id), Operand::Int(false_id)})) {
        return 0;
      }
      return result_id;
    }
    case BuiltinType::kTranspose:
      op = spv::Op::OpTranspose;
      break;
    case BuiltinType::kAbs:
      if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
        // abs() only operates on *signed* integers.
        // This is a no-op for unsigned integers.
        return get_arg_as_value_id(0);
      }
      if (builtin->ReturnType()->is_float_scalar_or_vector()) {
        glsl_std450(GLSLstd450FAbs);
      } else {
        glsl_std450(GLSLstd450SAbs);
      }
      break;
    default: {
      auto inst_id = builtin_to_glsl_method(builtin);
      if (inst_id == 0) {
        error_ = "unknown method " + std::string(builtin->str());
        return 0;
      }
      glsl_std450(inst_id);
      break;
    }
  }

  if (op == spv::Op::OpNop) {
    error_ = "unable to determine operator for: " + std::string(builtin->str());
    return 0;
  }

  for (size_t i = 0; i < call->Arguments().size(); i++) {
    if (auto val_id = get_arg_as_value_id(i)) {
      params.emplace_back(Operand::Int(val_id));
    } else {
      return 0;
    }
  }

  if (!push_function_inst(op, params)) {
    return 0;
  }

  return result_id;
}

bool Builder::GenerateTextureBuiltin(const sem::Call* call,
                                     const sem::Builtin* builtin,
                                     Operand result_type,
                                     Operand result_id) {
  using Usage = sem::ParameterUsage;

  auto& signature = builtin->Signature();
  auto& arguments = call->Arguments();

  // Generates the given expression, returning the operand ID
  auto gen = [&](const sem::Expression* expr) {
    const auto val_id = GenerateExpressionWithLoadIfNeeded(expr);
    return Operand::Int(val_id);
  };

  // Returns the argument with the given usage
  auto arg = [&](Usage usage) {
    int idx = signature.IndexOf(usage);
    return (idx >= 0) ? arguments[idx] : nullptr;
  };

  // Generates the argument with the given usage, returning the operand ID
  auto gen_arg = [&](Usage usage) {
    auto* argument = arg(usage);
    if (!argument) {
      TINT_ICE(Writer, builder_.Diagnostics())
          << "missing argument " << static_cast<int>(usage);
    }
    return gen(argument);
  };

  auto* texture = arg(Usage::kTexture);
  if (!texture) {
    TINT_ICE(Writer, builder_.Diagnostics()) << "missing texture argument";
  }

  auto* texture_type = texture->Type()->UnwrapRef()->As<sem::Texture>();

  auto op = spv::Op::OpNop;

  // Custom function to call after the texture-builtin op has been generated.
  std::function<bool()> post_emission = [] { return true; };

  // Populate the spirv_params with common parameters
  OperandList spirv_params;
  spirv_params.reserve(8);  // Enough to fit most parameter lists

  // Extra image operands, appended to spirv_params.
  struct ImageOperand {
    SpvImageOperandsMask mask;
    Operand operand;
  };
  std::vector<ImageOperand> image_operands;
  image_operands.reserve(4);  // Enough to fit most parameter lists

  // Appends `result_type` and `result_id` to `spirv_params`
  auto append_result_type_and_id_to_spirv_params = [&]() {
    spirv_params.emplace_back(std::move(result_type));
    spirv_params.emplace_back(std::move(result_id));
  };

  // Appends a result type and id to `spirv_params`, possibly adding a
  // post_emission step.
  //
  // If the texture is a depth texture, then this function wraps the result of
  // the op with a OpCompositeExtract to evaluate to the first element of the
  // returned vector. This is done as the WGSL texture reading functions for
  // depths return a single float scalar instead of a vector.
  //
  // If the texture is not a depth texture, then this function simply delegates
  // to calling append_result_type_and_id_to_spirv_params().
  auto append_result_type_and_id_to_spirv_params_for_read = [&]() {
    if (texture_type
            ->IsAnyOf<sem::DepthTexture, sem::DepthMultisampledTexture>()) {
      auto* f32 = builder_.create<sem::F32>();
      auto* spirv_result_type = builder_.create<sem::Vector>(f32, 4);
      auto spirv_result = result_op();
      post_emission = [=] {
        return push_function_inst(
            spv::Op::OpCompositeExtract,
            {result_type, result_id, spirv_result, Operand::Int(0)});
      };
      auto spirv_result_type_id = GenerateTypeIfNeeded(spirv_result_type);
      if (spirv_result_type_id == 0) {
        return false;
      }
      spirv_params.emplace_back(Operand::Int(spirv_result_type_id));
      spirv_params.emplace_back(spirv_result);
      return true;
    }

    append_result_type_and_id_to_spirv_params();
    return true;
  };

  // Appends a result type and id to `spirv_params`, by first swizzling the
  // result of the op with `swizzle`.
  auto append_result_type_and_id_to_spirv_params_swizzled =
      [&](uint32_t spirv_result_width, std::vector<uint32_t> swizzle) {
        if (swizzle.empty()) {
          append_result_type_and_id_to_spirv_params();
        } else {
          // Assign post_emission to swizzle the result of the call to
          // OpImageQuerySize[Lod].
          auto* element_type = ElementTypeOf(call->Type());
          auto spirv_result = result_op();
          auto* spirv_result_type =
              builder_.create<sem::Vector>(element_type, spirv_result_width);
          if (swizzle.size() > 1) {
            post_emission = [=] {
              OperandList operands{
                  result_type,
                  result_id,
                  spirv_result,
                  spirv_result,
              };
              for (auto idx : swizzle) {
                operands.emplace_back(Operand::Int(idx));
              }
              return push_function_inst(spv::Op::OpVectorShuffle, operands);
            };
          } else {
            post_emission = [=] {
              return push_function_inst(spv::Op::OpCompositeExtract,
                                        {result_type, result_id, spirv_result,
                                         Operand::Int(swizzle[0])});
            };
          }
          auto spirv_result_type_id = GenerateTypeIfNeeded(spirv_result_type);
          if (spirv_result_type_id == 0) {
            return false;
          }
          spirv_params.emplace_back(Operand::Int(spirv_result_type_id));
          spirv_params.emplace_back(spirv_result);
        }
        return true;
      };

  auto append_coords_to_spirv_params = [&]() -> bool {
    if (auto* array_index = arg(Usage::kArrayIndex)) {
      // Array index needs to be appended to the coordinates.
      auto* packed = AppendVector(&builder_, arg(Usage::kCoords)->Declaration(),
                                  array_index->Declaration());
      auto param = GenerateExpression(packed->Declaration());
      if (param == 0) {
        return false;
      }
      spirv_params.emplace_back(Operand::Int(param));
    } else {
      spirv_params.emplace_back(gen_arg(Usage::kCoords));  // coordinates
    }
    return true;
  };

  auto append_image_and_coords_to_spirv_params = [&]() -> bool {
    auto sampler_param = gen_arg(Usage::kSampler);
    auto texture_param = gen_arg(Usage::kTexture);
    auto sampled_image =
        GenerateSampledImage(texture_type, texture_param, sampler_param);

    // Populate the spirv_params with the common parameters
    spirv_params.emplace_back(Operand::Int(sampled_image));  // sampled image
    return append_coords_to_spirv_params();
  };

  switch (builtin->Type()) {
    case BuiltinType::kTextureDimensions: {
      // Number of returned elements from OpImageQuerySize[Lod] may not match
      // those of textureDimensions().
      // This might be due to an extra vector scalar describing the number of
      // array elements or textureDimensions() returning a vec3 for cubes
      // when only width / height is returned by OpImageQuerySize[Lod]
      // (see https://github.com/gpuweb/gpuweb/issues/1345).
      // Handle these mismatches by swizzling the returned vector.
      std::vector<uint32_t> swizzle;
      uint32_t spirv_dims = 0;
      switch (texture_type->dim()) {
        case ast::TextureDimension::kNone:
          error_ = "texture dimension is kNone";
          return false;
        case ast::TextureDimension::k1d:
        case ast::TextureDimension::k2d:
        case ast::TextureDimension::k3d:
        case ast::TextureDimension::kCube:
          break;  // No swizzle needed
        case ast::TextureDimension::kCubeArray:
        case ast::TextureDimension::k2dArray:
          swizzle = {0, 1};  // Strip array index
          spirv_dims = 3;    // [width, height, array_count]
          break;
      }

      if (!append_result_type_and_id_to_spirv_params_swizzled(spirv_dims,
                                                              swizzle)) {
        return false;
      }

      spirv_params.emplace_back(gen_arg(Usage::kTexture));
      if (texture_type->IsAnyOf<sem::MultisampledTexture,       //
                                sem::DepthMultisampledTexture,  //
                                sem::StorageTexture>()) {
        op = spv::Op::OpImageQuerySize;
      } else if (auto* level = arg(Usage::kLevel)) {
        op = spv::Op::OpImageQuerySizeLod;
        spirv_params.emplace_back(gen(level));
      } else {
        ast::SintLiteralExpression i32_0(ProgramID(), Source{}, 0);
        op = spv::Op::OpImageQuerySizeLod;
        spirv_params.emplace_back(
            Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
      }
      break;
    }
    case BuiltinType::kTextureNumLayers: {
      uint32_t spirv_dims = 0;
      switch (texture_type->dim()) {
        default:
          error_ = "texture is not arrayed";
          return false;
        case ast::TextureDimension::k2dArray:
        case ast::TextureDimension::kCubeArray:
          spirv_dims = 3;
          break;
      }

      // OpImageQuerySize[Lod] packs the array count as the last element of the
      // returned vector. Extract this.
      if (!append_result_type_and_id_to_spirv_params_swizzled(
              spirv_dims, {spirv_dims - 1})) {
        return false;
      }

      spirv_params.emplace_back(gen_arg(Usage::kTexture));

      if (texture_type->Is<sem::MultisampledTexture>() ||
          texture_type->Is<sem::StorageTexture>()) {
        op = spv::Op::OpImageQuerySize;
      } else {
        ast::SintLiteralExpression i32_0(ProgramID(), Source{}, 0);
        op = spv::Op::OpImageQuerySizeLod;
        spirv_params.emplace_back(
            Operand::Int(GenerateLiteralIfNeeded(nullptr, &i32_0)));
      }
      break;
    }
    case BuiltinType::kTextureNumLevels: {
      op = spv::Op::OpImageQueryLevels;
      append_result_type_and_id_to_spirv_params();
      spirv_params.emplace_back(gen_arg(Usage::kTexture));
      break;
    }
    case BuiltinType::kTextureNumSamples: {
      op = spv::Op::OpImageQuerySamples;
      append_result_type_and_id_to_spirv_params();
      spirv_params.emplace_back(gen_arg(Usage::kTexture));
      break;
    }
    case BuiltinType::kTextureLoad: {
      op = texture_type->Is<sem::StorageTexture>() ? spv::Op::OpImageRead
                                                   : spv::Op::OpImageFetch;
      append_result_type_and_id_to_spirv_params_for_read();
      spirv_params.emplace_back(gen_arg(Usage::kTexture));
      if (!append_coords_to_spirv_params()) {
        return false;
      }

      if (auto* level = arg(Usage::kLevel)) {
        image_operands.emplace_back(
            ImageOperand{SpvImageOperandsLodMask, gen(level)});
      }

      if (auto* sample_index = arg(Usage::kSampleIndex)) {
        image_operands.emplace_back(
            ImageOperand{SpvImageOperandsSampleMask, gen(sample_index)});
      }

      break;
    }
    case BuiltinType::kTextureStore: {
      op = spv::Op::OpImageWrite;
      spirv_params.emplace_back(gen_arg(Usage::kTexture));
      if (!append_coords_to_spirv_params()) {
        return false;
      }
      spirv_params.emplace_back(gen_arg(Usage::kValue));
      break;
    }
    case BuiltinType::kTextureGather: {
      op = spv::Op::OpImageGather;
      append_result_type_and_id_to_spirv_params();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      if (signature.IndexOf(Usage::kComponent) < 0) {
        spirv_params.emplace_back(
            Operand::Int(GenerateConstantIfNeeded(ScalarConstant::I32(0))));
      } else {
        spirv_params.emplace_back(gen_arg(Usage::kComponent));
      }
      break;
    }
    case BuiltinType::kTextureGatherCompare: {
      op = spv::Op::OpImageDrefGather;
      append_result_type_and_id_to_spirv_params();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      spirv_params.emplace_back(gen_arg(Usage::kDepthRef));
      break;
    }
    case BuiltinType::kTextureSample: {
      op = spv::Op::OpImageSampleImplicitLod;
      append_result_type_and_id_to_spirv_params_for_read();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      break;
    }
    case BuiltinType::kTextureSampleBias: {
      op = spv::Op::OpImageSampleImplicitLod;
      append_result_type_and_id_to_spirv_params_for_read();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      image_operands.emplace_back(
          ImageOperand{SpvImageOperandsBiasMask, gen_arg(Usage::kBias)});
      break;
    }
    case BuiltinType::kTextureSampleLevel: {
      op = spv::Op::OpImageSampleExplicitLod;
      append_result_type_and_id_to_spirv_params_for_read();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      auto level = Operand::Int(0);
      if (arg(Usage::kLevel)->Type()->UnwrapRef()->Is<sem::I32>()) {
        // Depth textures have i32 parameters for the level, but SPIR-V expects
        // F32. Cast.
        auto f32_type_id = GenerateTypeIfNeeded(builder_.create<sem::F32>());
        if (f32_type_id == 0) {
          return 0;
        }
        level = result_op();
        if (!push_function_inst(
                spv::Op::OpConvertSToF,
                {Operand::Int(f32_type_id), level, gen_arg(Usage::kLevel)})) {
          return 0;
        }
      } else {
        level = gen_arg(Usage::kLevel);
      }
      image_operands.emplace_back(ImageOperand{SpvImageOperandsLodMask, level});
      break;
    }
    case BuiltinType::kTextureSampleGrad: {
      op = spv::Op::OpImageSampleExplicitLod;
      append_result_type_and_id_to_spirv_params_for_read();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      image_operands.emplace_back(
          ImageOperand{SpvImageOperandsGradMask, gen_arg(Usage::kDdx)});
      image_operands.emplace_back(
          ImageOperand{SpvImageOperandsGradMask, gen_arg(Usage::kDdy)});
      break;
    }
    case BuiltinType::kTextureSampleCompare: {
      op = spv::Op::OpImageSampleDrefImplicitLod;
      append_result_type_and_id_to_spirv_params();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      spirv_params.emplace_back(gen_arg(Usage::kDepthRef));
      break;
    }
    case BuiltinType::kTextureSampleCompareLevel: {
      op = spv::Op::OpImageSampleDrefExplicitLod;
      append_result_type_and_id_to_spirv_params();
      if (!append_image_and_coords_to_spirv_params()) {
        return false;
      }
      spirv_params.emplace_back(gen_arg(Usage::kDepthRef));

      ast::FloatLiteralExpression float_0(ProgramID(), Source{}, 0.0);
      image_operands.emplace_back(ImageOperand{
          SpvImageOperandsLodMask,
          Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))});
      break;
    }
    default:
      TINT_UNREACHABLE(Writer, builder_.Diagnostics());
      return false;
  }

  if (auto* offset = arg(Usage::kOffset)) {
    image_operands.emplace_back(
        ImageOperand{SpvImageOperandsConstOffsetMask, gen(offset)});
  }

  if (!image_operands.empty()) {
    std::sort(image_operands.begin(), image_operands.end(),
              [](auto& a, auto& b) { return a.mask < b.mask; });
    uint32_t mask = 0;
    for (auto& image_operand : image_operands) {
      mask |= image_operand.mask;
    }
    spirv_params.emplace_back(Operand::Int(mask));
    for (auto& image_operand : image_operands) {
      spirv_params.emplace_back(image_operand.operand);
    }
  }

  if (op == spv::Op::OpNop) {
    error_ = "unable to determine operator for: " + std::string(builtin->str());
    return false;
  }

  if (!push_function_inst(op, spirv_params)) {
    return false;
  }

  return post_emission();
}

bool Builder::GenerateControlBarrierBuiltin(const sem::Builtin* builtin) {
  auto const op = spv::Op::OpControlBarrier;
  uint32_t execution = 0;
  uint32_t memory = 0;
  uint32_t semantics = 0;

  // TODO(crbug.com/tint/661): Combine sequential barriers to a single
  // instruction.
  if (builtin->Type() == sem::BuiltinType::kWorkgroupBarrier) {
    execution = static_cast<uint32_t>(spv::Scope::Workgroup);
    memory = static_cast<uint32_t>(spv::Scope::Workgroup);
    semantics =
        static_cast<uint32_t>(spv::MemorySemanticsMask::AcquireRelease) |
        static_cast<uint32_t>(spv::MemorySemanticsMask::WorkgroupMemory);
  } else if (builtin->Type() == sem::BuiltinType::kStorageBarrier) {
    execution = static_cast<uint32_t>(spv::Scope::Workgroup);
    memory = static_cast<uint32_t>(spv::Scope::Workgroup);
    semantics =
        static_cast<uint32_t>(spv::MemorySemanticsMask::AcquireRelease) |
        static_cast<uint32_t>(spv::MemorySemanticsMask::UniformMemory);
  } else {
    error_ = "unexpected barrier builtin type ";
    error_ += sem::str(builtin->Type());
    return false;
  }

  auto execution_id = GenerateConstantIfNeeded(ScalarConstant::U32(execution));
  auto memory_id = GenerateConstantIfNeeded(ScalarConstant::U32(memory));
  auto semantics_id = GenerateConstantIfNeeded(ScalarConstant::U32(semantics));
  if (execution_id == 0 || memory_id == 0 || semantics_id == 0) {
    return false;
  }

  return push_function_inst(op, {
                                    Operand::Int(execution_id),
                                    Operand::Int(memory_id),
                                    Operand::Int(semantics_id),
                                });
}

bool Builder::GenerateAtomicBuiltin(const sem::Call* call,
                                    const sem::Builtin* builtin,
                                    Operand result_type,
                                    Operand result_id) {
  auto is_value_signed = [&] {
    return builtin->Parameters()[1]->Type()->Is<sem::I32>();
  };

  auto storage_class =
      builtin->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass();

  uint32_t memory_id = 0;
  switch (
      builtin->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass()) {
    case ast::StorageClass::kWorkgroup:
      memory_id = GenerateConstantIfNeeded(
          ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Workgroup)));
      break;
    case ast::StorageClass::kStorage:
      memory_id = GenerateConstantIfNeeded(
          ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Device)));
      break;
    default:
      TINT_UNREACHABLE(Writer, builder_.Diagnostics())
          << "unhandled atomic storage class " << storage_class;
      return false;
  }
  if (memory_id == 0) {
    return false;
  }

  uint32_t semantics_id = GenerateConstantIfNeeded(ScalarConstant::U32(
      static_cast<uint32_t>(spv::MemorySemanticsMask::MaskNone)));
  if (semantics_id == 0) {
    return false;
  }

  uint32_t pointer_id = GenerateExpression(call->Arguments()[0]->Declaration());
  if (pointer_id == 0) {
    return false;
  }

  uint32_t value_id = 0;
  if (call->Arguments().size() > 1) {
    value_id = GenerateExpressionWithLoadIfNeeded(call->Arguments().back());
    if (value_id == 0) {
      return false;
    }
  }

  Operand pointer = Operand::Int(pointer_id);
  Operand value = Operand::Int(value_id);
  Operand memory = Operand::Int(memory_id);
  Operand semantics = Operand::Int(semantics_id);

  switch (builtin->Type()) {
    case sem::BuiltinType::kAtomicLoad:
      return push_function_inst(spv::Op::OpAtomicLoad, {
                                                           result_type,
                                                           result_id,
                                                           pointer,
                                                           memory,
                                                           semantics,
                                                       });
    case sem::BuiltinType::kAtomicStore:
      return push_function_inst(spv::Op::OpAtomicStore, {
                                                            pointer,
                                                            memory,
                                                            semantics,
                                                            value,
                                                        });
    case sem::BuiltinType::kAtomicAdd:
      return push_function_inst(spv::Op::OpAtomicIAdd, {
                                                           result_type,
                                                           result_id,
                                                           pointer,
                                                           memory,
                                                           semantics,
                                                           value,
                                                       });
    case sem::BuiltinType::kAtomicSub:
      return push_function_inst(spv::Op::OpAtomicISub, {
                                                           result_type,
                                                           result_id,
                                                           pointer,
                                                           memory,
                                                           semantics,
                                                           value,
                                                       });
    case sem::BuiltinType::kAtomicMax:
      return push_function_inst(
          is_value_signed() ? spv::Op::OpAtomicSMax : spv::Op::OpAtomicUMax,
          {
              result_type,
              result_id,
              pointer,
              memory,
              semantics,
              value,
          });
    case sem::BuiltinType::kAtomicMin:
      return push_function_inst(
          is_value_signed() ? spv::Op::OpAtomicSMin : spv::Op::OpAtomicUMin,
          {
              result_type,
              result_id,
              pointer,
              memory,
              semantics,
              value,
          });
    case sem::BuiltinType::kAtomicAnd:
      return push_function_inst(spv::Op::OpAtomicAnd, {
                                                          result_type,
                                                          result_id,
                                                          pointer,
                                                          memory,
                                                          semantics,
                                                          value,
                                                      });
    case sem::BuiltinType::kAtomicOr:
      return push_function_inst(spv::Op::OpAtomicOr, {
                                                         result_type,
                                                         result_id,
                                                         pointer,
                                                         memory,
                                                         semantics,
                                                         value,
                                                     });
    case sem::BuiltinType::kAtomicXor:
      return push_function_inst(spv::Op::OpAtomicXor, {
                                                          result_type,
                                                          result_id,
                                                          pointer,
                                                          memory,
                                                          semantics,
                                                          value,
                                                      });
    case sem::BuiltinType::kAtomicExchange:
      return push_function_inst(spv::Op::OpAtomicExchange, {
                                                               result_type,
                                                               result_id,
                                                               pointer,
                                                               memory,
                                                               semantics,
                                                               value,
                                                           });
    case sem::BuiltinType::kAtomicCompareExchangeWeak: {
      auto comparator = GenerateExpression(call->Arguments()[1]->Declaration());
      if (comparator == 0) {
        return false;
      }

      auto* value_sem_type = TypeOf(call->Arguments()[2]->Declaration());

      auto value_type = GenerateTypeIfNeeded(value_sem_type);
      if (value_type == 0) {
        return false;
      }

      auto* bool_sem_ty = builder_.create<sem::Bool>();
      auto bool_type = GenerateTypeIfNeeded(bool_sem_ty);
      if (bool_type == 0) {
        return false;
      }

      // original_value := OpAtomicCompareExchange(pointer, memory, semantics,
      //                                           semantics, value, comparator)
      auto original_value = result_op();
      if (!push_function_inst(spv::Op::OpAtomicCompareExchange,
                              {
                                  Operand::Int(value_type),
                                  original_value,
                                  pointer,
                                  memory,
                                  semantics,
                                  semantics,
                                  value,
                                  Operand::Int(comparator),
                              })) {
        return false;
      }

      // values_equal := original_value == value
      auto values_equal = result_op();
      if (!push_function_inst(spv::Op::OpIEqual, {
                                                     Operand::Int(bool_type),
                                                     values_equal,
                                                     original_value,
                                                     value,
                                                 })) {
        return false;
      }

      // zero := T(0)
      // one := T(1)
      uint32_t zero = 0;
      uint32_t one = 0;
      if (value_sem_type->Is<sem::I32>()) {
        zero = GenerateConstantIfNeeded(ScalarConstant::I32(0u));
        one = GenerateConstantIfNeeded(ScalarConstant::I32(1u));
      } else if (value_sem_type->Is<sem::U32>()) {
        zero = GenerateConstantIfNeeded(ScalarConstant::U32(0u));
        one = GenerateConstantIfNeeded(ScalarConstant::U32(1u));
      } else {
        TINT_UNREACHABLE(Writer, builder_.Diagnostics())
            << "unsupported atomic type " << value_sem_type->TypeInfo().name;
      }
      if (zero == 0 || one == 0) {
        return false;
      }

      // xchg_success := values_equal ? one : zero
      auto xchg_success = result_op();
      if (!push_function_inst(spv::Op::OpSelect, {
                                                     Operand::Int(value_type),
                                                     xchg_success,
                                                     values_equal,
                                                     Operand::Int(one),
                                                     Operand::Int(zero),
                                                 })) {
        return false;
      }

      // result := vec2<T>(original_value, xchg_success)
      return push_function_inst(spv::Op::OpCompositeConstruct,
                                {
                                    result_type,
                                    result_id,
                                    original_value,
                                    xchg_success,
                                });
    }
    default:
      TINT_UNREACHABLE(Writer, builder_.Diagnostics())
          << "unhandled atomic builtin " << builtin->Type();
      return false;
  }
}

uint32_t Builder::GenerateSampledImage(const sem::Type* texture_type,
                                       Operand texture_operand,
                                       Operand sampler_operand) {
  uint32_t sampled_image_type_id = 0;
  auto val = texture_type_name_to_sampled_image_type_id_.find(
      texture_type->type_name());
  if (val != texture_type_name_to_sampled_image_type_id_.end()) {
    // The sampled image type is already created.
    sampled_image_type_id = val->second;
  } else {
    // We need to create the sampled image type and cache the result.
    auto sampled_image_type = result_op();
    sampled_image_type_id = sampled_image_type.to_i();
    auto texture_type_id = GenerateTypeIfNeeded(texture_type);
    push_type(spv::Op::OpTypeSampledImage,
              {sampled_image_type, Operand::Int(texture_type_id)});
    texture_type_name_to_sampled_image_type_id_[texture_type->type_name()] =
        sampled_image_type_id;
  }

  auto sampled_image = result_op();
  if (!push_function_inst(spv::Op::OpSampledImage,
                          {Operand::Int(sampled_image_type_id), sampled_image,
                           texture_operand, sampler_operand})) {
    return 0;
  }

  return sampled_image.to_i();
}

uint32_t Builder::GenerateBitcastExpression(
    const ast::BitcastExpression* expr) {
  auto result = result_op();
  auto result_id = result.to_i();

  auto result_type_id = GenerateTypeIfNeeded(TypeOf(expr));
  if (result_type_id == 0) {
    return 0;
  }

  auto val_id = GenerateExpressionWithLoadIfNeeded(expr->expr);
  if (val_id == 0) {
    return 0;
  }

  // Bitcast does not allow same types, just emit a CopyObject
  auto* to_type = TypeOf(expr)->UnwrapRef();
  auto* from_type = TypeOf(expr->expr)->UnwrapRef();
  if (to_type->type_name() == from_type->type_name()) {
    if (!push_function_inst(
            spv::Op::OpCopyObject,
            {Operand::Int(result_type_id), result, Operand::Int(val_id)})) {
      return 0;
    }
    return result_id;
  }

  if (!push_function_inst(spv::Op::OpBitcast, {Operand::Int(result_type_id),
                                               result, Operand::Int(val_id)})) {
    return 0;
  }

  return result_id;
}

bool Builder::GenerateConditionalBlock(
    const ast::Expression* cond,
    const ast::BlockStatement* true_body,
    size_t cur_else_idx,
    const ast::ElseStatementList& else_stmts) {
  auto cond_id = GenerateExpressionWithLoadIfNeeded(cond);
  if (cond_id == 0) {
    return false;
  }

  auto merge_block = result_op();
  auto merge_block_id = merge_block.to_i();

  if (!push_function_inst(spv::Op::OpSelectionMerge,
                          {Operand::Int(merge_block_id),
                           Operand::Int(SpvSelectionControlMaskNone)})) {
    return false;
  }

  auto true_block = result_op();
  auto true_block_id = true_block.to_i();

  // if there are no more else statements we branch on false to the merge
  // block otherwise we branch to the false block
  auto false_block_id =
      cur_else_idx < else_stmts.size() ? next_id() : merge_block_id;

  if (!push_function_inst(spv::Op::OpBranchConditional,
                          {Operand::Int(cond_id), Operand::Int(true_block_id),
                           Operand::Int(false_block_id)})) {
    return false;
  }

  // Output true block
  if (!GenerateLabel(true_block_id)) {
    return false;
  }
  if (!GenerateBlockStatement(true_body)) {
    return false;
  }
  // We only branch if the last element of the body didn't already branch.
  if (InsideBasicBlock()) {
    if (!push_function_inst(spv::Op::OpBranch,
                            {Operand::Int(merge_block_id)})) {
      return false;
    }
  }

  // Start the false block if needed
  if (false_block_id != merge_block_id) {
    if (!GenerateLabel(false_block_id)) {
      return false;
    }

    auto* else_stmt = else_stmts[cur_else_idx];
    // Handle the else case by just outputting the statements.
    if (!else_stmt->condition) {
      if (!GenerateBlockStatement(else_stmt->body)) {
        return false;
      }
    } else {
      if (!GenerateConditionalBlock(else_stmt->condition, else_stmt->body,
                                    cur_else_idx + 1, else_stmts)) {
        return false;
      }
    }
    if (InsideBasicBlock()) {
      if (!push_function_inst(spv::Op::OpBranch,
                              {Operand::Int(merge_block_id)})) {
        return false;
      }
    }
  }

  // Output the merge block
  return GenerateLabel(merge_block_id);
}

bool Builder::GenerateIfStatement(const ast::IfStatement* stmt) {
  if (!continuing_stack_.empty() &&
      stmt == continuing_stack_.back().last_statement->As<ast::IfStatement>()) {
    const ContinuingInfo& ci = continuing_stack_.back();
    // Match one of two patterns: the break-if and break-unless patterns.
    //
    // The break-if pattern:
    //  continuing { ...
    //    if (cond) { break; }
    //  }
    //
    // The break-unless pattern:
    //  continuing { ...
    //    if (cond) {} else {break;}
    //  }
    auto is_just_a_break = [](const ast::BlockStatement* block) {
      return block && (block->statements.size() == 1) &&
             block->Last()->Is<ast::BreakStatement>();
    };
    if (is_just_a_break(stmt->body) && stmt->else_statements.empty()) {
      // It's a break-if.
      TINT_ASSERT(Writer, !backedge_stack_.empty());
      const auto cond_id = GenerateExpressionWithLoadIfNeeded(stmt->condition);
      if (!cond_id) {
        return false;
      }
      backedge_stack_.back() =
          Backedge(spv::Op::OpBranchConditional,
                   {Operand::Int(cond_id), Operand::Int(ci.break_target_id),
                    Operand::Int(ci.loop_header_id)});
      return true;
    } else if (stmt->body->Empty()) {
      const auto& es = stmt->else_statements;
      if (es.size() == 1 && !es.back()->condition &&
          is_just_a_break(es.back()->body)) {
        // It's a break-unless.
        TINT_ASSERT(Writer, !backedge_stack_.empty());
        const auto cond_id =
            GenerateExpressionWithLoadIfNeeded(stmt->condition);
        if (!cond_id) {
          return false;
        }
        backedge_stack_.back() =
            Backedge(spv::Op::OpBranchConditional,
                     {Operand::Int(cond_id), Operand::Int(ci.loop_header_id),
                      Operand::Int(ci.break_target_id)});
        return true;
      }
    }
  }

  if (!GenerateConditionalBlock(stmt->condition, stmt->body, 0,
                                stmt->else_statements)) {
    return false;
  }
  return true;
}

bool Builder::GenerateSwitchStatement(const ast::SwitchStatement* stmt) {
  auto merge_block = result_op();
  auto merge_block_id = merge_block.to_i();

  merge_stack_.push_back(merge_block_id);

  auto cond_id = GenerateExpressionWithLoadIfNeeded(stmt->condition);
  if (cond_id == 0) {
    return false;
  }

  auto default_block = result_op();
  auto default_block_id = default_block.to_i();

  OperandList params = {Operand::Int(cond_id), Operand::Int(default_block_id)};

  std::vector<uint32_t> case_ids;
  for (const auto* item : stmt->body) {
    if (item->IsDefault()) {
      case_ids.push_back(default_block_id);
      continue;
    }

    auto block = result_op();
    auto block_id = block.to_i();

    case_ids.push_back(block_id);
    for (auto* selector : item->selectors) {
      auto* int_literal = selector->As<ast::IntLiteralExpression>();
      if (!int_literal) {
        error_ = "expected integer literal for switch case label";
        return false;
      }

      params.push_back(Operand::Int(int_literal->ValueAsU32()));
      params.push_back(Operand::Int(block_id));
    }
  }

  if (!push_function_inst(spv::Op::OpSelectionMerge,
                          {Operand::Int(merge_block_id),
                           Operand::Int(SpvSelectionControlMaskNone)})) {
    return false;
  }
  if (!push_function_inst(spv::Op::OpSwitch, params)) {
    return false;
  }

  bool generated_default = false;
  auto& body = stmt->body;
  // We output the case statements in order they were entered in the original
  // source. Each fallthrough goes to the next case entry, so is a forward
  // branch, otherwise the branch is to the merge block which comes after
  // the switch statement.
  for (uint32_t i = 0; i < body.size(); i++) {
    auto* item = body[i];

    if (item->IsDefault()) {
      generated_default = true;
    }

    if (!GenerateLabel(case_ids[i])) {
      return false;
    }
    if (!GenerateBlockStatement(item->body)) {
      return false;
    }

    if (LastIsFallthrough(item->body)) {
      if (i == (body.size() - 1)) {
        // This case is caught by Resolver validation
        TINT_UNREACHABLE(Writer, builder_.Diagnostics());
        return false;
      }
      if (!push_function_inst(spv::Op::OpBranch,
                              {Operand::Int(case_ids[i + 1])})) {
        return false;
      }
    } else if (InsideBasicBlock()) {
      if (!push_function_inst(spv::Op::OpBranch,
                              {Operand::Int(merge_block_id)})) {
        return false;
      }
    }
  }

  if (!generated_default) {
    if (!GenerateLabel(default_block_id)) {
      return false;
    }
    if (!push_function_inst(spv::Op::OpBranch,
                            {Operand::Int(merge_block_id)})) {
      return false;
    }
  }

  merge_stack_.pop_back();

  return GenerateLabel(merge_block_id);
}

bool Builder::GenerateReturnStatement(const ast::ReturnStatement* stmt) {
  if (stmt->value) {
    auto val_id = GenerateExpressionWithLoadIfNeeded(stmt->value);
    if (val_id == 0) {
      return false;
    }
    if (!push_function_inst(spv::Op::OpReturnValue, {Operand::Int(val_id)})) {
      return false;
    }
  } else {
    if (!push_function_inst(spv::Op::OpReturn, {})) {
      return false;
    }
  }

  return true;
}

bool Builder::GenerateLoopStatement(const ast::LoopStatement* stmt) {
  auto loop_header = result_op();
  auto loop_header_id = loop_header.to_i();
  if (!push_function_inst(spv::Op::OpBranch, {Operand::Int(loop_header_id)})) {
    return false;
  }
  if (!GenerateLabel(loop_header_id)) {
    return false;
  }

  auto merge_block = result_op();
  auto merge_block_id = merge_block.to_i();
  auto continue_block = result_op();
  auto continue_block_id = continue_block.to_i();

  auto body_block = result_op();
  auto body_block_id = body_block.to_i();

  if (!push_function_inst(
          spv::Op::OpLoopMerge,
          {Operand::Int(merge_block_id), Operand::Int(continue_block_id),
           Operand::Int(SpvLoopControlMaskNone)})) {
    return false;
  }

  continue_stack_.push_back(continue_block_id);
  merge_stack_.push_back(merge_block_id);

  // Usually, the backedge is a simple branch.  This will be modified if the
  // backedge block in the continuing construct has an exiting edge.
  backedge_stack_.emplace_back(spv::Op::OpBranch,
                               OperandList{Operand::Int(loop_header_id)});

  if (!push_function_inst(spv::Op::OpBranch, {Operand::Int(body_block_id)})) {
    return false;
  }
  if (!GenerateLabel(body_block_id)) {
    return false;
  }

  // We need variables from the body to be visible in the continuing block, so
  // manage scope outside of GenerateBlockStatement.
  {
    scope_stack_.Push();
    TINT_DEFER(scope_stack_.Pop());

    if (!GenerateBlockStatementWithoutScoping(stmt->body)) {
      return false;
    }

    // We only branch if the last element of the body didn't already branch.
    if (InsideBasicBlock()) {
      if (!push_function_inst(spv::Op::OpBranch,
                              {Operand::Int(continue_block_id)})) {
        return false;
      }
    }

    if (!GenerateLabel(continue_block_id)) {
      return false;
    }
    if (stmt->continuing && !stmt->continuing->Empty()) {
      continuing_stack_.emplace_back(stmt->continuing->Last(), loop_header_id,
                                     merge_block_id);
      if (!GenerateBlockStatementWithoutScoping(stmt->continuing)) {
        return false;
      }
      continuing_stack_.pop_back();
    }
  }

  // Generate the backedge.
  TINT_ASSERT(Writer, !backedge_stack_.empty());
  const Backedge& backedge = backedge_stack_.back();
  if (!push_function_inst(backedge.opcode, backedge.operands)) {
    return false;
  }
  backedge_stack_.pop_back();

  merge_stack_.pop_back();
  continue_stack_.pop_back();

  return GenerateLabel(merge_block_id);
}

bool Builder::GenerateStatement(const ast::Statement* stmt) {
  return Switch(
      stmt,
      [&](const ast::AssignmentStatement* a) {
        return GenerateAssignStatement(a);
      },
      [&](const ast::BlockStatement* b) {  //
        return GenerateBlockStatement(b);
      },
      [&](const ast::BreakStatement* b) {  //
        return GenerateBreakStatement(b);
      },
      [&](const ast::CallStatement* c) {
        return GenerateCallExpression(c->expr) != 0;
      },
      [&](const ast::ContinueStatement* c) {
        return GenerateContinueStatement(c);
      },
      [&](const ast::DiscardStatement* d) {
        return GenerateDiscardStatement(d);
      },
      [&](const ast::FallthroughStatement*) {
        // Do nothing here, the fallthrough gets handled by the switch code.
        return true;
      },
      [&](const ast::IfStatement* i) {  //
        return GenerateIfStatement(i);
      },
      [&](const ast::LoopStatement* l) {  //
        return GenerateLoopStatement(l);
      },
      [&](const ast::ReturnStatement* r) {  //
        return GenerateReturnStatement(r);
      },
      [&](const ast::SwitchStatement* s) {  //
        return GenerateSwitchStatement(s);
      },
      [&](const ast::VariableDeclStatement* v) {
        return GenerateVariableDeclStatement(v);
      },
      [&](Default) {
        error_ = "Unknown statement: " + std::string(stmt->TypeInfo().name);
        return false;
      });
}

bool Builder::GenerateVariableDeclStatement(
    const ast::VariableDeclStatement* stmt) {
  return GenerateFunctionVariable(stmt->variable);
}

uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) {
  if (type == nullptr) {
    error_ = "attempting to generate type from null type";
    return 0;
  }

  // Atomics are a type in WGSL, but aren't a distinct type in SPIR-V.
  // Just emit the type inside the atomic.
  if (auto* atomic = type->As<sem::Atomic>()) {
    return GenerateTypeIfNeeded(atomic->Type());
  }

  // Pointers and references with differing accesses should not result in a
  // different SPIR-V types, so we explicitly ignore the access.
  // Pointers and References both map to a SPIR-V pointer type.
  // Transform a Reference to a Pointer to prevent these having duplicated
  // definitions in the generated SPIR-V. Note that nested pointers and
  // references are not legal in WGSL, so only considering the top-level type is
  // fine.
  std::string type_name;
  if (auto* ptr = type->As<sem::Pointer>()) {
    type_name =
        sem::Pointer(ptr->StoreType(), ptr->StorageClass(), ast::kReadWrite)
            .type_name();
  } else if (auto* ref = type->As<sem::Reference>()) {
    type_name =
        sem::Pointer(ref->StoreType(), ref->StorageClass(), ast::kReadWrite)
            .type_name();
  } else {
    type_name = type->type_name();
  }

  return utils::GetOrCreate(type_name_to_id_, type_name, [&]() -> uint32_t {
    auto result = result_op();
    auto id = result.to_i();
    bool ok = Switch(
        type,
        [&](const sem::Array* arr) {  //
          return GenerateArrayType(arr, result);
        },
        [&](const sem::Bool*) {
          push_type(spv::Op::OpTypeBool, {result});
          return true;
        },
        [&](const sem::F32*) {
          push_type(spv::Op::OpTypeFloat, {result, Operand::Int(32)});
          return true;
        },
        [&](const sem::I32*) {
          push_type(spv::Op::OpTypeInt,
                    {result, Operand::Int(32), Operand::Int(1)});
          return true;
        },
        [&](const sem::Matrix* mat) {  //
          return GenerateMatrixType(mat, result);
        },
        [&](const sem::Pointer* ptr) {  //
          return GeneratePointerType(ptr, result);
        },
        [&](const sem::Reference* ref) {  //
          return GenerateReferenceType(ref, result);
        },
        [&](const sem::Struct* str) {  //
          return GenerateStructType(str, result);
        },
        [&](const sem::U32*) {
          push_type(spv::Op::OpTypeInt,
                    {result, Operand::Int(32), Operand::Int(0)});
          return true;
        },
        [&](const sem::Vector* vec) {  //
          return GenerateVectorType(vec, result);
        },
        [&](const sem::Void*) {
          push_type(spv::Op::OpTypeVoid, {result});
          return true;
        },
        [&](const sem::StorageTexture* tex) {
          if (!GenerateTextureType(tex, result)) {
            return false;
          }

          // Register all three access types of StorageTexture names. In
          // SPIR-V, we must output a single type, while the variable is
          // annotated with the access type. Doing this ensures we de-dupe.
          type_name_to_id_[builder_
                               .create<sem::StorageTexture>(
                                   tex->dim(), tex->texel_format(),
                                   ast::Access::kRead, tex->type())
                               ->type_name()] = id;
          type_name_to_id_[builder_
                               .create<sem::StorageTexture>(
                                   tex->dim(), tex->texel_format(),
                                   ast::Access::kWrite, tex->type())
                               ->type_name()] = id;
          type_name_to_id_[builder_
                               .create<sem::StorageTexture>(
                                   tex->dim(), tex->texel_format(),
                                   ast::Access::kReadWrite, tex->type())
                               ->type_name()] = id;
          return true;
        },
        [&](const sem::Texture* tex) {
          return GenerateTextureType(tex, result);
        },
        [&](const sem::Sampler*) {
          push_type(spv::Op::OpTypeSampler, {result});

          // Register both of the sampler type names. In SPIR-V they're the same
          // sampler type, so we need to match that when we do the dedup check.
          type_name_to_id_["__sampler_sampler"] = id;
          type_name_to_id_["__sampler_comparison"] = id;
          return true;
        },
        [&](Default) {
          error_ = "unable to convert type: " + type->type_name();
          return false;
        });

    if (!ok) {
      return 0;
    }

    return id;
  });
}

bool Builder::GenerateTextureType(const sem::Texture* texture,
                                  const Operand& result) {
  uint32_t array_literal = 0u;
  const auto dim = texture->dim();
  if (dim == ast::TextureDimension::k2dArray ||
      dim == ast::TextureDimension::kCubeArray) {
    array_literal = 1u;
  }

  uint32_t dim_literal = SpvDim2D;
  if (dim == ast::TextureDimension::k1d) {
    dim_literal = SpvDim1D;
    if (texture->Is<sem::SampledTexture>()) {
      push_capability(SpvCapabilitySampled1D);
    } else if (texture->Is<sem::StorageTexture>()) {
      push_capability(SpvCapabilityImage1D);
    }
  }
  if (dim == ast::TextureDimension::k3d) {
    dim_literal = SpvDim3D;
  }
  if (dim == ast::TextureDimension::kCube ||
      dim == ast::TextureDimension::kCubeArray) {
    dim_literal = SpvDimCube;
  }

  uint32_t ms_literal = 0u;
  if (texture->IsAnyOf<sem::MultisampledTexture,
                       sem::DepthMultisampledTexture>()) {
    ms_literal = 1u;
  }

  uint32_t depth_literal = 0u;
  if (texture->IsAnyOf<sem::DepthTexture, sem::DepthMultisampledTexture>()) {
    depth_literal = 1u;
  }

  uint32_t sampled_literal = 2u;
  if (texture->IsAnyOf<sem::MultisampledTexture, sem::SampledTexture,
                       sem::DepthTexture, sem::DepthMultisampledTexture>()) {
    sampled_literal = 1u;
  }

  if (dim == ast::TextureDimension::kCubeArray) {
    if (texture->IsAnyOf<sem::SampledTexture, sem::DepthTexture>()) {
      push_capability(SpvCapabilitySampledCubeArray);
    }
  }

  uint32_t type_id = Switch(
      texture,
      [&](const sem::DepthTexture*) {
        return GenerateTypeIfNeeded(builder_.create<sem::F32>());
      },
      [&](const sem::DepthMultisampledTexture*) {
        return GenerateTypeIfNeeded(builder_.create<sem::F32>());
      },
      [&](const sem::SampledTexture* t) {
        return GenerateTypeIfNeeded(t->type());
      },
      [&](const sem::MultisampledTexture* t) {
        return GenerateTypeIfNeeded(t->type());
      },
      [&](const sem::StorageTexture* t) {
        return GenerateTypeIfNeeded(t->type());
      },
      [&](Default) -> uint32_t {  //
        return 0u;
      });
  if (type_id == 0u) {
    return false;
  }

  uint32_t format_literal = SpvImageFormat_::SpvImageFormatUnknown;
  if (auto* t = texture->As<sem::StorageTexture>()) {
    format_literal = convert_texel_format_to_spv(t->texel_format());
  }

  push_type(spv::Op::OpTypeImage,
            {result, Operand::Int(type_id), Operand::Int(dim_literal),
             Operand::Int(depth_literal), Operand::Int(array_literal),
             Operand::Int(ms_literal), Operand::Int(sampled_literal),
             Operand::Int(format_literal)});

  return true;
}

bool Builder::GenerateArrayType(const sem::Array* ary, const Operand& result) {
  auto elem_type = GenerateTypeIfNeeded(ary->ElemType());
  if (elem_type == 0) {
    return false;
  }

  auto result_id = result.to_i();
  if (ary->IsRuntimeSized()) {
    push_type(spv::Op::OpTypeRuntimeArray, {result, Operand::Int(elem_type)});
  } else {
    auto len_id = GenerateConstantIfNeeded(ScalarConstant::U32(ary->Count()));
    if (len_id == 0) {
      return false;
    }

    push_type(spv::Op::OpTypeArray,
              {result, Operand::Int(elem_type), Operand::Int(len_id)});
  }

  push_annot(spv::Op::OpDecorate,
             {Operand::Int(result_id), Operand::Int(SpvDecorationArrayStride),
              Operand::Int(ary->Stride())});
  return true;
}

bool Builder::GenerateMatrixType(const sem::Matrix* mat,
                                 const Operand& result) {
  auto* col_type = builder_.create<sem::Vector>(mat->type(), mat->rows());
  auto col_type_id = GenerateTypeIfNeeded(col_type);
  if (has_error()) {
    return false;
  }

  push_type(spv::Op::OpTypeMatrix,
            {result, Operand::Int(col_type_id), Operand::Int(mat->columns())});
  return true;
}

bool Builder::GeneratePointerType(const sem::Pointer* ptr,
                                  const Operand& result) {
  auto subtype_id = GenerateTypeIfNeeded(ptr->StoreType());
  if (subtype_id == 0) {
    return false;
  }

  auto stg_class = ConvertStorageClass(ptr->StorageClass());
  if (stg_class == SpvStorageClassMax) {
    error_ = "invalid storage class for pointer";
    return false;
  }

  push_type(spv::Op::OpTypePointer,
            {result, Operand::Int(stg_class), Operand::Int(subtype_id)});

  return true;
}

bool Builder::GenerateReferenceType(const sem::Reference* ref,
                                    const Operand& result) {
  auto subtype_id = GenerateTypeIfNeeded(ref->StoreType());
  if (subtype_id == 0) {
    return false;
  }

  auto stg_class = ConvertStorageClass(ref->StorageClass());
  if (stg_class == SpvStorageClassMax) {
    error_ = "invalid storage class for reference";
    return false;
  }

  push_type(spv::Op::OpTypePointer,
            {result, Operand::Int(stg_class), Operand::Int(subtype_id)});

  return true;
}

bool Builder::GenerateStructType(const sem::Struct* struct_type,
                                 const Operand& result) {
  auto struct_id = result.to_i();

  if (struct_type->Name().IsValid()) {
    push_debug(
        spv::Op::OpName,
        {Operand::Int(struct_id),
         Operand::String(builder_.Symbols().NameFor(struct_type->Name()))});
  }

  OperandList ops;
  ops.push_back(result);

  auto* decl = struct_type->Declaration();
  if (decl &&
      ast::HasAttribute<transform::AddSpirvBlockAttribute::SpirvBlockAttribute>(
          decl->attributes)) {
    push_annot(spv::Op::OpDecorate,
               {Operand::Int(struct_id), Operand::Int(SpvDecorationBlock)});
  }

  for (uint32_t i = 0; i < struct_type->Members().size(); ++i) {
    auto mem_id = GenerateStructMember(struct_id, i, struct_type->Members()[i]);
    if (mem_id == 0) {
      return false;
    }

    ops.push_back(Operand::Int(mem_id));
  }

  push_type(spv::Op::OpTypeStruct, std::move(ops));
  return true;
}

uint32_t Builder::GenerateStructMember(uint32_t struct_id,
                                       uint32_t idx,
                                       const sem::StructMember* member) {
  push_debug(spv::Op::OpMemberName,
             {Operand::Int(struct_id), Operand::Int(idx),
              Operand::String(builder_.Symbols().NameFor(member->Name()))});

  // Note: This will generate layout annotations for *all* structs, whether or
  // not they are used in host-shareable variables. This is officially ok in
  // SPIR-V 1.0 through 1.3. If / when we migrate to using SPIR-V 1.4 we'll have
  // to only generate the layout info for structs used for certain storage
  // classes.

  push_annot(
      spv::Op::OpMemberDecorate,
      {Operand::Int(struct_id), Operand::Int(idx),
       Operand::Int(SpvDecorationOffset), Operand::Int(member->Offset())});

  // Infer and emit matrix layout.
  auto* matrix_type = GetNestedMatrixType(member->Type());
  if (matrix_type) {
    push_annot(spv::Op::OpMemberDecorate,
               {Operand::Int(struct_id), Operand::Int(idx),
                Operand::Int(SpvDecorationColMajor)});
    if (!matrix_type->type()->Is<sem::F32>()) {
      error_ = "matrix scalar element type must be f32";
      return 0;
    }
    const auto scalar_elem_size = 4;
    const auto effective_row_count = (matrix_type->rows() == 2) ? 2 : 4;
    push_annot(spv::Op::OpMemberDecorate,
               {Operand::Int(struct_id), Operand::Int(idx),
                Operand::Int(SpvDecorationMatrixStride),
                Operand::Int(effective_row_count * scalar_elem_size)});
  }

  return GenerateTypeIfNeeded(member->Type());
}

bool Builder::GenerateVectorType(const sem::Vector* vec,
                                 const Operand& result) {
  auto type_id = GenerateTypeIfNeeded(vec->type());
  if (has_error()) {
    return false;
  }

  push_type(spv::Op::OpTypeVector,
            {result, Operand::Int(type_id), Operand::Int(vec->Width())});
  return true;
}

SpvStorageClass Builder::ConvertStorageClass(ast::StorageClass klass) const {
  switch (klass) {
    case ast::StorageClass::kInvalid:
      return SpvStorageClassMax;
    case ast::StorageClass::kInput:
      return SpvStorageClassInput;
    case ast::StorageClass::kOutput:
      return SpvStorageClassOutput;
    case ast::StorageClass::kUniform:
      return SpvStorageClassUniform;
    case ast::StorageClass::kWorkgroup:
      return SpvStorageClassWorkgroup;
    case ast::StorageClass::kUniformConstant:
      return SpvStorageClassUniformConstant;
    case ast::StorageClass::kStorage:
      return SpvStorageClassStorageBuffer;
    case ast::StorageClass::kPrivate:
      return SpvStorageClassPrivate;
    case ast::StorageClass::kFunction:
      return SpvStorageClassFunction;
    case ast::StorageClass::kNone:
      break;
  }
  return SpvStorageClassMax;
}

SpvBuiltIn Builder::ConvertBuiltin(ast::Builtin builtin,
                                   ast::StorageClass storage) {
  switch (builtin) {
    case ast::Builtin::kPosition:
      if (storage == ast::StorageClass::kInput) {
        return SpvBuiltInFragCoord;
      } else if (storage == ast::StorageClass::kOutput) {
        return SpvBuiltInPosition;
      } else {
        TINT_ICE(Writer, builder_.Diagnostics())
            << "invalid storage class for builtin";
        break;
      }
    case ast::Builtin::kVertexIndex:
      return SpvBuiltInVertexIndex;
    case ast::Builtin::kInstanceIndex:
      return SpvBuiltInInstanceIndex;
    case ast::Builtin::kFrontFacing:
      return SpvBuiltInFrontFacing;
    case ast::Builtin::kFragDepth:
      return SpvBuiltInFragDepth;
    case ast::Builtin::kLocalInvocationId:
      return SpvBuiltInLocalInvocationId;
    case ast::Builtin::kLocalInvocationIndex:
      return SpvBuiltInLocalInvocationIndex;
    case ast::Builtin::kGlobalInvocationId:
      return SpvBuiltInGlobalInvocationId;
    case ast::Builtin::kPointSize:
      return SpvBuiltInPointSize;
    case ast::Builtin::kWorkgroupId:
      return SpvBuiltInWorkgroupId;
    case ast::Builtin::kNumWorkgroups:
      return SpvBuiltInNumWorkgroups;
    case ast::Builtin::kSampleIndex:
      push_capability(SpvCapabilitySampleRateShading);
      return SpvBuiltInSampleId;
    case ast::Builtin::kSampleMask:
      return SpvBuiltInSampleMask;
    case ast::Builtin::kNone:
      break;
  }
  return SpvBuiltInMax;
}

void Builder::AddInterpolationDecorations(uint32_t id,
                                          ast::InterpolationType type,
                                          ast::InterpolationSampling sampling) {
  switch (type) {
    case ast::InterpolationType::kLinear:
      push_annot(spv::Op::OpDecorate,
                 {Operand::Int(id), Operand::Int(SpvDecorationNoPerspective)});
      break;
    case ast::InterpolationType::kFlat:
      push_annot(spv::Op::OpDecorate,
                 {Operand::Int(id), Operand::Int(SpvDecorationFlat)});
      break;
    case ast::InterpolationType::kPerspective:
      break;
  }
  switch (sampling) {
    case ast::InterpolationSampling::kCentroid:
      push_annot(spv::Op::OpDecorate,
                 {Operand::Int(id), Operand::Int(SpvDecorationCentroid)});
      break;
    case ast::InterpolationSampling::kSample:
      push_capability(SpvCapabilitySampleRateShading);
      push_annot(spv::Op::OpDecorate,
                 {Operand::Int(id), Operand::Int(SpvDecorationSample)});
      break;
    case ast::InterpolationSampling::kCenter:
    case ast::InterpolationSampling::kNone:
      break;
  }
}

SpvImageFormat Builder::convert_texel_format_to_spv(
    const ast::TexelFormat format) {
  switch (format) {
    case ast::TexelFormat::kR32Uint:
      return SpvImageFormatR32ui;
    case ast::TexelFormat::kR32Sint:
      return SpvImageFormatR32i;
    case ast::TexelFormat::kR32Float:
      return SpvImageFormatR32f;
    case ast::TexelFormat::kRgba8Unorm:
      return SpvImageFormatRgba8;
    case ast::TexelFormat::kRgba8Snorm:
      return SpvImageFormatRgba8Snorm;
    case ast::TexelFormat::kRgba8Uint:
      return SpvImageFormatRgba8ui;
    case ast::TexelFormat::kRgba8Sint:
      return SpvImageFormatRgba8i;
    case ast::TexelFormat::kRg32Uint:
      push_capability(SpvCapabilityStorageImageExtendedFormats);
      return SpvImageFormatRg32ui;
    case ast::TexelFormat::kRg32Sint:
      push_capability(SpvCapabilityStorageImageExtendedFormats);
      return SpvImageFormatRg32i;
    case ast::TexelFormat::kRg32Float:
      push_capability(SpvCapabilityStorageImageExtendedFormats);
      return SpvImageFormatRg32f;
    case ast::TexelFormat::kRgba16Uint:
      return SpvImageFormatRgba16ui;
    case ast::TexelFormat::kRgba16Sint:
      return SpvImageFormatRgba16i;
    case ast::TexelFormat::kRgba16Float:
      return SpvImageFormatRgba16f;
    case ast::TexelFormat::kRgba32Uint:
      return SpvImageFormatRgba32ui;
    case ast::TexelFormat::kRgba32Sint:
      return SpvImageFormatRgba32i;
    case ast::TexelFormat::kRgba32Float:
      return SpvImageFormatRgba32f;
    case ast::TexelFormat::kNone:
      return SpvImageFormatUnknown;
  }
  return SpvImageFormatUnknown;
}

bool Builder::push_function_inst(spv::Op op, const OperandList& operands) {
  if (functions_.empty()) {
    std::ostringstream ss;
    ss << "Internal error: trying to add SPIR-V instruction " << int(op)
       << " outside a function";
    error_ = ss.str();
    return false;
  }
  functions_.back().push_inst(op, operands);
  return true;
}

bool Builder::InsideBasicBlock() const {
  if (functions_.empty()) {
    return false;
  }
  const auto& instructions = functions_.back().instructions();
  if (instructions.empty()) {
    // The Function object does not explicitly represent its entry block
    // label.  So return *true* because an empty list means the only
    // thing in the function is that entry block label.
    return true;
  }
  const auto& inst = instructions.back();
  switch (inst.opcode()) {
    case spv::Op::OpBranch:
    case spv::Op::OpBranchConditional:
    case spv::Op::OpSwitch:
    case spv::Op::OpReturn:
    case spv::Op::OpReturnValue:
    case spv::Op::OpUnreachable:
    case spv::Op::OpKill:
    case spv::Op::OpTerminateInvocation:
      return false;
    default:
      break;
  }
  return true;
}

Builder::ContinuingInfo::ContinuingInfo(
    const ast::Statement* the_last_statement,
    uint32_t loop_id,
    uint32_t break_id)
    : last_statement(the_last_statement),
      loop_header_id(loop_id),
      break_target_id(break_id) {
  TINT_ASSERT(Writer, last_statement != nullptr);
  TINT_ASSERT(Writer, loop_header_id != 0u);
  TINT_ASSERT(Writer, break_target_id != 0u);
}

Builder::Backedge::Backedge(spv::Op the_opcode, OperandList the_operands)
    : opcode(the_opcode), operands(the_operands) {}

Builder::Backedge::Backedge(const Builder::Backedge& other) = default;
Builder::Backedge& Builder::Backedge::operator=(
    const Builder::Backedge& other) = default;
Builder::Backedge::~Backedge() = default;

}  // namespace spirv
}  // namespace writer
}  // namespace tint
