// Copyright 2022 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/tint/lang/core/constant/eval.h"

#include <algorithm>
#include <iomanip>
#include <limits>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>

#include "src/tint/lang/core/constant/composite.h"
#include "src/tint/lang/core/constant/scalar.h"
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/constant/value.h"
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/number.h"
#include "src/tint/lang/core/type/abstract_float.h"
#include "src/tint/lang/core/type/abstract_int.h"
#include "src/tint/lang/core/type/array.h"
#include "src/tint/lang/core/type/bool.h"
#include "src/tint/lang/core/type/f16.h"
#include "src/tint/lang/core/type/f32.h"
#include "src/tint/lang/core/type/i32.h"
#include "src/tint/lang/core/type/matrix.h"
#include "src/tint/lang/core/type/struct.h"
#include "src/tint/lang/core/type/u32.h"
#include "src/tint/lang/core/type/vector.h"
#include "src/tint/utils/containers/map.h"
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/diagnostic/diagnostic.h"
#include "src/tint/utils/macros/compiler.h"
#include "src/tint/utils/memory/bitcast.h"
#include "src/tint/utils/rtti/switch.h"
#include "src/tint/utils/text/string_stream.h"

using namespace tint::core::fluent_types;     // NOLINT
using namespace tint::core::number_suffixes;  // NOLINT

namespace tint::core::constant {
namespace {

/// Returns the first element of a parameter pack
template <typename T>
T First(T&& first, ...) {
    return std::forward<T>(first);
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_iu32(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::I32*) { return f(cs->template ValueAs<i32>()...); },
        [&](const core::type::U32*) { return f(cs->template ValueAs<u32>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_ia_iu32(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::AbstractInt*) { return f(cs->template ValueAs<AInt>()...); },
        [&](const core::type::I32*) { return f(cs->template ValueAs<i32>()...); },
        [&](const core::type::U32*) { return f(cs->template ValueAs<u32>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_ia_iu32_bool(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::AbstractInt*) { return f(cs->template ValueAs<AInt>()...); },
        [&](const core::type::I32*) { return f(cs->template ValueAs<i32>()...); },
        [&](const core::type::U32*) { return f(cs->template ValueAs<u32>()...); },
        [&](const core::type::Bool*) { return f(cs->template ValueAs<bool>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_fia_fi32_f16(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::AbstractInt*) { return f(cs->template ValueAs<AInt>()...); },
        [&](const core::type::AbstractFloat*) { return f(cs->template ValueAs<AFloat>()...); },
        [&](const core::type::F32*) { return f(cs->template ValueAs<f32>()...); },
        [&](const core::type::I32*) { return f(cs->template ValueAs<i32>()...); },
        [&](const core::type::F16*) { return f(cs->template ValueAs<f16>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_fia_fiu32_f16(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::AbstractInt*) { return f(cs->template ValueAs<AInt>()...); },
        [&](const core::type::AbstractFloat*) { return f(cs->template ValueAs<AFloat>()...); },
        [&](const core::type::F32*) { return f(cs->template ValueAs<f32>()...); },
        [&](const core::type::I32*) { return f(cs->template ValueAs<i32>()...); },
        [&](const core::type::U32*) { return f(cs->template ValueAs<u32>()...); },
        [&](const core::type::F16*) { return f(cs->template ValueAs<f16>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_fia_fiu32_f16_bool(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::AbstractInt*) { return f(cs->template ValueAs<AInt>()...); },
        [&](const core::type::AbstractFloat*) { return f(cs->template ValueAs<AFloat>()...); },
        [&](const core::type::F32*) { return f(cs->template ValueAs<f32>()...); },
        [&](const core::type::I32*) { return f(cs->template ValueAs<i32>()...); },
        [&](const core::type::U32*) { return f(cs->template ValueAs<u32>()...); },
        [&](const core::type::F16*) { return f(cs->template ValueAs<f16>()...); },
        [&](const core::type::Bool*) { return f(cs->template ValueAs<bool>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_fa_f32_f16(F&& f, CONSTANTS&&... cs) {
    return Switch(
        First(cs...)->Type(),  //
        [&](const core::type::AbstractFloat*) { return f(cs->template ValueAs<AFloat>()...); },
        [&](const core::type::F32*) { return f(cs->template ValueAs<f32>()...); },
        [&](const core::type::F16*) { return f(cs->template ValueAs<f16>()...); });
}

/// Helper that calls `f` passing in the value of all `cs`.
/// Calls `f` with all constants cast to the type of the first `cs` argument.
template <typename F, typename... CONSTANTS>
auto Dispatch_bool(F&& f, CONSTANTS&&... cs) {
    return f(cs->template ValueAs<bool>()...);
}

/// ZeroTypeDispatch is a helper for calling the function `f`, passing a single zero-value argument
/// of the C++ type that corresponds to the core::type::Type `type`. For example, calling
/// `ZeroTypeDispatch()` with a type of `type::I32*` will call the function f with a single argument
/// of `i32(0)`.
/// @returns the value returned by calling `f`.
/// @note `type` must be a scalar or abstract numeric type. Other types will not call `f`, and will
/// return the zero-initialized value of the return type for `f`.
template <typename F>
auto ZeroTypeDispatch(const core::type::Type* type, F&& f) {
    return Switch(
        type,                                                            //
        [&](const core::type::AbstractInt*) { return f(AInt(0)); },      //
        [&](const core::type::AbstractFloat*) { return f(AFloat(0)); },  //
        [&](const core::type::I32*) { return f(i32(0)); },               //
        [&](const core::type::U32*) { return f(u32(0)); },               //
        [&](const core::type::F32*) { return f(f32(0)); },               //
        [&](const core::type::F16*) { return f(f16(0)); },               //
        [&](const core::type::Bool*) { return f(static_cast<bool>(0)); });
}

template <typename NumberT>
std::string OverflowErrorMessage(NumberT lhs, const char* op, NumberT rhs) {
    StringStream ss;
    ss << "'" << lhs.value << " " << op << " " << rhs.value << "' cannot be represented as '"
       << FriendlyName<NumberT>() << "'";
    return ss.str();
}

template <typename VALUE_TY>
std::string OverflowErrorMessage(VALUE_TY value, std::string_view target_ty) {
    StringStream ss;
    ss << "value " << value << " cannot be represented as "
       << "'" << target_ty << "'";
    return ss.str();
}

template <typename NumberT>
std::string OverflowExpErrorMessage(std::string_view base, NumberT exp) {
    StringStream ss;
    ss << base << "^" << exp << " cannot be represented as "
       << "'" << FriendlyName<NumberT>() << "'";
    return ss.str();
}

/// @returns the number of consecutive leading bits in `@p e` set to `@p bit_value_to_count`.
template <typename T>
std::make_unsigned_t<T> CountLeadingBits(T e, T bit_value_to_count) {
    using UT = std::make_unsigned_t<T>;
    constexpr UT kNumBits = sizeof(UT) * 8;
    constexpr UT kLeftMost = UT{1} << (kNumBits - 1);
    const UT b = bit_value_to_count == 0 ? UT{0} : kLeftMost;

    auto v = static_cast<UT>(e);
    auto count = UT{0};
    while ((count < kNumBits) && ((v & kLeftMost) == b)) {
        ++count;
        v <<= 1;
    }
    return count;
}

/// @returns the number of consecutive trailing bits set to `@p bit_value_to_count` in `@p e`
template <typename T>
std::make_unsigned_t<T> CountTrailingBits(T e, T bit_value_to_count) {
    using UT = std::make_unsigned_t<T>;
    constexpr UT kNumBits = sizeof(UT) * 8;
    constexpr UT kRightMost = UT{1};
    const UT b = static_cast<UT>(bit_value_to_count);

    auto v = static_cast<UT>(e);
    auto count = UT{0};
    while ((count < kNumBits) && ((v & kRightMost) == b)) {
        ++count;
        v >>= 1;
    }
    return count;
}

/// Common data for constant conversion.
struct ConvertContext {
    Manager& mgr;
    diag::List& diags;
    const Source& source;
    bool use_runtime_semantics;
};

/// Converts the constant scalar value to the target type.
/// @returns the converted scalar, or nullptr on error.
template <typename T>
const ScalarBase* ScalarConvert(const Scalar<T>* scalar,
                                const core::type::Type* target_ty,
                                ConvertContext& ctx) {
    TINT_BEGIN_DISABLE_WARNING(UNREACHABLE_CODE);
    if (target_ty == scalar->type) {
        // If the types are identical, then no conversion is needed.
        return scalar;
    }
    return ZeroTypeDispatch(target_ty, [&](auto zero_to) -> const ScalarBase* {
        // `value` is the source value.
        // `FROM` is the source type.
        // `TO` is the target type.
        using TO = std::decay_t<decltype(zero_to)>;
        using FROM = T;
        if constexpr (std::is_same_v<TO, bool>) {
            // [x -> bool]
            return ctx.mgr.Get<Scalar<TO>>(target_ty, !scalar->IsZero());
        } else if constexpr (std::is_same_v<FROM, bool>) {
            // [bool -> x]
            return ctx.mgr.Get<Scalar<TO>>(target_ty, TO(scalar->value ? 1 : 0));
        } else if (auto conv = CheckedConvert<TO>(scalar->value)) {
            // Conversion success
            return ctx.mgr.Get<Scalar<TO>>(target_ty, conv.Get());
            // --- Below this point are the failure cases ---
        } else if constexpr (IsAbstract<FROM>) {
            // [abstract-numeric -> x] - materialization failure
            auto msg = OverflowErrorMessage(scalar->value, target_ty->FriendlyName());
            if (ctx.use_runtime_semantics) {
                ctx.diags.add_warning(tint::diag::System::Resolver, msg, ctx.source);
                switch (conv.Failure()) {
                    case ConversionFailure::kExceedsNegativeLimit:
                        return ctx.mgr.Get<Scalar<TO>>(target_ty, TO::Lowest());
                    case ConversionFailure::kExceedsPositiveLimit:
                        return ctx.mgr.Get<Scalar<TO>>(target_ty, TO::Highest());
                }
            } else {
                ctx.diags.add_error(tint::diag::System::Resolver, msg, ctx.source);
                return nullptr;
            }
        } else if constexpr (IsFloatingPoint<TO>) {
            // [x -> floating-point] - number not exactly representable
            // https://www.w3.org/TR/WGSL/#floating-point-conversion
            auto msg = OverflowErrorMessage(scalar->value, target_ty->FriendlyName());
            if (ctx.use_runtime_semantics) {
                ctx.diags.add_warning(tint::diag::System::Resolver, msg, ctx.source);
                switch (conv.Failure()) {
                    case ConversionFailure::kExceedsNegativeLimit:
                        return ctx.mgr.Get<Scalar<TO>>(target_ty, TO::Lowest());
                    case ConversionFailure::kExceedsPositiveLimit:
                        return ctx.mgr.Get<Scalar<TO>>(target_ty, TO::Highest());
                }
            } else {
                ctx.diags.add_error(tint::diag::System::Resolver, msg, ctx.source);
                return nullptr;
            }
        } else if constexpr (IsFloatingPoint<FROM>) {
            // [floating-point -> integer] - number not exactly representable
            // https://www.w3.org/TR/WGSL/#floating-point-conversion
            switch (conv.Failure()) {
                case ConversionFailure::kExceedsNegativeLimit:
                    return ctx.mgr.Get<Scalar<TO>>(target_ty, TO::Lowest());
                case ConversionFailure::kExceedsPositiveLimit:
                    return ctx.mgr.Get<Scalar<TO>>(target_ty, TO::Highest());
            }
        } else if constexpr (IsIntegral<FROM>) {
            // [integer -> integer] - number not exactly representable
            // Static cast
            return ctx.mgr.Get<Scalar<TO>>(target_ty, static_cast<TO>(scalar->value));
        }
        TINT_UNREACHABLE() << "Expression is not constant";
        return nullptr;
    });
    TINT_END_DISABLE_WARNING(UNREACHABLE_CODE);
}

/// Converts the constant value to the target type.
/// @returns the converted value, or nullptr on error.
const Value* ConvertInternal(const Value* root_value,
                             const core::type::Type* root_target_ty,
                             ConvertContext& ctx) {
    struct ActionConvert {
        const Value* value = nullptr;
        const core::type::Type* target_ty = nullptr;
    };
    struct ActionBuildSplat {
        size_t count = 0;
        const core::type::Type* type = nullptr;
    };
    struct ActionBuildComposite {
        size_t count = 0;
        const core::type::Type* type = nullptr;
    };
    using Action = std::variant<ActionConvert, ActionBuildSplat, ActionBuildComposite>;

    Vector<Action, 8> pending{
        ActionConvert{root_value, root_target_ty},
    };

    Vector<const Value*, 32> value_stack;

    while (!pending.IsEmpty()) {
        auto next = pending.Pop();

        if (auto* build = std::get_if<ActionBuildSplat>(&next)) {
            TINT_ASSERT(value_stack.Length() >= 1);
            auto* el = value_stack.Pop();
            value_stack.Push(ctx.mgr.Splat(build->type, el, build->count));
            continue;
        }

        if (auto* build = std::get_if<ActionBuildComposite>(&next)) {
            TINT_ASSERT(value_stack.Length() >= build->count);
            // Take build->count elements off the top of value_stack
            // Note: The values are ordered with the first composite value at the top of the stack.
            Vector<const Value*, 32> elements;
            elements.Reserve(build->count);
            for (size_t i = 0; i < build->count; i++) {
                elements.Push(value_stack.Pop());
            }
            // Build the composite
            value_stack.Push(ctx.mgr.Composite(build->type, std::move(elements)));
            continue;
        }

        auto* convert = std::get_if<ActionConvert>(&next);

        bool ok = Switch(
            convert->value,
            [&](const ScalarBase* scalar) {
                auto* converted = Switch(
                    scalar,
                    [&](const Scalar<AFloat>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    },
                    [&](const Scalar<AInt>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    },
                    [&](const Scalar<u32>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    },
                    [&](const Scalar<i32>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    },
                    [&](const Scalar<f32>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    },
                    [&](const Scalar<f16>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    },
                    [&](const Scalar<bool>* val) {
                        return ScalarConvert(val, convert->target_ty, ctx);
                    });
                if (!converted) {
                    return false;
                }
                value_stack.Push(converted);
                return true;
            },
            [&](const Splat* splat) {
                const core::type::Type* target_el_ty = nullptr;
                if (auto* str = convert->target_ty->As<core::type::Struct>()) {
                    // Structure conversion.
                    auto members = str->Members();
                    target_el_ty = members[0]->Type();

                    // Structures can only be converted during materialization. The user cannot
                    // declare the target structure type, so each member type must be the same
                    // default materialization type.
                    for (size_t i = 1; i < members.Length(); i++) {
                        if (members[i]->Type() != target_el_ty) {
                            TINT_ICE()
                                << "inconsistent target struct member types for SplatConvert";
                            return false;
                        }
                    }
                } else {
                    target_el_ty = convert->target_ty->Elements(convert->target_ty).type;
                }

                // Convert the single splatted element type.
                pending.Push(ActionBuildSplat{splat->count, convert->target_ty});
                pending.Push(ActionConvert{splat->el, target_el_ty});
                return true;
            },
            [&](const Composite* composite) {
                const size_t el_count = composite->NumElements();

                // Build the new composite from the converted element types.
                pending.Push(ActionBuildComposite{el_count, convert->target_ty});

                if (auto* str = convert->target_ty->As<core::type::Struct>()) {
                    if (TINT_UNLIKELY(str->Members().Length() != el_count)) {
                        TINT_ICE()
                            << "const-eval conversion of structure has mismatched element counts";
                        return false;
                    }
                    // Struct composites can have different types for each member.
                    auto members = str->Members();
                    for (size_t i = 0; i < el_count; i++) {
                        pending.Push(ActionConvert{composite->Index(i), members[i]->Type()});
                    }
                } else {
                    // Non-struct composites have the same type for all elements.
                    auto* el_ty = convert->target_ty->Elements(convert->target_ty).type;
                    for (size_t i = 0; i < el_count; i++) {
                        auto* el = composite->Index(i);
                        pending.Push(ActionConvert{el, el_ty});
                    }
                }

                return true;
            });
        if (!ok) {
            return nullptr;
        }
    }

    TINT_ASSERT(value_stack.Length() == 1);
    return value_stack.Pop();
}

/// TransformElements constructs a new constant of type `composite_ty` by applying the
/// transformation function `f` on each of the most deeply nested elements of 'cs'. Assumes that all
/// input constants `cs` are of the same arity (all scalars or all vectors of the same size).
/// If `f`'s last argument is a `size_t`, then the index of the most deeply nested element inside
/// the most deeply nested aggregate type will be passed in.
template <typename F, typename... CONSTANTS>
tint::traits::EnableIf<tint::traits::IsType<size_t, tint::traits::LastParameterType<F>>,
                       Eval::Result>
TransformElements(Manager& mgr,
                  const core::type::Type* composite_ty,
                  const F& f,
                  size_t index,
                  CONSTANTS&&... cs) {
    auto [el_ty, n] = First(cs...)->Type()->Elements();
    if (!el_ty) {
        return f(cs..., index);
    }

    auto* composite_el_ty = composite_ty->Elements(composite_ty).type;

    Vector<const Value*, 8> els;
    els.Reserve(n);
    for (uint32_t i = 0; i < n; i++) {
        if (auto el = TransformElements(mgr, composite_el_ty, f, index + i, cs->Index(i)...)) {
            els.Push(el.Get());

        } else {
            return el.Failure();
        }
    }
    return mgr.Composite(composite_ty, std::move(els));
}

/// Signature of a unary transformation callback
using UnaryTransform = std::function<Eval::Result(const Value*)>;

/// TransformUnaryElements constructs a new constant of type `composite_ty` by applying the
/// transformation function 'f' on each of the most deeply nested elements of `c0`.
Eval::Result TransformUnaryElements(Manager& mgr,
                                    const core::type::Type* composite_ty,
                                    const UnaryTransform& f,
                                    const Value* c0) {
    auto [el_ty, n] = c0->Type()->Elements();
    if (!el_ty) {
        return f(c0);
    }

    auto* composite_el_ty = composite_ty->Elements(composite_ty).type;

    Vector<const Value*, 8> els;
    els.Reserve(n);
    for (uint32_t i = 0; i < n; i++) {
        if (auto el = TransformUnaryElements(mgr, composite_el_ty, f, c0->Index(i))) {
            els.Push(el.Get());

        } else {
            return el.Failure();
        }
    }
    return mgr.Composite(composite_ty, std::move(els));
}

/// Signature of a binary transformation callback.
using BinaryTransform = std::function<Eval::Result(const Value*, const Value*)>;

/// TransformBinaryElements constructs a new constant of type `composite_ty` by applying the
/// transformation function 'f' on each of the most deeply nested elements of both `c0` and `c1`.
Eval::Result TransformBinaryElements(Manager& mgr,
                                     const core::type::Type* composite_ty,
                                     const BinaryTransform& f,
                                     const Value* c0,
                                     const Value* c1) {
    auto [el_ty, n] = c0->Type()->Elements();
    if (!el_ty) {
        return f(c0, c1);
    }

    TINT_ASSERT(n == c1->Type()->Elements().count);

    auto* composite_el_ty = composite_ty->Elements(composite_ty).type;

    Vector<const Value*, 8> els;
    els.Reserve(n);
    for (uint32_t i = 0; i < n; i++) {
        if (auto el =
                TransformBinaryElements(mgr, composite_el_ty, f, c0->Index(i), c1->Index(i))) {
            els.Push(el.Get());

        } else {
            return el.Failure();
        }
    }
    return mgr.Composite(composite_ty, std::move(els));
}

/// TransformBinaryDifferingArityElements constructs a new constant of type `composite_ty` by
/// applying the transformation function 'f' on each of the most deeply nested elements of both `c0`
/// and `c1`. Unlike TransformElements, this function handles the constants being of different
/// arity, e.g. vector-scalar, scalar-vector.
Eval::Result TransformBinaryDifferingArityElements(Manager& mgr,
                                                   const core::type::Type* composite_ty,
                                                   const BinaryTransform& f,
                                                   const Value* c0,
                                                   const Value* c1) {
    uint32_t n0 = c0->Type()->Elements(nullptr, 1).count;
    uint32_t n1 = c1->Type()->Elements(nullptr, 1).count;
    uint32_t max_n = std::max(n0, n1);
    // If arity of both constants is 1, invoke callback
    if (max_n == 1u) {
        return f(c0, c1);
    }

    const auto* element_ty = composite_ty->Elements(composite_ty).type;

    Vector<const Value*, 8> els;
    els.Reserve(max_n);
    for (uint32_t i = 0; i < max_n; i++) {
        auto nested_or_self = [&](auto* c, uint32_t num_elems) {
            return (num_elems == 1) ? c : c->Index(i);
        };
        if (auto el = TransformBinaryDifferingArityElements(
                mgr, element_ty, f, nested_or_self(c0, n0), nested_or_self(c1, n1))) {
            els.Push(el.Get());
        } else {
            return el.Failure();
        }
    }
    return mgr.Composite(composite_ty, std::move(els));
}

/// Signature of a ternary transformation callback
using TernaryTransform = std::function<Eval::Result(const Value*, const Value*, const Value*)>;

/// TransformTernaryElements constructs a new constant of type `composite_ty` by applying the
/// transformation function 'f' on each of the most deeply nested elements of both `c0`, `c1`, and
/// `c2`.
Eval::Result TransformTernaryElements(Manager& mgr,
                                      const core::type::Type* composite_ty,
                                      const TernaryTransform& f,
                                      const Value* c0,
                                      const Value* c1,
                                      const Value* c2) {
    auto [el_ty, n] = c0->Type()->Elements();
    if (!el_ty) {
        return f(c0, c1, c2);
    }

    auto* composite_el_ty = composite_ty->Elements(composite_ty).type;

    Vector<const Value*, 8> els;
    els.Reserve(n);
    for (uint32_t i = 0; i < n; i++) {
        if (auto el = TransformTernaryElements(mgr, composite_el_ty, f, c0->Index(i), c1->Index(i),
                                               c2->Index(i))) {
            els.Push(el.Get());

        } else {
            return el.Failure();
        }
    }
    return mgr.Composite(composite_ty, std::move(els));
}
}  // namespace

Eval::Eval(Manager& manager, diag::List& diagnostics, bool use_runtime_semantics /* = false */)
    : mgr(manager), diags(diagnostics), use_runtime_semantics_(use_runtime_semantics) {}

template <typename T>
Eval::Result Eval::CreateScalar(const Source& source, const core::type::Type* t, T v) {
    static_assert(IsNumber<T> || std::is_same_v<T, bool>, "T must be a Number or bool");
    TINT_ASSERT(t->Is<core::type::Scalar>());

    if constexpr (IsFloatingPoint<T>) {
        if (!std::isfinite(v.value)) {
            AddError(OverflowErrorMessage(v, t->FriendlyName()), source);
            if (use_runtime_semantics_) {
                return ZeroValue(t);
            } else {
                return tint::Failure;
            }
        }
    }
    return mgr.Get<Scalar<T>>(t, v);
}

const Value* Eval::ZeroValue(const core::type::Type* type) {
    return Switch(
        type,  //
        [&](const core::type::Vector* v) -> const Value* {
            auto* zero_el = ZeroValue(v->type());
            return mgr.Splat(type, zero_el, v->Width());
        },
        [&](const core::type::Matrix* m) -> const Value* {
            auto* zero_el = ZeroValue(m->ColumnType());
            return mgr.Splat(type, zero_el, m->columns());
        },
        [&](const core::type::Array* a) -> const Value* {
            if (auto n = a->ConstantCount()) {
                if (auto* zero_el = ZeroValue(a->ElemType())) {
                    return mgr.Splat(type, zero_el, n.value());
                }
            }
            return nullptr;
        },
        [&](const core::type::Struct* s) -> const Value* {
            Hashmap<const core::type::Type*, const Value*, 8> zero_by_type;
            Vector<const Value*, 4> zeros;
            zeros.Reserve(s->Members().Length());
            for (auto* member : s->Members()) {
                auto* zero = zero_by_type.GetOrCreate(member->Type(),
                                                      [&] { return ZeroValue(member->Type()); });
                if (!zero) {
                    return nullptr;
                }
                zeros.Push(zero);
            }
            if (zero_by_type.Count() == 1) {
                // All members were of the same type, so the zero value is the same for all members.
                return mgr.Splat(type, zeros[0], s->Members().Length());
            }
            return mgr.Composite(s, std::move(zeros));
        },
        [&](Default) -> const Value* {
            return ZeroTypeDispatch(type, [&](auto zero) -> const Value* {
                auto el = CreateScalar(Source{}, type, zero);
                TINT_ASSERT(el);
                return el.Get();
            });
        });
}

template <typename NumberT>
tint::Result<NumberT> Eval::Add(const Source& source, NumberT a, NumberT b) {
    NumberT result;
    if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
        if (auto r = CheckedAdd(a, b)) {
            result = r->value;
        } else {
            AddError(OverflowErrorMessage(a, "+", b), source);
            if (use_runtime_semantics_) {
                return NumberT{0};
            } else {
                return tint::Failure;
            }
        }
    } else {
        using T = UnwrapNumber<NumberT>;
        auto add_values = [](T lhs, T rhs) {
            if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
                // Ensure no UB for signed overflow
                using UT = std::make_unsigned_t<T>;
                return static_cast<T>(static_cast<UT>(lhs) + static_cast<UT>(rhs));
            } else {
                return lhs + rhs;
            }
        };
        result = add_values(a.value, b.value);
    }
    return result;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Sub(const Source& source, NumberT a, NumberT b) {
    NumberT result;
    if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
        if (auto r = CheckedSub(a, b)) {
            result = r->value;
        } else {
            AddError(OverflowErrorMessage(a, "-", b), source);
            if (use_runtime_semantics_) {
                return NumberT{0};
            } else {
                return tint::Failure;
            }
        }
    } else {
        using T = UnwrapNumber<NumberT>;
        auto sub_values = [](T lhs, T rhs) {
            if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
                // Ensure no UB for signed overflow
                using UT = std::make_unsigned_t<T>;
                return static_cast<T>(static_cast<UT>(lhs) - static_cast<UT>(rhs));
            } else {
                return lhs - rhs;
            }
        };
        result = sub_values(a.value, b.value);
    }
    return result;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Mul(const Source& source, NumberT a, NumberT b) {
    using T = UnwrapNumber<NumberT>;
    NumberT result;
    if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
        if (auto r = CheckedMul(a, b)) {
            result = r->value;
        } else {
            AddError(OverflowErrorMessage(a, "*", b), source);
            if (use_runtime_semantics_) {
                return NumberT{0};
            } else {
                return tint::Failure;
            }
        }
    } else {
        auto mul_values = [](T lhs, T rhs) {
            if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
                // For signed integrals, avoid C++ UB by multiplying as unsigned
                using UT = std::make_unsigned_t<T>;
                return static_cast<T>(static_cast<UT>(lhs) * static_cast<UT>(rhs));
            } else {
                return lhs * rhs;
            }
        };
        result = mul_values(a.value, b.value);
    }
    return result;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Div(const Source& source, NumberT a, NumberT b) {
    NumberT result;
    if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
        if (auto r = CheckedDiv(a, b)) {
            result = r->value;
        } else {
            AddError(OverflowErrorMessage(a, "/", b), source);
            if (use_runtime_semantics_) {
                return a;
            } else {
                return tint::Failure;
            }
        }
    } else {
        using T = UnwrapNumber<NumberT>;
        auto lhs = a.value;
        auto rhs = b.value;
        if (rhs == 0) {
            // For integers (as for floats), lhs / 0 is an error
            AddError(OverflowErrorMessage(a, "/", b), source);
            if (use_runtime_semantics_) {
                return a;
            } else {
                return tint::Failure;
            }
        }
        if constexpr (std::is_signed_v<T>) {
            // For signed integers, lhs / -1 where lhs is the
            // most negative value is an error
            if (rhs == -1 && lhs == std::numeric_limits<T>::min()) {
                AddError(OverflowErrorMessage(a, "/", b), source);
                if (use_runtime_semantics_) {
                    return a;
                } else {
                    return tint::Failure;
                }
            }
        }
        result = lhs / rhs;
    }
    return result;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Mod(const Source& source, NumberT a, NumberT b) {
    NumberT result;
    if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
        if (auto r = CheckedMod(a, b)) {
            result = r->value;
        } else {
            AddError(OverflowErrorMessage(a, "%", b), source);
            if (use_runtime_semantics_) {
                return NumberT{0};
            } else {
                return tint::Failure;
            }
        }
    } else {
        using T = UnwrapNumber<NumberT>;
        auto lhs = a.value;
        auto rhs = b.value;
        if (rhs == 0) {
            // lhs % 0 is an error
            AddError(OverflowErrorMessage(a, "%", b), source);
            if (use_runtime_semantics_) {
                return NumberT{0};
            } else {
                return tint::Failure;
            }
        }
        if constexpr (std::is_signed_v<T>) {
            // For signed integers, lhs % -1 where lhs is the
            // most negative value is an error
            if (rhs == -1 && lhs == std::numeric_limits<T>::min()) {
                AddError(OverflowErrorMessage(a, "%", b), source);
                if (use_runtime_semantics_) {
                    return NumberT{0};
                } else {
                    return tint::Failure;
                }
            }
        }
        result = lhs % rhs;
    }
    return result;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Dot2(const Source& source,
                                 NumberT a1,
                                 NumberT a2,
                                 NumberT b1,
                                 NumberT b2) {
    auto r1 = Mul(source, a1, b1);
    if (!r1) {
        return tint::Failure;
    }
    auto r2 = Mul(source, a2, b2);
    if (!r2) {
        return tint::Failure;
    }
    auto r = Add(source, r1.Get(), r2.Get());
    if (!r) {
        return tint::Failure;
    }
    return r;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Dot3(const Source& source,
                                 NumberT a1,
                                 NumberT a2,
                                 NumberT a3,
                                 NumberT b1,
                                 NumberT b2,
                                 NumberT b3) {
    auto r1 = Mul(source, a1, b1);
    if (!r1) {
        return tint::Failure;
    }
    auto r2 = Mul(source, a2, b2);
    if (!r2) {
        return tint::Failure;
    }
    auto r3 = Mul(source, a3, b3);
    if (!r3) {
        return tint::Failure;
    }
    auto r = Add(source, r1.Get(), r2.Get());
    if (!r) {
        return tint::Failure;
    }
    r = Add(source, r.Get(), r3.Get());
    if (!r) {
        return tint::Failure;
    }
    return r;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Dot4(const Source& source,
                                 NumberT a1,
                                 NumberT a2,
                                 NumberT a3,
                                 NumberT a4,
                                 NumberT b1,
                                 NumberT b2,
                                 NumberT b3,
                                 NumberT b4) {
    auto r1 = Mul(source, a1, b1);
    if (!r1) {
        return tint::Failure;
    }
    auto r2 = Mul(source, a2, b2);
    if (!r2) {
        return tint::Failure;
    }
    auto r3 = Mul(source, a3, b3);
    if (!r3) {
        return tint::Failure;
    }
    auto r4 = Mul(source, a4, b4);
    if (!r4) {
        return tint::Failure;
    }
    auto r = Add(source, r1.Get(), r2.Get());
    if (!r) {
        return tint::Failure;
    }
    r = Add(source, r.Get(), r3.Get());
    if (!r) {
        return tint::Failure;
    }
    r = Add(source, r.Get(), r4.Get());
    if (!r) {
        return tint::Failure;
    }
    return r;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Det2(const Source& source, NumberT a, NumberT b, NumberT c, NumberT d) {
    // | a c |
    // | b d |
    //
    // =
    //
    // a * d - c * b

    auto r1 = Mul(source, a, d);
    if (!r1) {
        return tint::Failure;
    }
    auto r2 = Mul(source, c, b);
    if (!r2) {
        return tint::Failure;
    }
    auto r = Sub(source, r1.Get(), r2.Get());
    if (!r) {
        return tint::Failure;
    }
    return r;
}

template <typename NumberT>
tint::Result<NumberT> Eval::Det3(const Source& source,
                                 NumberT a,
                                 NumberT b,
                                 NumberT c,
                                 NumberT d,
                                 NumberT e,
                                 NumberT f,
                                 NumberT g,
                                 NumberT h,
                                 NumberT i) {
    // | a d g |
    // | b e h |
    // | c f i |
    //
    // =
    //
    // a | e h | - d | b h | + g | b e |
    //   | f i |     | c i |     | c f |

    auto det1 = Det2(source, e, f, h, i);
    if (!det1) {
        return tint::Failure;
    }
    auto a_det1 = Mul(source, a, det1.Get());
    if (!a_det1) {
        return tint::Failure;
    }
    auto det2 = Det2(source, b, c, h, i);
    if (!det2) {
        return tint::Failure;
    }
    auto d_det2 = Mul(source, d, det2.Get());
    if (!d_det2) {
        return tint::Failure;
    }
    auto det3 = Det2(source, b, c, e, f);
    if (!det3) {
        return tint::Failure;
    }
    auto g_det3 = Mul(source, g, det3.Get());
    if (!g_det3) {
        return tint::Failure;
    }
    auto r = Sub(source, a_det1.Get(), d_det2.Get());
    if (!r) {
        return tint::Failure;
    }
    return Add(source, r.Get(), g_det3.Get());
}

template <typename NumberT>
tint::Result<NumberT> Eval::Det4(const Source& source,
                                 NumberT a,
                                 NumberT b,
                                 NumberT c,
                                 NumberT d,
                                 NumberT e,
                                 NumberT f,
                                 NumberT g,
                                 NumberT h,
                                 NumberT i,
                                 NumberT j,
                                 NumberT k,
                                 NumberT l,
                                 NumberT m,
                                 NumberT n,
                                 NumberT o,
                                 NumberT p) {
    // | a e i m |
    // | b f j n |
    // | c g k o |
    // | d h l p |
    //
    // =
    //
    // a | f j n | - e | b j n | + i | b f n | - m | b f j |
    //   | g k o |     | c k o |     | c g o |     | c g k |
    //   | h l p |     | d l p |     | d h p |     | d h l |

    auto det1 = Det3(source, f, g, h, j, k, l, n, o, p);
    if (!det1) {
        return tint::Failure;
    }
    auto a_det1 = Mul(source, a, det1.Get());
    if (!a_det1) {
        return tint::Failure;
    }
    auto det2 = Det3(source, b, c, d, j, k, l, n, o, p);
    if (!det2) {
        return tint::Failure;
    }
    auto e_det2 = Mul(source, e, det2.Get());
    if (!e_det2) {
        return tint::Failure;
    }
    auto det3 = Det3(source, b, c, d, f, g, h, n, o, p);
    if (!det3) {
        return tint::Failure;
    }
    auto i_det3 = Mul(source, i, det3.Get());
    if (!i_det3) {
        return tint::Failure;
    }
    auto det4 = Det3(source, b, c, d, f, g, h, j, k, l);
    if (!det4) {
        return tint::Failure;
    }
    auto m_det4 = Mul(source, m, det4.Get());
    if (!m_det4) {
        return tint::Failure;
    }
    auto r = Sub(source, a_det1.Get(), e_det2.Get());
    if (!r) {
        return tint::Failure;
    }
    r = Add(source, r.Get(), i_det3.Get());
    if (!r) {
        return tint::Failure;
    }
    return Sub(source, r.Get(), m_det4.Get());
}

template <typename NumberT>
tint::Result<NumberT> Eval::Sqrt(const Source& source, NumberT v) {
    if (v < NumberT(0)) {
        AddError("sqrt must be called with a value >= 0", source);
        if (use_runtime_semantics_) {
            return NumberT{0};
        } else {
            return tint::Failure;
        }
    }
    return NumberT{std::sqrt(v)};
}

auto Eval::SqrtFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto v) -> Eval::Result {
        if (auto r = Sqrt(source, v)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

template <typename NumberT>
tint::Result<NumberT> Eval::Clamp(const Source& source, NumberT e, NumberT low, NumberT high) {
    if (low > high) {
        StringStream ss;
        ss << "clamp called with 'low' (" << low << ") greater than 'high' (" << high << ")";
        AddError(ss.str(), source);
        if (!use_runtime_semantics_) {
            return tint::Failure;
        }
    }
    return NumberT{std::min(std::max(e, low), high)};
}

auto Eval::ClampFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto e, auto low, auto high) -> Eval::Result {
        if (auto r = Clamp(source, e, low, high)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::AddFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2) -> Eval::Result {
        if (auto r = Add(source, a1, a2)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::SubFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2) -> Eval::Result {
        if (auto r = Sub(source, a1, a2)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::MulFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2) -> Eval::Result {
        if (auto r = Mul(source, a1, a2)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::DivFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2) -> Eval::Result {
        if (auto r = Div(source, a1, a2)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::ModFunc(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2) -> Eval::Result {
        if (auto r = Mod(source, a1, a2)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::Dot2Func(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2, auto b1, auto b2) -> Eval::Result {
        if (auto r = Dot2(source, a1, a2, b1, b2)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::Dot3Func(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2, auto a3, auto b1, auto b2, auto b3) -> Eval::Result {
        if (auto r = Dot3(source, a1, a2, a3, b1, b2, b3)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::Dot4Func(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a1, auto a2, auto a3, auto a4, auto b1, auto b2, auto b3,
               auto b4) -> Eval::Result {
        if (auto r = Dot4(source, a1, a2, a3, a4, b1, b2, b3, b4)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

Eval::Result Eval::Dot(const Source& source, const Value* v1, const Value* v2) {
    auto* vec_ty = v1->Type()->As<core::type::Vector>();
    TINT_ASSERT(vec_ty);
    auto* elem_ty = vec_ty->type();
    switch (vec_ty->Width()) {
        case 2:
            return Dispatch_fia_fiu32_f16(   //
                Dot2Func(source, elem_ty),   //
                v1->Index(0), v1->Index(1),  //
                v2->Index(0), v2->Index(1));
        case 3:
            return Dispatch_fia_fiu32_f16(                 //
                Dot3Func(source, elem_ty),                 //
                v1->Index(0), v1->Index(1), v1->Index(2),  //
                v2->Index(0), v2->Index(1), v2->Index(2));
        case 4:
            return Dispatch_fia_fiu32_f16(                               //
                Dot4Func(source, elem_ty),                               //
                v1->Index(0), v1->Index(1), v1->Index(2), v1->Index(3),  //
                v2->Index(0), v2->Index(1), v2->Index(2), v2->Index(3));
    }
    TINT_ICE() << "Expected vector";
    return Failure;
}

Eval::Result Eval::Length(const Source& source, const core::type::Type* ty, const Value* c0) {
    auto* vec_ty = c0->Type()->As<core::type::Vector>();
    // Evaluates to the absolute value of e if T is scalar.
    if (vec_ty == nullptr) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            return CreateScalar(source, ty, NumberT{std::abs(e)});
        };
        return Dispatch_fa_f32_f16(create, c0);
    }

    // Evaluates to sqrt(e[0]^2 + e[1]^2 + ...) if T is a vector type.
    auto d = Dot(source, c0, c0);
    if (!d) {
        return tint::Failure;
    }
    return Dispatch_fa_f32_f16(SqrtFunc(source, ty), d.Get());
}

Eval::Result Eval::Mul(const Source& source,
                       const core::type::Type* ty,
                       const Value* v1,
                       const Value* v2) {
    auto transform = [&](const Value* c0, const Value* c1) {
        return Dispatch_fia_fiu32_f16(MulFunc(source, c0->Type()), c0, c1);
    };
    return TransformBinaryDifferingArityElements(mgr, ty, transform, v1, v2);
}

Eval::Result Eval::Sub(const Source& source,
                       const core::type::Type* ty,
                       const Value* v1,
                       const Value* v2) {
    auto transform = [&](const Value* c0, const Value* c1) {
        return Dispatch_fia_fiu32_f16(SubFunc(source, c0->Type()), c0, c1);
    };
    return TransformBinaryDifferingArityElements(mgr, ty, transform, v1, v2);
}

auto Eval::Det2Func(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a, auto b, auto c, auto d) -> Eval::Result {
        if (auto r = Det2(source, a, b, c, d)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::Det3Func(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a, auto b, auto c, auto d, auto e, auto f, auto g, auto h,
               auto i) -> Eval::Result {
        if (auto r = Det3(source, a, b, c, d, e, f, g, h, i)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

auto Eval::Det4Func(const Source& source, const core::type::Type* elem_ty) {
    return [=](auto a, auto b, auto c, auto d, auto e, auto f, auto g, auto h, auto i, auto j,
               auto k, auto l, auto m, auto n, auto o, auto p) -> Eval::Result {
        if (auto r = Det4(source, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)) {
            return CreateScalar(source, elem_ty, r.Get());
        }
        return tint::Failure;
    };
}

Eval::Result Eval::ArrayOrStructCtor(const core::type::Type* ty, VectorRef<const Value*> args) {
    if (args.IsEmpty()) {
        return ZeroValue(ty);
    }

    if (args.Length() == 1 && args[0]->Type() == ty) {
        // Identity constructor.
        return args[0];
    }

    // Multiple arguments. Must be a value constructor.
    return mgr.Composite(ty, std::move(args));
}

Eval::Result Eval::Conv(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto* el_ty = ty->Elements(ty).type;
    if (!el_ty) {
        return nullptr;
    }

    if (!args[0]) {
        return nullptr;  // Single argument is not constant.
    }

    return Convert(ty, args[0], source);
}

Eval::Result Eval::Zero(const core::type::Type* ty, VectorRef<const Value*>, const Source&) {
    return ZeroValue(ty);
}

Eval::Result Eval::Identity(const core::type::Type*, VectorRef<const Value*> args, const Source&) {
    return args[0];
}

Eval::Result Eval::VecSplat(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source&) {
    if (auto* arg = args[0]) {
        return mgr.Splat(ty, arg, static_cast<const core::type::Vector*>(ty)->Width());
    }
    return nullptr;
}

Eval::Result Eval::VecInitS(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source&) {
    return mgr.Composite(ty, args);
}

Eval::Result Eval::VecInitM(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source&) {
    Vector<const Value*, 4> els;
    for (auto* arg : args) {
        auto* val = arg;
        if (!val) {
            return nullptr;
        }
        auto* arg_ty = arg->Type();
        if (auto* arg_vec = arg_ty->As<core::type::Vector>()) {
            // Extract out vector elements.
            for (uint32_t j = 0; j < arg_vec->Width(); j++) {
                auto* el = val->Index(j);
                if (!el) {
                    return nullptr;
                }
                els.Push(el);
            }
        } else {
            els.Push(val);
        }
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::MatInitS(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source&) {
    auto* m = static_cast<const core::type::Matrix*>(ty);

    Vector<const Value*, 4> els;
    for (uint32_t c = 0; c < m->columns(); c++) {
        Vector<const Value*, 4> column;
        for (uint32_t r = 0; r < m->rows(); r++) {
            auto i = r + c * m->rows();
            column.Push(args[i]);
        }
        els.Push(mgr.Composite(m->ColumnType(), std::move(column)));
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::MatInitV(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source&) {
    return mgr.Composite(ty, args);
}

Eval::Result Eval::Index(const Value* obj_val,
                         const core::type::Type* obj_ty,
                         const Value* idx_val,
                         const Source& idx_source) {
    auto el = obj_ty->UnwrapRef()->Elements();

    AInt idx = idx_val->ValueAs<AInt>();
    if (idx < 0 || (el.count > 0 && idx >= el.count)) {
        std::string range;
        if (el.count > 0) {
            range = " [0.." + std::to_string(el.count - 1) + "]";
        }
        AddError("index " + std::to_string(idx) + " out of bounds" + range, idx_source);
        if (use_runtime_semantics_) {
            return ZeroValue(el.type);
        } else {
            return tint::Failure;
        }
    }

    return obj_val ? obj_val->Index(static_cast<size_t>(idx)) : nullptr;
}

Eval::Result Eval::Swizzle(const core::type::Type* ty,
                           const Value* object,
                           VectorRef<uint32_t> indices) {
    if (indices.Length() == 1) {
        return object->Index(static_cast<size_t>(indices[0]));
    }
    auto values = tint::Transform<4>(
        indices, [&](uint32_t i) { return object->Index(static_cast<size_t>(i)); });
    return mgr.Composite(ty, std::move(values));
}

Eval::Result Eval::Bitcast(const core::type::Type* ty, const Value* value, const Source& source) {
    // Target type
    auto dst_elements = ty->Elements(ty->DeepestElement(), 1u);
    auto dst_el_ty = dst_elements.type;
    auto dst_count = dst_elements.count;
    // Source type
    auto src_elements = value->Type()->Elements(value->Type()->DeepestElement(), 1u);
    auto src_el_ty = src_elements.type;
    auto src_count = src_elements.count;

    TINT_ASSERT(dst_count * dst_el_ty->Size() == src_count * src_el_ty->Size());
    uint32_t total_bitwidth = dst_count * dst_el_ty->Size();
    // Buffer holding the bits from source value, result value reinterpreted from it.
    Vector<std::byte, 16> buffer;
    buffer.Reserve(total_bitwidth);

    // Ensure elements are of 32-bit or 16-bit numerical scalar type.
    TINT_ASSERT(
        (src_el_ty->IsAnyOf<core::type::F32, core::type::I32, core::type::U32, core::type::F16>()));
    // Pushes bits from source value into the buffer.
    auto push_src_element_bits = [&](const Value* element) {
        auto push_32_bits = [&](uint32_t v) {
            buffer.Push(std::byte(v & 0xffu));
            buffer.Push(std::byte((v >> 8) & 0xffu));
            buffer.Push(std::byte((v >> 16) & 0xffu));
            buffer.Push(std::byte((v >> 24) & 0xffu));
        };
        auto push_16_bits = [&](uint16_t v) {
            buffer.Push(std::byte(v & 0xffu));
            buffer.Push(std::byte((v >> 8) & 0xffu));
        };
        Switch(
            src_el_ty,
            [&](const core::type::U32*) {  //
                uint32_t r = element->ValueAs<u32>();
                push_32_bits(r);
            },
            [&](const core::type::I32*) {  //
                uint32_t r = tint::Bitcast<u32>(element->ValueAs<i32>());
                push_32_bits(r);
            },
            [&](const core::type::F32*) {  //
                uint32_t r = tint::Bitcast<u32>(element->ValueAs<f32>());
                push_32_bits(r);
            },
            [&](const core::type::F16*) {  //
                uint16_t r = element->ValueAs<f16>().BitsRepresentation();
                push_16_bits(r);
            });
    };
    if (src_count == 1) {
        push_src_element_bits(value);
    } else {
        for (size_t i = 0; i < src_count; i++) {
            push_src_element_bits(value->Index(i));
        }
    }

    // Vector holding elements of return value
    Vector<const Value*, 4> els;

    // Reinterprets the buffer bits as destination element and push the result into the vector.
    // Return false if an error occured, otherwise return true.
    auto push_dst_element = [&](size_t offset) -> bool {
        uint32_t v;
        if (dst_el_ty->Size() == 4) {
            v = (std::to_integer<uint32_t>(buffer[offset])) |
                (std::to_integer<uint32_t>(buffer[offset + 1]) << 8) |
                (std::to_integer<uint32_t>(buffer[offset + 2]) << 16) |
                (std::to_integer<uint32_t>(buffer[offset + 3]) << 24);
        } else {
            v = (std::to_integer<uint32_t>(buffer[offset])) |
                (std::to_integer<uint32_t>(buffer[offset + 1]) << 8);
        }

        return Switch(
            dst_el_ty,
            [&](const core::type::U32*) {  //
                auto r = CreateScalar(source, dst_el_ty, u32(v));
                if (r) {
                    els.Push(r.Get());
                }
                return r;
            },
            [&](const core::type::I32*) {  //
                auto r = CreateScalar(source, dst_el_ty, tint::Bitcast<i32>(v));
                if (r) {
                    els.Push(r.Get());
                }
                return r;
            },
            [&](const core::type::F32*) {  //
                auto r = CreateScalar(source, dst_el_ty, tint::Bitcast<f32>(v));
                if (r) {
                    els.Push(r.Get());
                }
                return r;
            },
            [&](const core::type::F16*) {  //
                auto r = CreateScalar(source, dst_el_ty, f16::FromBits(static_cast<uint16_t>(v)));
                if (r) {
                    els.Push(r.Get());
                }
                return r;
            });
    };

    TINT_ASSERT((buffer.Length() == total_bitwidth));
    for (size_t i = 0; i < dst_count; i++) {
        if (!push_dst_element(i * dst_el_ty->Size())) {
            return tint::Failure;
        }
    }

    if (dst_count == 1) {
        return std::move(els[0]);
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::Complement(const core::type::Type* ty,
                              VectorRef<const Value*> args,
                              const Source& source) {
    auto transform = [&](const Value* c) {
        auto create = [&](auto i) {
            return CreateScalar(source, c->Type(), decltype(i)(~i.value));
        };
        return Dispatch_ia_iu32(create, c);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::UnaryMinus(const core::type::Type* ty,
                              VectorRef<const Value*> args,
                              const Source& source) {
    auto transform = [&](const Value* c) {
        auto create = [&](auto i) {
            // For signed integrals, avoid C++ UB by not negating the
            // smallest negative number. In WGSL, this operation is well
            // defined to return the same value, see:
            // https://gpuweb.github.io/gpuweb/wgsl/#arithmetic-expr.
            using T = UnwrapNumber<decltype(i)>;
            if constexpr (std::is_integral_v<T>) {
                auto v = i.value;
                if (v != std::numeric_limits<T>::min()) {
                    v = -v;
                }
                return CreateScalar(source, c->Type(), decltype(i)(v));
            } else {
                return CreateScalar(source, c->Type(), decltype(i)(-i.value));
            }
        };
        return Dispatch_fia_fi32_f16(create, c);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::Not(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c) {
        auto create = [&](auto i) { return CreateScalar(source, c->Type(), decltype(i)(!i)); };
        return Dispatch_bool(create, c);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::Plus(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        return Dispatch_fia_fiu32_f16(AddFunc(source, c0->Type()), c0, c1);
    };

    return TransformBinaryDifferingArityElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::Minus(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    return Sub(source, ty, args[0], args[1]);
}

Eval::Result Eval::Multiply(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source& source) {
    return Mul(source, ty, args[0], args[1]);
}

Eval::Result Eval::MultiplyMatVec(const core::type::Type* ty,
                                  VectorRef<const Value*> args,
                                  const Source& source) {
    auto* mat_ty = args[0]->Type()->As<core::type::Matrix>();
    auto* vec_ty = args[1]->Type()->As<core::type::Vector>();
    auto* elem_ty = vec_ty->type();

    auto dot = [&](const Value* m, size_t row, const Value* v) {
        Eval::Result result;
        switch (mat_ty->columns()) {
            case 2:
                result = Dispatch_fa_f32_f16(Dot2Func(source, elem_ty),  //
                                             m->Index(0)->Index(row),    //
                                             m->Index(1)->Index(row),    //
                                             v->Index(0),                //
                                             v->Index(1));
                break;
            case 3:
                result = Dispatch_fa_f32_f16(Dot3Func(source, elem_ty),  //
                                             m->Index(0)->Index(row),    //
                                             m->Index(1)->Index(row),    //
                                             m->Index(2)->Index(row),    //
                                             v->Index(0),                //
                                             v->Index(1), v->Index(2));
                break;
            case 4:
                result = Dispatch_fa_f32_f16(Dot4Func(source, elem_ty),  //
                                             m->Index(0)->Index(row),    //
                                             m->Index(1)->Index(row),    //
                                             m->Index(2)->Index(row),    //
                                             m->Index(3)->Index(row),    //
                                             v->Index(0),                //
                                             v->Index(1),                //
                                             v->Index(2),                //
                                             v->Index(3));
                break;
        }
        return result;
    };

    Vector<const Value*, 4> result;
    for (size_t i = 0; i < mat_ty->rows(); ++i) {
        auto r = dot(args[0], i, args[1]);  // matrix row i * vector
        if (!r) {
            return tint::Failure;
        }
        result.Push(r.Get());
    }
    return mgr.Composite(ty, result);
}
Eval::Result Eval::MultiplyVecMat(const core::type::Type* ty,
                                  VectorRef<const Value*> args,
                                  const Source& source) {
    auto* vec_ty = args[0]->Type()->As<core::type::Vector>();
    auto* mat_ty = args[1]->Type()->As<core::type::Matrix>();
    auto* elem_ty = vec_ty->type();

    auto dot = [&](const Value* v, const Value* m, size_t col) {
        Eval::Result result;
        switch (mat_ty->rows()) {
            case 2:
                result = Dispatch_fa_f32_f16(Dot2Func(source, elem_ty),  //
                                             m->Index(col)->Index(0),    //
                                             m->Index(col)->Index(1),    //
                                             v->Index(0),                //
                                             v->Index(1));
                break;
            case 3:
                result = Dispatch_fa_f32_f16(Dot3Func(source, elem_ty),  //
                                             m->Index(col)->Index(0),    //
                                             m->Index(col)->Index(1),    //
                                             m->Index(col)->Index(2),
                                             v->Index(0),  //
                                             v->Index(1),  //
                                             v->Index(2));
                break;
            case 4:
                result = Dispatch_fa_f32_f16(Dot4Func(source, elem_ty),  //
                                             m->Index(col)->Index(0),    //
                                             m->Index(col)->Index(1),    //
                                             m->Index(col)->Index(2),    //
                                             m->Index(col)->Index(3),    //
                                             v->Index(0),                //
                                             v->Index(1),                //
                                             v->Index(2),                //
                                             v->Index(3));
        }
        return result;
    };

    Vector<const Value*, 4> result;
    for (size_t i = 0; i < mat_ty->columns(); ++i) {
        auto r = dot(args[0], args[1], i);  // vector * matrix col i
        if (!r) {
            return tint::Failure;
        }
        result.Push(r.Get());
    }
    return mgr.Composite(ty, result);
}

Eval::Result Eval::MultiplyMatMat(const core::type::Type* ty,
                                  VectorRef<const Value*> args,
                                  const Source& source) {
    auto* mat1 = args[0];
    auto* mat2 = args[1];
    auto* mat1_ty = mat1->Type()->As<core::type::Matrix>();
    auto* mat2_ty = mat2->Type()->As<core::type::Matrix>();
    auto* elem_ty = mat1_ty->type();

    auto dot = [&](const Value* m1, size_t row, const Value* m2, size_t col) {
        auto m1e = [&](size_t r, size_t c) { return m1->Index(c)->Index(r); };
        auto m2e = [&](size_t r, size_t c) { return m2->Index(c)->Index(r); };

        Eval::Result result;
        switch (mat1_ty->columns()) {
            case 2:
                result = Dispatch_fa_f32_f16(Dot2Func(source, elem_ty),  //
                                             m1e(row, 0),                //
                                             m1e(row, 1),                //
                                             m2e(0, col),                //
                                             m2e(1, col));
                break;
            case 3:
                result = Dispatch_fa_f32_f16(Dot3Func(source, elem_ty),  //
                                             m1e(row, 0),                //
                                             m1e(row, 1),                //
                                             m1e(row, 2),                //
                                             m2e(0, col),                //
                                             m2e(1, col),                //
                                             m2e(2, col));
                break;
            case 4:
                result = Dispatch_fa_f32_f16(Dot4Func(source, elem_ty),  //
                                             m1e(row, 0),                //
                                             m1e(row, 1),                //
                                             m1e(row, 2),                //
                                             m1e(row, 3),                //
                                             m2e(0, col),                //
                                             m2e(1, col),                //
                                             m2e(2, col),                //
                                             m2e(3, col));
                break;
        }
        return result;
    };

    Vector<const Value*, 4> result_mat;
    for (size_t c = 0; c < mat2_ty->columns(); ++c) {
        Vector<const Value*, 4> col_vec;
        for (size_t r = 0; r < mat1_ty->rows(); ++r) {
            auto v = dot(mat1, r, mat2, c);  // mat1 row r * mat2 col c
            if (!v) {
                return tint::Failure;
            }
            col_vec.Push(v.Get());  // mat1 row r * mat2 col c
        }

        // Add column vector to matrix
        auto* col_vec_ty = ty->As<core::type::Matrix>()->ColumnType();
        result_mat.Push(mgr.Composite(col_vec_ty, col_vec));
    }
    return mgr.Composite(ty, result_mat);
}

Eval::Result Eval::Divide(const core::type::Type* ty,
                          VectorRef<const Value*> args,
                          const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        return Dispatch_fia_fiu32_f16(DivFunc(source, c0->Type()), c0, c1);
    };

    return TransformBinaryDifferingArityElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::Modulo(const core::type::Type* ty,
                          VectorRef<const Value*> args,
                          const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        return Dispatch_fia_fiu32_f16(ModFunc(source, c0->Type()), c0, c1);
    };

    return TransformBinaryDifferingArityElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::Equal(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), i == j);
        };
        return Dispatch_fia_fiu32_f16_bool(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::NotEqual(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), i != j);
        };
        return Dispatch_fia_fiu32_f16_bool(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::LessThan(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), i < j);
        };
        return Dispatch_fia_fiu32_f16(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::GreaterThan(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), i > j);
        };
        return Dispatch_fia_fiu32_f16(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::LessThanEqual(const core::type::Type* ty,
                                 VectorRef<const Value*> args,
                                 const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), i <= j);
        };
        return Dispatch_fia_fiu32_f16(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::GreaterThanEqual(const core::type::Type* ty,
                                    VectorRef<const Value*> args,
                                    const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), i >= j);
        };
        return Dispatch_fia_fiu32_f16(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::LogicalAnd(const core::type::Type* ty,
                              VectorRef<const Value*> args,
                              const Source& source) {
    // Due to short-circuiting, this function is only called if lhs is true, so we only return the
    // value of the rhs.
    TINT_ASSERT(args[0]->ValueAs<bool>());
    return CreateScalar(source, ty, args[1]->ValueAs<bool>());
}

Eval::Result Eval::LogicalOr(const core::type::Type* ty,
                             VectorRef<const Value*> args,
                             const Source& source) {
    // Due to short-circuiting, this function is only called if lhs is false, so we only only return
    // the value of the rhs.
    TINT_ASSERT(!args[0]->ValueAs<bool>());
    return CreateScalar(source, ty, args[1]->ValueAs<bool>());
}

Eval::Result Eval::And(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            using T = decltype(i);
            T result;
            if constexpr (std::is_same_v<T, bool>) {
                result = i && j;
            } else {  // integral
                result = i & j;
            }
            return CreateScalar(source, ty->DeepestElement(), result);
        };
        return Dispatch_ia_iu32_bool(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::Or(const core::type::Type* ty,
                      VectorRef<const Value*> args,
                      const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            using T = decltype(i);
            T result;
            if constexpr (std::is_same_v<T, bool>) {
                result = i || j;
            } else {  // integral
                result = i | j;
            }
            return CreateScalar(source, ty->DeepestElement(), result);
        };
        return Dispatch_ia_iu32_bool(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::Xor(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), decltype(i){i ^ j});
        };
        return Dispatch_ia_iu32(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::ShiftLeft(const core::type::Type* ty,
                             VectorRef<const Value*> args,
                             const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto e1, auto e2) -> Eval::Result {
            using NumberT = decltype(e1);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            constexpr size_t bit_width = BitWidth<NumberT>;
            UT e1u = static_cast<UT>(e1);
            UT e2u = static_cast<UT>(e2);

            if constexpr (IsAbstract<NumberT>) {
                // The e2 + 1 most significant bits of e1 must have the same bit value, otherwise
                // sign change (overflow) would occur.
                // Check sign change only if e2 is less than bit width of e1. If e1 is larger
                // than bit width, we check for non-representable value below.
                if (e2u < bit_width) {
                    UT must_match_msb = e2u + 1;
                    UT mask = ~UT{0} << (bit_width - must_match_msb);
                    if ((e1u & mask) != 0 && (e1u & mask) != mask) {
                        AddError("shift left operation results in sign change", source);
                        if (!use_runtime_semantics_) {
                            return tint::Failure;
                        }
                    }
                } else {
                    // If shift value >= bit_width, then any non-zero value would overflow
                    if (e1 != 0) {
                        AddError(OverflowErrorMessage(e1, "<<", e2), source);
                        if (!use_runtime_semantics_) {
                            return tint::Failure;
                        }
                    }

                    // It's UB in C++ to shift by greater or equal to the bit width (even if the lhs
                    // is 0), so we make sure to avoid this by setting the shift value to 0.
                    e2u = 0;
                }
            } else {
                if (static_cast<size_t>(e2) >= bit_width) {
                    // At shader/pipeline-creation time, it is an error to shift by the bit width of
                    // the lhs or greater.
                    // NOTE: At runtime, we shift by e2 % (bit width of e1).
                    AddError(
                        "shift left value must be less than the bit width of the lhs, which is " +
                            std::to_string(bit_width),
                        source);
                    if (use_runtime_semantics_) {
                        e2u = e2u % bit_width;
                    } else {
                        return tint::Failure;
                    }
                }

                if constexpr (std::is_signed_v<T>) {
                    // If T is a signed integer type, and the e2+1 most significant bits of e1 do
                    // not have the same bit value, then error.
                    size_t must_match_msb = e2u + 1;
                    UT mask = ~UT{0} << (bit_width - must_match_msb);
                    if ((e1u & mask) != 0 && (e1u & mask) != mask) {
                        AddError("shift left operation results in sign change", source);
                        if (!use_runtime_semantics_) {
                            return tint::Failure;
                        }
                    }
                } else {
                    // If T is an unsigned integer type, and any of the e2 most significant bits of
                    // e1 are 1, then error.
                    if (e2u > 0) {
                        size_t must_be_zero_msb = e2u;
                        UT mask = ~UT{0} << (bit_width - must_be_zero_msb);
                        if ((e1u & mask) != 0) {
                            AddError(OverflowErrorMessage(e1, "<<", e2), source);
                            if (!use_runtime_semantics_) {
                                return tint::Failure;
                            }
                        }
                    }
                }
            }

            // Avoid UB by left shifting as unsigned value
            auto result = static_cast<T>(static_cast<UT>(e1) << e2u);
            return CreateScalar(source, ty->DeepestElement(), NumberT{result});
        };
        return Dispatch_ia_iu32(create, c0, c1);
    };

    if (TINT_UNLIKELY(!args[1]->Type()->DeepestElement()->Is<core::type::U32>())) {
        TINT_ICE() << "Element type of rhs of ShiftLeft must be a u32";
        return Failure;
    }

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::ShiftRight(const core::type::Type* ty,
                              VectorRef<const Value*> args,
                              const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto e1, auto e2) -> Eval::Result {
            using NumberT = decltype(e1);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            const size_t bit_width = BitWidth<NumberT>;
            UT e1u = static_cast<UT>(e1);
            UT e2u = static_cast<UT>(e2);

            [[maybe_unused]] auto signed_shift_right = [&] {
                // In C++, right shift of a signed negative number is implementation-defined.
                // Although most implementations sign-extend, we do it manually to ensure it works
                // correctly on all implementations.
                const UT msb = UT{1} << (bit_width - 1);
                UT sign_ext = 0;
                if (e1u & msb) {
                    // Set e2 + 1 bits to 1
                    UT num_shift_bits_mask = ((UT{1} << e2u) - UT{1});
                    sign_ext = (num_shift_bits_mask << (bit_width - e2u - UT{1})) | msb;
                }
                return static_cast<T>((e1u >> e2u) | sign_ext);
            };

            T result = 0;
            if constexpr (IsAbstract<NumberT>) {
                if (static_cast<size_t>(e2) >= bit_width) {
                    result = T{0};
                } else {
                    result = signed_shift_right();
                }
            } else {
                if (static_cast<size_t>(e2) >= bit_width) {
                    // At shader/pipeline-creation time, it is an error to shift by the bit width of
                    // the lhs or greater. NOTE: At runtime, we shift by e2 % (bit width of e1).
                    AddError(
                        "shift right value must be less than the bit width of the lhs, which is " +
                            std::to_string(bit_width),
                        source);
                    if (use_runtime_semantics_) {
                        e2u = e2u % bit_width;
                    } else {
                        return tint::Failure;
                    }
                }

                if constexpr (std::is_signed_v<T>) {
                    result = signed_shift_right();
                } else {
                    result = e1 >> e2u;
                }
            }
            return CreateScalar(source, ty->DeepestElement(), NumberT{result});
        };
        return Dispatch_ia_iu32(create, c0, c1);
    };

    if (TINT_UNLIKELY(!args[1]->Type()->DeepestElement()->Is<core::type::U32>())) {
        TINT_ICE() << "Element type of rhs of ShiftLeft must be a u32";
        return Failure;
    }

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::abs(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            NumberT result;
            if constexpr (IsUnsignedIntegral<NumberT>) {
                result = e;
            } else if constexpr (IsSignedIntegral<NumberT>) {
                if (e == NumberT::Lowest()) {
                    result = e;
                } else {
                    result = NumberT{std::abs(e)};
                }
            } else {
                result = NumberT{std::abs(e)};
            }
            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_fia_fiu32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::acos(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            if (i < NumberT(-1.0) || i > NumberT(1.0)) {
                AddError("acos must be called with a value in the range [-1 .. 1] (inclusive)",
                         source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), NumberT(std::acos(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::acosh(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            if (i < NumberT(1.0)) {
                AddError("acosh must be called with a value >= 1.0", source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), NumberT(std::acosh(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };

    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::all(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    return CreateScalar(source, ty, !args[0]->AnyZero());
}

Eval::Result Eval::any(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    return CreateScalar(source, ty, !args[0]->AllZero());
}

Eval::Result Eval::asin(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            if (i < NumberT(-1.0) || i > NumberT(1.0)) {
                AddError("asin must be called with a value in the range [-1 .. 1] (inclusive)",
                         source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), NumberT(std::asin(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::asinh(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) {
            return CreateScalar(source, c0->Type(), decltype(i)(std::asinh(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };

    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::atan(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) {
            return CreateScalar(source, c0->Type(), decltype(i)(std::atan(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::atanh(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            if (i <= NumberT(-1.0) || i >= NumberT(1.0)) {
                AddError("atanh must be called with a value in the range (-1 .. 1) (exclusive)",
                         source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), NumberT(std::atanh(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };

    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::atan2(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto i, auto j) {
            return CreateScalar(source, c0->Type(), decltype(i)(std::atan2(i.value, j.value)));
        };
        return Dispatch_fa_f32_f16(create, c0, c1);
    };
    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::ceil(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            return CreateScalar(source, c0->Type(), decltype(e)(std::ceil(e)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::clamp(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1, const Value* c2) {
        return Dispatch_fia_fiu32_f16(ClampFunc(source, c0->Type()), c0, c1, c2);
    };
    return TransformTernaryElements(mgr, ty, transform, args[0], args[1], args[2]);
}

Eval::Result Eval::cos(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            return CreateScalar(source, c0->Type(), NumberT(std::cos(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::cosh(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            return CreateScalar(source, c0->Type(), NumberT(std::cosh(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::countLeadingZeros(const core::type::Type* ty,
                                     VectorRef<const Value*> args,
                                     const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;
            auto count = CountLeadingBits(T{e}, T{0});
            return CreateScalar(source, c0->Type(), NumberT(count));
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::countOneBits(const core::type::Type* ty,
                                VectorRef<const Value*> args,
                                const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            constexpr UT kRightMost = UT{1};

            auto count = UT{0};
            for (auto v = static_cast<UT>(e); v != UT{0}; v >>= 1) {
                if ((v & kRightMost) == 1) {
                    ++count;
                }
            }

            return CreateScalar(source, c0->Type(), NumberT(count));
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::countTrailingZeros(const core::type::Type* ty,
                                      VectorRef<const Value*> args,
                                      const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;
            auto count = CountTrailingBits(T{e}, T{0});
            return CreateScalar(source, c0->Type(), NumberT(count));
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::cross(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto* u = args[0];
    auto* v = args[1];
    auto* elem_ty = u->Type()->As<core::type::Vector>()->type();

    // cross product of a v3 is the determinant of the 3x3 matrix:
    //
    // |i   j   k |
    // |u0  u1  u2|
    // |v0  v1  v2|
    //
    // |u1 u2|i  - |u0 u2|j + |u0 u1|k
    // |v1 v2|     |v0 v2|    |v0 v1|
    //
    // |u1 u2|i  + |v0 v2|j + |u0 u1|k
    // |v1 v2|     |u0 u2|    |v0 v1|

    auto* u0 = u->Index(0);
    auto* u1 = u->Index(1);
    auto* u2 = u->Index(2);
    auto* v0 = v->Index(0);
    auto* v1 = v->Index(1);
    auto* v2 = v->Index(2);

    auto x = Dispatch_fa_f32_f16(Det2Func(source, elem_ty), u1, u2, v1, v2);
    if (!x) {
        return tint::Failure;
    }
    auto y = Dispatch_fa_f32_f16(Det2Func(source, elem_ty), v0, v2, u0, u2);
    if (!y) {
        return tint::Failure;
    }
    auto z = Dispatch_fa_f32_f16(Det2Func(source, elem_ty), u0, u1, v0, v1);
    if (!z) {
        return tint::Failure;
    }

    return mgr.Composite(ty, Vector<const Value*, 3>{x.Get(), y.Get(), z.Get()});
}

Eval::Result Eval::degrees(const core::type::Type* ty,
                           VectorRef<const Value*> args,
                           const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) -> Eval::Result {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;

            auto pi = kPi<T>;
            auto scale = Div(source, NumberT(180), NumberT(pi));
            if (!scale) {
                AddNote("when calculating degrees", source);
                return tint::Failure;
            }
            auto result = Mul(source, e, scale.Get());
            if (!result) {
                AddNote("when calculating degrees", source);
                return tint::Failure;
            }
            return CreateScalar(source, c0->Type(), result.Get());
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::determinant(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    auto calculate = [&]() -> Eval::Result {
        auto* m = args[0];
        auto* mat_ty = m->Type()->As<core::type::Matrix>();
        auto me = [&](size_t r, size_t c) { return m->Index(c)->Index(r); };
        switch (mat_ty->rows()) {
            case 2:
                return Dispatch_fa_f32_f16(Det2Func(source, ty),  //
                                           me(0, 0), me(1, 0),    //
                                           me(0, 1), me(1, 1));

            case 3:
                return Dispatch_fa_f32_f16(Det3Func(source, ty),          //
                                           me(0, 0), me(1, 0), me(2, 0),  //
                                           me(0, 1), me(1, 1), me(2, 1),  //
                                           me(0, 2), me(1, 2), me(2, 2));

            case 4:
                return Dispatch_fa_f32_f16(Det4Func(source, ty),                    //
                                           me(0, 0), me(1, 0), me(2, 0), me(3, 0),  //
                                           me(0, 1), me(1, 1), me(2, 1), me(3, 1),  //
                                           me(0, 2), me(1, 2), me(2, 2), me(3, 2),  //
                                           me(0, 3), me(1, 3), me(2, 3), me(3, 3));
        }
        TINT_ICE() << "Unexpected number of matrix rows";
        return Failure;
    };
    auto r = calculate();
    if (!r) {
        AddNote("when calculating determinant", source);
    }
    return r;
}

Eval::Result Eval::distance(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source& source) {
    auto err = [&]() -> Eval::Result {
        AddNote("when calculating distance", source);
        return tint::Failure;
    };

    auto minus = Minus(args[0]->Type(), args, source);
    if (!minus) {
        return err();
    }

    auto len = Length(source, ty, minus.Get());
    if (!len) {
        return err();
    }
    return len;
}

Eval::Result Eval::dot(const core::type::Type*,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto r = Dot(source, args[0], args[1]);
    if (!r) {
        AddNote("when calculating dot", source);
    }
    return r;
}

Eval::Result Eval::exp(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e0) -> Eval::Result {
            using NumberT = decltype(e0);
            auto val = NumberT(std::exp(e0));
            if (!std::isfinite(val.value)) {
                AddError(OverflowExpErrorMessage("e", e0), source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), val);
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::exp2(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e0) -> Eval::Result {
            using NumberT = decltype(e0);
            auto val = NumberT(std::exp2(e0));
            if (!std::isfinite(val.value)) {
                AddError(OverflowExpErrorMessage("2", e0), source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), val);
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::extractBits(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto in_e) -> Eval::Result {
            using NumberT = decltype(in_e);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            using NumberUT = Number<UT>;

            // Read args that are always scalar
            NumberUT in_offset = args[1]->ValueAs<NumberUT>();
            NumberUT in_count = args[2]->ValueAs<NumberUT>();

            // Cast all to unsigned
            UT e = static_cast<UT>(in_e);
            UT o = static_cast<UT>(in_offset);
            UT c = static_cast<UT>(in_count);

            constexpr UT w = sizeof(UT) * 8;
            if (o > w || c > w || (o + c) > w) {
                AddError("'offset + 'count' must be less than or equal to the bit width of 'e'",
                         source);
                if (use_runtime_semantics_) {
                    o = std::min(o, w);
                    c = std::min(c, w - o);
                } else {
                    return tint::Failure;
                }
            }

            NumberT result;
            if (c == UT{0}) {
                // The result is 0 if c is 0
                result = NumberT{0};
            } else if (c == w) {
                // The result is e if c is w
                result = NumberT{e};
            } else {
                // Otherwise, bits 0..c - 1 of the result are copied from bits o..o + c - 1 of e.
                UT src_mask = ((UT{1} << c) - UT{1}) << o;
                UT r = (e & src_mask) >> o;
                if constexpr (IsSignedIntegral<NumberT>) {
                    // Other bits of the result are the same as bit c - 1 of the result.
                    // Only need to set other bits if bit at c - 1 of result is 1
                    if ((r & (UT{1} << (c - UT{1}))) != UT{0}) {
                        UT dst_mask = src_mask >> o;
                        r |= (~UT{0} & ~dst_mask);
                    }
                }

                result = NumberT{r};
            }
            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::faceForward(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    // Returns e1 if dot(e2, e3) is negative, and -e1 otherwise.
    auto* e1 = args[0];
    auto* e2 = args[1];
    auto* e3 = args[2];
    auto r = Dot(source, e2, e3);
    if (!r) {
        AddNote("when calculating faceForward", source);
        return tint::Failure;
    }
    auto is_negative = [](auto v) { return v < 0; };
    if (Dispatch_fa_f32_f16(is_negative, r.Get())) {
        return e1;
    }
    return UnaryMinus(ty, Vector{e1}, source);
}

Eval::Result Eval::firstLeadingBit(const core::type::Type* ty,
                                   VectorRef<const Value*> args,
                                   const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            constexpr UT kNumBits = sizeof(UT) * 8;

            NumberT result;
            if constexpr (IsUnsignedIntegral<T>) {
                if (e == T{0}) {
                    // T(-1) if e is zero.
                    result = NumberT(static_cast<T>(-1));
                } else {
                    // Otherwise the position of the most significant 1 bit in e.
                    static_assert(std::is_same_v<T, UT>);
                    UT count = CountLeadingBits(UT{e}, UT{0});
                    UT pos = kNumBits - count - 1;
                    result = NumberT(pos);
                }
            } else {
                if (e == T{0} || e == T{-1}) {
                    // -1 if e is 0 or -1.
                    result = NumberT(-1);
                } else {
                    // Otherwise the position of the most significant bit in e that is different
                    // from e's sign bit.
                    UT eu = static_cast<UT>(e);
                    UT sign_bit = eu >> (kNumBits - 1);
                    UT count = CountLeadingBits(eu, sign_bit);
                    UT pos = kNumBits - count - 1;
                    result = NumberT(pos);
                }
            }

            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::firstTrailingBit(const core::type::Type* ty,
                                    VectorRef<const Value*> args,
                                    const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;

            NumberT result;
            if (e == T{0}) {
                // T(-1) if e is zero.
                result = NumberT(static_cast<T>(-1));
            } else {
                // Otherwise the position of the least significant 1 bit in e.
                UT pos = CountTrailingBits(T{e}, T{0});
                result = NumberT(pos);
            }

            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::floor(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            return CreateScalar(source, c0->Type(), decltype(e)(std::floor(e)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::fma(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c1, const Value* c2, const Value* c3) {
        auto create = [&](auto e1, auto e2, auto e3) -> Eval::Result {
            auto err_msg = [&] {
                AddNote("when calculating fma", source);
                return tint::Failure;
            };

            auto mul = Mul(source, e1, e2);
            if (!mul) {
                return err_msg();
            }

            auto val = Add(source, mul.Get(), e3);
            if (!val) {
                return err_msg();
            }
            return CreateScalar(source, c1->Type(), val.Get());
        };
        return Dispatch_fa_f32_f16(create, c1, c2, c3);
    };
    return TransformTernaryElements(mgr, ty, transform, args[0], args[1], args[2]);
}

Eval::Result Eval::fract(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c1) {
        auto create = [&](auto e) -> Eval::Result {
            using NumberT = decltype(e);
            auto r = e - std::floor(e);
            return CreateScalar(source, c1->Type(), NumberT{r});
        };
        return Dispatch_fa_f32_f16(create, c1);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::frexp(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto* arg = args[0];

    struct FractExp {
        Eval::Result fract;
        Eval::Result exp;
    };

    auto scalar = [&](const Value* s) {
        int exp = 0;
        double fract = std::frexp(s->ValueAs<AFloat>(), &exp);
        return Switch(
            s->Type(),
            [&](const core::type::F32*) {
                return FractExp{
                    CreateScalar(source, mgr.types.f32(), f32(fract)),
                    CreateScalar(source, mgr.types.i32(), i32(exp)),
                };
            },
            [&](const core::type::F16*) {
                return FractExp{
                    CreateScalar(source, mgr.types.f16(), f16(fract)),
                    CreateScalar(source, mgr.types.i32(), i32(exp)),
                };
            },
            [&](const core::type::AbstractFloat*) {
                return FractExp{
                    CreateScalar(source, mgr.types.AFloat(), AFloat(fract)),
                    CreateScalar(source, mgr.types.AInt(), AInt(exp)),
                };
            },
            [&](Default) {
                TINT_ICE() << "unhandled element type for frexp() const-eval: "
                           << s->Type()->FriendlyName();
                return FractExp{Failure, Failure};
            });
    };

    if (auto* vec = arg->Type()->As<core::type::Vector>()) {
        Vector<const Value*, 4> fract_els;
        Vector<const Value*, 4> exp_els;
        for (uint32_t i = 0; i < vec->Width(); i++) {
            auto fe = scalar(arg->Index(i));
            if (!fe.fract || !fe.exp) {
                return tint::Failure;
            }
            fract_els.Push(fe.fract.Get());
            exp_els.Push(fe.exp.Get());
        }
        auto fract_ty = mgr.types.vec(fract_els[0]->Type(), vec->Width());
        auto exp_ty = mgr.types.vec(exp_els[0]->Type(), vec->Width());
        return mgr.Composite(ty, Vector<const Value*, 2>{
                                     mgr.Composite(fract_ty, std::move(fract_els)),
                                     mgr.Composite(exp_ty, std::move(exp_els)),
                                 });
    } else {
        auto fe = scalar(arg);
        if (!fe.fract || !fe.exp) {
            return tint::Failure;
        }
        return mgr.Composite(ty, Vector<const Value*, 2>{
                                     fe.fract.Get(),
                                     fe.exp.Get(),
                                 });
    }
}

Eval::Result Eval::insertBits(const core::type::Type* ty,
                              VectorRef<const Value*> args,
                              const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto in_e, auto in_newbits) -> Eval::Result {
            using NumberT = decltype(in_e);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            using NumberUT = Number<UT>;

            // Read args that are always scalar
            NumberUT in_offset = args[2]->ValueAs<NumberUT>();
            NumberUT in_count = args[3]->ValueAs<NumberUT>();

            // Cast all to unsigned
            UT e = static_cast<UT>(in_e);
            UT newbits = static_cast<UT>(in_newbits);
            UT o = static_cast<UT>(in_offset);
            UT c = static_cast<UT>(in_count);

            constexpr UT w = sizeof(UT) * 8;
            if (o > w || c > w || (o + c) > w) {
                AddError("'offset + 'count' must be less than or equal to the bit width of 'e'",
                         source);
                if (use_runtime_semantics_) {
                    o = std::min(o, w);
                    c = std::min(c, w - o);
                } else {
                    return tint::Failure;
                }
            }

            NumberT result;
            if (c == UT{0}) {
                // The result is e if c is 0
                result = NumberT{e};
            } else if (c == w) {
                // The result is newbits if c is w
                result = NumberT{newbits};
            } else {
                // Otherwise, bits o..o + c - 1 of the result are copied from bits 0..c - 1 of
                // newbits. Other bits of the result are copied from e.
                UT from = newbits << o;
                UT mask = ((UT{1} << c) - UT{1}) << UT{o};
                auto r = e;          // Start with 'e' as the result
                r &= ~mask;          // Zero the bits in 'e' we're overwriting
                r |= (from & mask);  // Overwrite from 'newbits' (shifted into position)
                result = NumberT{r};
            }

            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_iu32(create, c0, c1);
    };
    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::inverseSqrt(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) -> Eval::Result {
            using NumberT = decltype(e);

            if (e <= NumberT(0)) {
                AddError("inverseSqrt must be called with a value > 0", source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }

            auto err = [&] {
                AddNote("when calculating inverseSqrt", source);
                return tint::Failure;
            };

            auto s = Sqrt(source, e);
            if (!s) {
                return err();
            }
            auto div = Div(source, NumberT(1), s.Get());
            if (!div) {
                return err();
            }

            return CreateScalar(source, c0->Type(), div.Get());
        };
        return Dispatch_fa_f32_f16(create, c0);
    };

    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::ldexp(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c1, size_t index) {
        auto create = [&](auto e1) -> Eval::Result {
            using E1Type = decltype(e1);
            // If e1 is AFloat, then e2 is AInt, otherwise it's i32
            using E2Type = std::conditional_t<std::is_same_v<E1Type, AFloat>, AInt, i32>;

            E2Type e2;
            auto* c2 = args[1];
            if (c2->Type()->Is<core::type::Vector>()) {
                e2 = c2->Index(index)->ValueAs<E2Type>();
            } else {
                e2 = c2->ValueAs<E2Type>();
            }

            E2Type bias;
            if constexpr (std::is_same_v<E1Type, f16>) {
                bias = 15;
            } else if constexpr (std::is_same_v<E1Type, f32>) {
                bias = 127;
            } else {
                bias = 1023;
            }

            if (e2 > bias + 1) {
                AddError("e2 must be less than or equal to " + std::to_string(bias + 1), source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c1->Type());
                } else {
                    return tint::Failure;
                }
            }

            auto target_ty = ty->DeepestElement();

            auto r = std::ldexp(e1, static_cast<int>(e2));
            return CreateScalar(source, target_ty, E1Type{r});
        };
        return Dispatch_fa_f32_f16(create, c1);
    };

    return TransformElements(mgr, ty, transform, 0, args[0]);
}

Eval::Result Eval::length(const core::type::Type* ty,
                          VectorRef<const Value*> args,
                          const Source& source) {
    auto r = Length(source, ty, args[0]);
    if (!r) {
        AddNote("when calculating length", source);
    }
    return r;
}

Eval::Result Eval::log(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto v) -> Eval::Result {
            using NumberT = decltype(v);
            if (v <= NumberT(0)) {
                AddError("log must be called with a value > 0", source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), NumberT(std::log(v)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::log2(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto v) -> Eval::Result {
            using NumberT = decltype(v);
            if (v <= NumberT(0)) {
                AddError("log2 must be called with a value > 0", source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), NumberT(std::log2(v)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::max(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto e0, auto e1) {
            return CreateScalar(source, c0->Type(), decltype(e0)(std::max(e0, e1)));
        };
        return Dispatch_fia_fiu32_f16(create, c0, c1);
    };
    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::min(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto e0, auto e1) {
            return CreateScalar(source, c0->Type(), decltype(e0)(std::min(e0, e1)));
        };
        return Dispatch_fia_fiu32_f16(create, c0, c1);
    };
    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::mix(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1, size_t index) {
        auto create = [&](auto e1, auto e2) -> Eval::Result {
            using NumberT = decltype(e1);
            // e3 is either a vector or a scalar
            NumberT e3;
            auto* c2 = args[2];
            if (c2->Type()->Is<core::type::Vector>()) {
                e3 = c2->Index(index)->ValueAs<NumberT>();
            } else {
                e3 = c2->ValueAs<NumberT>();
            }
            // Implement as `e1 * (1 - e3) + e2 * e3)` instead of as `e1 + e3 * (e2 - e1)` to avoid
            // float precision loss when e1 and e2 significantly differ in magnitude.
            auto one_sub_e3 = Sub(source, NumberT{1}, e3);
            if (!one_sub_e3) {
                return tint::Failure;
            }
            auto e1_mul_one_sub_e3 = Mul(source, e1, one_sub_e3.Get());
            if (!e1_mul_one_sub_e3) {
                return tint::Failure;
            }
            auto e2_mul_e3 = Mul(source, e2, e3);
            if (!e2_mul_e3) {
                return tint::Failure;
            }
            auto r = Add(source, e1_mul_one_sub_e3.Get(), e2_mul_e3.Get());
            if (!r) {
                return tint::Failure;
            }
            return CreateScalar(source, c0->Type(), r.Get());
        };
        return Dispatch_fa_f32_f16(create, c0, c1);
    };
    auto r = TransformElements(mgr, ty, transform, 0, args[0], args[1]);
    if (!r) {
        AddNote("when calculating mix", source);
    }
    return r;
}

Eval::Result Eval::modf(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform_fract = [&](const Value* c) {
        auto create = [&](auto e) {
            return CreateScalar(source, c->Type(), decltype(e)(e.value - std::trunc(e.value)));
        };
        return Dispatch_fa_f32_f16(create, c);
    };
    auto transform_whole = [&](const Value* c) {
        auto create = [&](auto e) {
            return CreateScalar(source, c->Type(), decltype(e)(std::trunc(e.value)));
        };
        return Dispatch_fa_f32_f16(create, c);
    };

    Vector<const Value*, 2> fields;

    if (auto fract = TransformUnaryElements(mgr, args[0]->Type(), transform_fract, args[0])) {
        fields.Push(fract.Get());
    } else {
        return tint::Failure;
    }

    if (auto whole = TransformUnaryElements(mgr, args[0]->Type(), transform_whole, args[0])) {
        fields.Push(whole.Get());
    } else {
        return tint::Failure;
    }

    return mgr.Composite(ty, std::move(fields));
}

Eval::Result Eval::normalize(const core::type::Type* ty,
                             VectorRef<const Value*> args,
                             const Source& source) {
    auto* len_ty = ty->DeepestElement();
    auto len = Length(source, len_ty, args[0]);
    if (!len) {
        AddNote("when calculating normalize", source);
        return tint::Failure;
    }
    auto* v = len.Get();
    if (v->AllZero()) {
        AddError("zero length vector can not be normalized", source);
        if (use_runtime_semantics_) {
            return ZeroValue(ty);
        } else {
            return tint::Failure;
        }
    }
    return Divide(ty, Vector{args[0], v}, source);
}

Eval::Result Eval::pack2x16float(const core::type::Type* ty,
                                 VectorRef<const Value*> args,
                                 const Source& source) {
    auto convert = [&](f32 val) -> tint::Result<uint32_t> {
        auto conv = CheckedConvert<f16>(val);
        if (!conv) {
            AddError(OverflowErrorMessage(val, "f16"), source);
            if (use_runtime_semantics_) {
                return 0;
            } else {
                return tint::Failure;
            }
        }
        uint16_t v = conv.Get().BitsRepresentation();
        return tint::Result<uint32_t>{v};
    };

    auto* e = args[0];
    auto e0 = convert(e->Index(0)->ValueAs<f32>());
    if (!e0) {
        return tint::Failure;
    }

    auto e1 = convert(e->Index(1)->ValueAs<f32>());
    if (!e1) {
        return tint::Failure;
    }

    u32 ret = u32((e0.Get() & 0x0000'ffff) | (e1.Get() << 16));
    return CreateScalar(source, ty, ret);
}

Eval::Result Eval::pack2x16snorm(const core::type::Type* ty,
                                 VectorRef<const Value*> args,
                                 const Source& source) {
    auto calc = [&](f32 val) -> u32 {
        auto clamped = Clamp(source, val, f32(-1.0f), f32(1.0f)).Get();
        return u32(
            tint::Bitcast<uint16_t>(static_cast<int16_t>(std::floor(0.5f + (32767.0f * clamped)))));
    };

    auto* e = args[0];
    auto e0 = calc(e->Index(0)->ValueAs<f32>());
    auto e1 = calc(e->Index(1)->ValueAs<f32>());

    u32 ret = u32((e0 & 0x0000'ffff) | (e1 << 16));
    return CreateScalar(source, ty, ret);
}

Eval::Result Eval::pack2x16unorm(const core::type::Type* ty,
                                 VectorRef<const Value*> args,
                                 const Source& source) {
    auto calc = [&](f32 val) -> u32 {
        auto clamped = Clamp(source, val, f32(0.0f), f32(1.0f)).Get();
        return u32{std::floor(0.5f + (65535.0f * clamped))};
    };

    auto* e = args[0];
    auto e0 = calc(e->Index(0)->ValueAs<f32>());
    auto e1 = calc(e->Index(1)->ValueAs<f32>());

    u32 ret = u32((e0 & 0x0000'ffff) | (e1 << 16));
    return CreateScalar(source, ty, ret);
}

Eval::Result Eval::pack4x8snorm(const core::type::Type* ty,
                                VectorRef<const Value*> args,
                                const Source& source) {
    auto calc = [&](f32 val) -> u32 {
        auto clamped = Clamp(source, val, f32(-1.0f), f32(1.0f)).Get();
        return u32(
            tint::Bitcast<uint8_t>(static_cast<int8_t>(std::floor(0.5f + (127.0f * clamped)))));
    };

    auto* e = args[0];
    auto e0 = calc(e->Index(0)->ValueAs<f32>());
    auto e1 = calc(e->Index(1)->ValueAs<f32>());
    auto e2 = calc(e->Index(2)->ValueAs<f32>());
    auto e3 = calc(e->Index(3)->ValueAs<f32>());

    uint32_t mask = 0x0000'00ff;
    u32 ret = u32((e0 & mask) | ((e1 & mask) << 8) | ((e2 & mask) << 16) | ((e3 & mask) << 24));
    return CreateScalar(source, ty, ret);
}

Eval::Result Eval::pack4x8unorm(const core::type::Type* ty,
                                VectorRef<const Value*> args,
                                const Source& source) {
    auto calc = [&](f32 val) -> u32 {
        auto clamped = Clamp(source, val, f32(0.0f), f32(1.0f)).Get();
        return u32{std::floor(0.5f + (255.0f * clamped))};
    };

    auto* e = args[0];
    auto e0 = calc(e->Index(0)->ValueAs<f32>());
    auto e1 = calc(e->Index(1)->ValueAs<f32>());
    auto e2 = calc(e->Index(2)->ValueAs<f32>());
    auto e3 = calc(e->Index(3)->ValueAs<f32>());

    uint32_t mask = 0x0000'00ff;
    u32 ret = u32((e0 & mask) | ((e1 & mask) << 8) | ((e2 & mask) << 16) | ((e3 & mask) << 24));
    return CreateScalar(source, ty, ret);
}

Eval::Result Eval::pow(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto e1, auto e2) -> Eval::Result {
            auto r = CheckedPow(e1, e2);
            if (!r) {
                AddError(OverflowErrorMessage(e1, "^", e2), source);
                if (use_runtime_semantics_) {
                    return ZeroValue(c0->Type());
                } else {
                    return tint::Failure;
                }
            }
            return CreateScalar(source, c0->Type(), *r);
        };
        return Dispatch_fa_f32_f16(create, c0, c1);
    };
    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::radians(const core::type::Type* ty,
                           VectorRef<const Value*> args,
                           const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) -> Eval::Result {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;

            auto pi = kPi<T>;
            auto scale = Div(source, NumberT(pi), NumberT(180));
            if (!scale) {
                AddNote("when calculating radians", source);
                return tint::Failure;
            }
            auto result = Mul(source, e, scale.Get());
            if (!result) {
                AddNote("when calculating radians", source);
                return tint::Failure;
            }
            return CreateScalar(source, c0->Type(), result.Get());
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::reflect(const core::type::Type* ty,
                           VectorRef<const Value*> args,
                           const Source& source) {
    auto calculate = [&]() -> Eval::Result {
        // For the incident vector e1 and surface orientation e2, returns the reflection direction
        // e1 - 2 * dot(e2, e1) * e2.
        auto* e1 = args[0];
        auto* e2 = args[1];
        auto* vec_ty = ty->As<core::type::Vector>();
        auto* el_ty = vec_ty->type();

        // dot(e2, e1)
        auto dot_e2_e1 = Dot(source, e2, e1);
        if (!dot_e2_e1) {
            return tint::Failure;
        }

        // 2 * dot(e2, e1)
        auto mul2 = [&](auto v) -> Eval::Result {
            using NumberT = decltype(v);
            return CreateScalar(source, el_ty, NumberT{NumberT{2} * v});
        };
        auto dot_e2_e1_2 = Dispatch_fa_f32_f16(mul2, dot_e2_e1.Get());
        if (!dot_e2_e1_2) {
            return tint::Failure;
        }

        // 2 * dot(e2, e1) * e2
        auto dot_e2_e1_2_e2 = Mul(source, ty, dot_e2_e1_2.Get(), e2);
        if (!dot_e2_e1_2_e2) {
            return tint::Failure;
        }

        // e1 - 2 * dot(e2, e1) * e2
        return Sub(source, ty, e1, dot_e2_e1_2_e2.Get());
    };
    auto r = calculate();
    if (!r) {
        AddNote("when calculating reflect", source);
    }
    return r;
}

Eval::Result Eval::refract(const core::type::Type* ty,
                           VectorRef<const Value*> args,
                           const Source& source) {
    auto* vec_ty = ty->As<core::type::Vector>();
    auto* el_ty = vec_ty->type();

    auto compute_k = [&](auto e3, auto dot_e2_e1) -> Eval::Result {
        using NumberT = decltype(e3);
        // let k = 1.0 - e3 * e3 * (1.0 - dot(e2, e1) * dot(e2, e1))
        auto e3_squared = Mul(source, e3, e3);
        if (!e3_squared) {
            return tint::Failure;
        }
        auto dot_e2_e1_squared = Mul(source, dot_e2_e1, dot_e2_e1);
        if (!dot_e2_e1_squared) {
            return tint::Failure;
        }
        auto r = Sub(source, NumberT(1), dot_e2_e1_squared.Get());
        if (!r) {
            return tint::Failure;
        }
        r = Mul(source, e3_squared.Get(), r.Get());
        if (!r) {
            return tint::Failure;
        }
        r = Sub(source, NumberT(1), r.Get());
        if (!r) {
            return tint::Failure;
        }
        return CreateScalar(source, el_ty, r.Get());
    };

    auto compute_e2_scale = [&](auto e3, auto dot_e2_e1, auto k) -> Eval::Result {
        // e3 * dot(e2, e1) + sqrt(k)
        auto sqrt_k = Sqrt(source, k);
        if (!sqrt_k) {
            return tint::Failure;
        }
        auto r = Mul(source, e3, dot_e2_e1);
        if (!r) {
            return tint::Failure;
        }
        r = Add(source, r.Get(), sqrt_k.Get());
        if (!r) {
            return tint::Failure;
        }
        return CreateScalar(source, el_ty, r.Get());
    };

    auto calculate = [&]() -> Eval::Result {
        auto* e1 = args[0];
        auto* e2 = args[1];
        auto* e3 = args[2];

        // For the incident vector e1 and surface normal e2, and the ratio of indices of refraction
        // e3, let k = 1.0 - e3 * e3 * (1.0 - dot(e2, e1) * dot(e2, e1)). If k < 0.0, returns the
        // refraction vector 0.0, otherwise return the refraction vector e3 * e1 - (e3 * dot(e2, e1)
        // + sqrt(k)) * e2.

        // dot(e2, e1)
        auto dot_e2_e1 = Dot(source, e2, e1);
        if (!dot_e2_e1) {
            return tint::Failure;
        }

        // let k = 1.0 - e3 * e3 * (1.0 - dot(e2, e1) * dot(e2, e1))
        auto k = Dispatch_fa_f32_f16(compute_k, e3, dot_e2_e1.Get());
        if (!k) {
            return tint::Failure;
        }

        // If k < 0.0, returns the refraction vector 0.0
        if (k.Get()->ValueAs<AFloat>() < 0) {
            return ZeroValue(ty);
        }

        // Otherwise return the refraction vector e3 * e1 - (e3 * dot(e2, e1) + sqrt(k)) * e2
        auto e1_scaled = Mul(source, ty, e3, e1);
        if (!e1_scaled) {
            return tint::Failure;
        }
        auto e2_scale = Dispatch_fa_f32_f16(compute_e2_scale, e3, dot_e2_e1.Get(), k.Get());
        if (!e2_scale) {
            return tint::Failure;
        }
        auto e2_scaled = Mul(source, ty, e2_scale.Get(), e2);
        if (!e2_scaled) {
            return tint::Failure;
        }
        return Sub(source, ty, e1_scaled.Get(), e2_scaled.Get());
    };
    auto r = calculate();
    if (!r) {
        AddNote("when calculating refract", source);
    }
    return r;
}

Eval::Result Eval::reverseBits(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto in_e) -> Eval::Result {
            using NumberT = decltype(in_e);
            using T = UnwrapNumber<NumberT>;
            using UT = std::make_unsigned_t<T>;
            constexpr UT kNumBits = sizeof(UT) * 8;

            UT e = static_cast<UT>(in_e);
            UT r = UT{0};
            for (size_t s = 0; s < kNumBits; ++s) {
                // Write source 's' bit to destination 'd' bit if 1
                if (e & (UT{1} << s)) {
                    size_t d = kNumBits - s - 1;
                    r |= (UT{1} << d);
                }
            }

            return CreateScalar(source, c0->Type(), NumberT{r});
        };
        return Dispatch_iu32(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::round(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            using T = UnwrapNumber<NumberT>;

            auto integral = NumberT(0);
            auto fract = std::abs(std::modf(e.value, &(integral.value)));
            // When e lies halfway between integers k and k + 1, the result is k when k is even,
            // and k + 1 when k is odd.
            NumberT result = NumberT(0.0);
            if (fract == NumberT(0.5)) {
                // If the integral value is negative, then we need to subtract one in order to move
                // to the correct `k`. The half way check is `k` and `k + 1` which in the positive
                // case is `x` and `x + 1` but in the negative case is `x - 1` and `x`.
                T integral_val = integral.value;
                if (std::signbit(integral_val)) {
                    integral_val = std::abs(integral_val - 1);
                }
                if (uint64_t(integral_val) % 2 == 0) {
                    result = NumberT(std::floor(e.value));
                } else {
                    result = NumberT(std::ceil(e.value));
                }
            } else {
                result = NumberT(std::round(e.value));
            }
            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::saturate(const core::type::Type* ty,
                            VectorRef<const Value*> args,
                            const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) {
            using NumberT = decltype(e);
            return CreateScalar(source, c0->Type(),
                                NumberT(std::min(std::max(e, NumberT(0.0)), NumberT(1.0))));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::select_bool(const core::type::Type* ty,
                               VectorRef<const Value*> args,
                               const Source& source) {
    auto cond = args[2]->ValueAs<bool>();
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto f, auto t) -> Eval::Result {
            return CreateScalar(source, ty->DeepestElement(), cond ? t : f);
        };
        return Dispatch_fia_fiu32_f16_bool(create, c0, c1);
    };

    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::select_boolvec(const core::type::Type* ty,
                                  VectorRef<const Value*> args,
                                  const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1, size_t index) {
        auto create = [&](auto f, auto t) -> Eval::Result {
            // Get corresponding bool value at the current vector value index
            auto cond = args[2]->Index(index)->ValueAs<bool>();
            return CreateScalar(source, ty->DeepestElement(), cond ? t : f);
        };
        return Dispatch_fia_fiu32_f16_bool(create, c0, c1);
    };

    return TransformElements(mgr, ty, transform, 0, args[0], args[1]);
}

Eval::Result Eval::sign(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto e) -> Eval::Result {
            using NumberT = decltype(e);
            NumberT result;
            NumberT zero{0.0};
            if (e.value < zero) {
                result = NumberT{-1.0};
            } else if (e.value > zero) {
                result = NumberT{1.0};
            } else {
                result = zero;
            }
            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_fia_fi32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::sin(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            return CreateScalar(source, c0->Type(), NumberT(std::sin(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::sinh(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            return CreateScalar(source, c0->Type(), NumberT(std::sinh(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::smoothstep(const core::type::Type* ty,
                              VectorRef<const Value*> args,
                              const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1, const Value* c2) {
        auto create = [&](auto low, auto high, auto x) -> Eval::Result {
            using NumberT = decltype(low);

            auto err = [&] {
                AddNote("when calculating smoothstep", source);
                return tint::Failure;
            };

            // t = clamp((x - low) / (high - low), 0.0, 1.0)
            auto x_minus_low = Sub(source, x, low);
            auto high_minus_low = Sub(source, high, low);
            if (!x_minus_low || !high_minus_low) {
                return err();
            }

            auto div = Div(source, x_minus_low.Get(), high_minus_low.Get());
            if (!div) {
                return err();
            }

            auto clamp = Clamp(source, div.Get(), NumberT(0), NumberT(1));
            auto t = clamp.Get();

            // result = t * t * (3.0 - 2.0 * t)
            auto t_times_t = Mul(source, t, t);
            auto t_times_2 = Mul(source, NumberT(2), t);
            if (!t_times_t || !t_times_2) {
                return err();
            }

            auto three_minus_t_times_2 = Sub(source, NumberT(3), t_times_2.Get());
            if (!three_minus_t_times_2) {
                return err();
            }

            auto result = Mul(source, t_times_t.Get(), three_minus_t_times_2.Get());
            if (!result) {
                return err();
            }
            return CreateScalar(source, c0->Type(), result.Get());
        };
        return Dispatch_fa_f32_f16(create, c0, c1, c2);
    };
    return TransformTernaryElements(mgr, ty, transform, args[0], args[1], args[2]);
}

Eval::Result Eval::step(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0, const Value* c1) {
        auto create = [&](auto edge, auto x) -> Eval::Result {
            using NumberT = decltype(edge);
            NumberT result = x.value < edge.value ? NumberT(0.0) : NumberT(1.0);
            return CreateScalar(source, c0->Type(), result);
        };
        return Dispatch_fa_f32_f16(create, c0, c1);
    };
    return TransformBinaryElements(mgr, ty, transform, args[0], args[1]);
}

Eval::Result Eval::sqrt(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        return Dispatch_fa_f32_f16(SqrtFunc(source, c0->Type()), c0);
    };

    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::tan(const core::type::Type* ty,
                       VectorRef<const Value*> args,
                       const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            return CreateScalar(source, c0->Type(), NumberT(std::tan(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::tanh(const core::type::Type* ty,
                        VectorRef<const Value*> args,
                        const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) -> Eval::Result {
            using NumberT = decltype(i);
            return CreateScalar(source, c0->Type(), NumberT(std::tanh(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::transpose(const core::type::Type* ty,
                             VectorRef<const Value*> args,
                             const Source&) {
    auto* m = args[0];
    auto* mat_ty = m->Type()->As<core::type::Matrix>();
    auto me = [&](size_t r, size_t c) { return m->Index(c)->Index(r); };
    auto* result_mat_ty = ty->As<core::type::Matrix>();

    // Produce column vectors from each row
    Vector<const Value*, 4> result_mat;
    for (size_t r = 0; r < mat_ty->rows(); ++r) {
        Vector<const Value*, 4> new_col_vec;
        for (size_t c = 0; c < mat_ty->columns(); ++c) {
            new_col_vec.Push(me(r, c));
        }
        result_mat.Push(mgr.Composite(result_mat_ty->ColumnType(), new_col_vec));
    }
    return mgr.Composite(ty, result_mat);
}

Eval::Result Eval::trunc(const core::type::Type* ty,
                         VectorRef<const Value*> args,
                         const Source& source) {
    auto transform = [&](const Value* c0) {
        auto create = [&](auto i) {
            return CreateScalar(source, c0->Type(), decltype(i)(std::trunc(i.value)));
        };
        return Dispatch_fa_f32_f16(create, c0);
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::unpack2x16float(const core::type::Type* ty,
                                   VectorRef<const Value*> args,
                                   const Source& source) {
    auto* inner_ty = ty->DeepestElement();
    auto e = args[0]->ValueAs<u32>().value;

    Vector<const Value*, 2> els;
    els.Reserve(2);
    for (size_t i = 0; i < 2; ++i) {
        auto in = f16::FromBits(uint16_t((e >> (16 * i)) & 0x0000'ffff));
        auto val = CheckedConvert<f32>(in);
        if (!val) {
            AddError(OverflowErrorMessage(in, "f32"), source);
            if (use_runtime_semantics_) {
                val = f32(0.f);
            } else {
                return tint::Failure;
            }
        }
        auto el = CreateScalar(source, inner_ty, val.Get());
        if (!el) {
            return el;
        }
        els.Push(el.Get());
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::unpack2x16snorm(const core::type::Type* ty,
                                   VectorRef<const Value*> args,
                                   const Source& source) {
    auto* inner_ty = ty->DeepestElement();
    auto e = args[0]->ValueAs<u32>().value;

    Vector<const Value*, 2> els;
    els.Reserve(2);
    for (size_t i = 0; i < 2; ++i) {
        auto val = f32(
            std::max(static_cast<float>(int16_t((e >> (16 * i)) & 0x0000'ffff)) / 32767.f, -1.f));
        auto el = CreateScalar(source, inner_ty, val);
        if (!el) {
            return el;
        }
        els.Push(el.Get());
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::unpack2x16unorm(const core::type::Type* ty,
                                   VectorRef<const Value*> args,
                                   const Source& source) {
    auto* inner_ty = ty->DeepestElement();
    auto e = args[0]->ValueAs<u32>().value;

    Vector<const Value*, 2> els;
    els.Reserve(2);
    for (size_t i = 0; i < 2; ++i) {
        auto val = f32(static_cast<float>(uint16_t((e >> (16 * i)) & 0x0000'ffff)) / 65535.f);
        auto el = CreateScalar(source, inner_ty, val);
        if (!el) {
            return el;
        }
        els.Push(el.Get());
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::unpack4x8snorm(const core::type::Type* ty,
                                  VectorRef<const Value*> args,
                                  const Source& source) {
    auto* inner_ty = ty->DeepestElement();
    auto e = args[0]->ValueAs<u32>().value;

    Vector<const Value*, 4> els;
    els.Reserve(4);
    for (size_t i = 0; i < 4; ++i) {
        auto val =
            f32(std::max(static_cast<float>(int8_t((e >> (8 * i)) & 0x0000'00ff)) / 127.f, -1.f));
        auto el = CreateScalar(source, inner_ty, val);
        if (!el) {
            return el;
        }
        els.Push(el.Get());
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::unpack4x8unorm(const core::type::Type* ty,
                                  VectorRef<const Value*> args,
                                  const Source& source) {
    auto* inner_ty = ty->DeepestElement();
    auto e = args[0]->ValueAs<u32>().value;

    Vector<const Value*, 4> els;
    els.Reserve(4);
    for (size_t i = 0; i < 4; ++i) {
        auto val = f32(static_cast<float>(uint8_t((e >> (8 * i)) & 0x0000'00ff)) / 255.f);
        auto el = CreateScalar(source, inner_ty, val);
        if (!el) {
            return el;
        }
        els.Push(el.Get());
    }
    return mgr.Composite(ty, std::move(els));
}

Eval::Result Eval::quantizeToF16(const core::type::Type* ty,
                                 VectorRef<const Value*> args,
                                 const Source& source) {
    auto transform = [&](const Value* c) -> Eval::Result {
        auto value = c->ValueAs<f32>();
        auto conv = CheckedConvert<f32>(f16(value));
        if (!conv) {
            AddError(OverflowErrorMessage(value, "f16"), source);
            if (use_runtime_semantics_) {
                return ZeroValue(c->Type());
            } else {
                return tint::Failure;
            }
        }
        return CreateScalar(source, c->Type(), conv.Get());
    };
    return TransformUnaryElements(mgr, ty, transform, args[0]);
}

Eval::Result Eval::Convert(const core::type::Type* target_ty,
                           const Value* value,
                           const Source& source) {
    if (value->Type() == target_ty) {
        return value;
    }
    ConvertContext ctx{mgr, diags, source, use_runtime_semantics_};
    auto* converted = ConvertInternal(value, target_ty, ctx);
    return converted ? Result(converted) : tint::Failure;
}

void Eval::AddError(const std::string& msg, const Source& source) const {
    if (use_runtime_semantics_) {
        diags.add_warning(diag::System::Constant, msg, source);
    } else {
        diags.add_error(diag::System::Constant, msg, source);
    }
}

void Eval::AddWarning(const std::string& msg, const Source& source) const {
    diags.add_warning(diag::System::Constant, msg, source);
}

void Eval::AddNote(const std::string& msg, const Source& source) const {
    diags.add_note(diag::System::Constant, msg, source);
}

}  // namespace tint::core::constant
