Import Tint changes from Dawn

Changes:
  - d060f36a1cb56df491820b10bdeb6a3258e7a73c tint: refactor Number<T> constants for highest, lowest, e... by Antonio Maiorano <amaiorano@google.com>
  - 00cc485addeabbda12ff2bcc0d3fd52c08177fad Regex fuzzer: add swizzles by Alastair F. Donaldson <alastair.donaldson@imperial.ac.uk>
  - 3ca6880cafc49060b65c8768712e41c200102045 tint/sem: Add conversion handling of array types by Ben Clayton <bclayton@google.com>
  - 6fb5d379c2fd5f7415e793056b22d09a9626870a tint/sem: Add const to StructMember 'type'. by Ben Clayton <bclayton@google.com>
  - 8e0368e554917c4ee6913dc3d86e05aefa092716 tint: Use utils::Vector for sem::Type::Common() by Ben Clayton <bclayton@google.com>
  - 05a76183e0c071827a14301108c885752f451a04 tint: Split Resolver::Materialize() by Ben Clayton <bclayton@google.com>
  - ea84b9b07252c5e65abb459403bae123e477c594 tint/sem: Treat abstract-numerics as scalars. by Ben Clayton <bclayton@google.com>
  - 6fe1f515d4b4411fb44bb656ab804b833d16526a tint: Add f16 support for parts of float built-in, part 1 by Zhaoming Jiang <zhaoming.jiang@intel.com>
  - 65dcdcbad08f7cd32ae0925cec42be269ada4a81 tint/resolver: Clean up the SPIRV builder built-in unitte... by Zhaoming Jiang <zhaoming.jiang@intel.com>
GitOrigin-RevId: d060f36a1cb56df491820b10bdeb6a3258e7a73c
Change-Id: I1b4c7cee3fe182eda2b358b88cd46dcee64eb519
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/97720
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc b/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
index ea1aea1..9ffea24 100644
--- a/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
+++ b/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
@@ -40,6 +40,7 @@
     kReplaceOperator,
     kInsertBreakOrContinue,
     kReplaceFunctionCallWithBuiltin,
+    kAddSwizzle,
     kNumMutationKinds
 };
 
@@ -121,6 +122,11 @@
                 return 0;
             }
             break;
+        case MutationKind::kAddSwizzle:
+            if (!mutator.AddSwizzle(wgsl_code)) {
+                return 0;
+            }
+            break;
         default:
             assert(false && "Unreachable");
             return 0;
diff --git a/src/tint/fuzzers/tint_regex_fuzzer/regex_fuzzer_tests.cc b/src/tint/fuzzers/tint_regex_fuzzer/regex_fuzzer_tests.cc
index 9e0b1a0..fb1d508 100644
--- a/src/tint/fuzzers/tint_regex_fuzzer/regex_fuzzer_tests.cc
+++ b/src/tint/fuzzers/tint_regex_fuzzer/regex_fuzzer_tests.cc
@@ -28,13 +28,15 @@
 
     using WgslMutator::DeleteInterval;
     using WgslMutator::DuplicateInterval;
-    using WgslMutator::FindClosingBrace;
+    using WgslMutator::FindClosingBracket;
     using WgslMutator::FindOperatorOccurrence;
     using WgslMutator::GetFunctionBodyPositions;
     using WgslMutator::GetFunctionCallIdentifiers;
     using WgslMutator::GetIdentifiers;
     using WgslMutator::GetIntLiterals;
     using WgslMutator::GetLoopBodyPositions;
+    using WgslMutator::GetSwizzles;
+    using WgslMutator::GetVectorConstructors;
     using WgslMutator::ReplaceRegion;
     using WgslMutator::SwapIntervals;
 };
@@ -238,11 +240,8 @@
 
     std::vector<std::pair<size_t, size_t>> identifiers_pos = mutator.GetIdentifiers(wgsl_code);
     std::vector<std::pair<size_t, size_t>> ground_truth = {
-        {0, 2},   {3, 12},  {28, 3},   {32, 3},   {37, 4},   {42, 3},   {49, 5},  {55, 4},
-        {60, 3},  {68, 4},  {73, 3},   {81, 4},   {86, 3},   {110, 6},  {123, 2}, {126, 11},
-        {144, 7}, {152, 8}, {162, 4},  {167, 3},  {183, 12}, {209, 6},  {216, 4}, {221, 3},
-        {244, 8}, {259, 2}, {262, 13}, {288, 12}, {319, 7},  {328, 14}, {352, 2}, {355, 12},
-        {381, 3}, {385, 7}, {394, 3},  {399, 3},  {418, 12}};
+        {3, 12},   {32, 3},   {49, 5},   {126, 11}, {144, 7}, {152, 8}, {183, 12},
+        {262, 13}, {288, 12}, {328, 14}, {355, 12}, {385, 7}, {394, 3}, {418, 12}};
     ASSERT_EQ(ground_truth, identifiers_pos);
 }
 
@@ -316,7 +315,8 @@
         var foo_3 : i32 = -20;
       )";
     size_t opening_bracket_pos = 18;
-    size_t closing_bracket_pos = mutator.FindClosingBrace(opening_bracket_pos, wgsl_code);
+    size_t closing_bracket_pos =
+        mutator.FindClosingBracket(opening_bracket_pos, wgsl_code, '{', '}');
 
     // The -1 is needed since the function body starts after the left bracket.
     std::string function_body =
@@ -363,7 +363,8 @@
       foo_1 = 5 + 7;
       var foo_3 : i32 = -20;)";
     size_t opening_bracket_pos = 18;
-    size_t closing_bracket_pos = mutator.FindClosingBrace(opening_bracket_pos, wgsl_code);
+    size_t closing_bracket_pos =
+        mutator.FindClosingBracket(opening_bracket_pos, wgsl_code, '{', '}');
 
     // The -1 is needed since the function body starts after the left bracket.
     std::string function_body =
@@ -639,5 +640,30 @@
     ASSERT_EQ(ground_truth, call_identifiers);
 }
 
+TEST(TestAddSwizzle, FindSwizzles) {
+    RandomGenerator generator(0);
+    WgslMutatorTest mutator(generator);
+    std::string code = R"(x
+v.xxyy.wz.x;
+u.rgba.rrg.b)";
+    std::vector<std::pair<size_t, size_t>> swizzles = mutator.GetSwizzles(code);
+    std::vector<std::pair<size_t, size_t>> ground_truth{{3, 5},  {8, 3},  {11, 2},
+                                                        {16, 5}, {21, 4}, {25, 2}};
+    ASSERT_EQ(ground_truth, swizzles);
+}
+
+TEST(TestAddSwizzle, FindVectorConstructors) {
+    RandomGenerator generator(0);
+    WgslMutatorTest mutator(generator);
+    std::string code = R"(
+vec4<f32>(vec2<f32>(1, 2), vec2<f32>(3))
+
+vec2<i32>(1, abs(abs(2)))
+)";
+    std::vector<std::pair<size_t, size_t>> swizzles = mutator.GetVectorConstructors(code);
+    std::vector<std::pair<size_t, size_t>> ground_truth{{1, 40}, {11, 15}, {28, 12}, {43, 25}};
+    ASSERT_EQ(ground_truth, swizzles);
+}
+
 }  // namespace
 }  // namespace tint::fuzzers::regex_fuzzer
diff --git a/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc b/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc
index a965613..46db837 100644
--- a/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc
+++ b/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc
@@ -19,6 +19,7 @@
 #include <map>
 #include <regex>
 #include <string>
+#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -39,9 +40,19 @@
     return result;
 }
 
+std::unordered_set<std::string> WgslMutator::GetCommonKeywords() {
+    return {"array",  "bool", "break", "compute", "continue", "f32",  "fn",     "fragment",
+            "i32",    "if",   "for",   "let",     "location", "loop", "ptr",    "return",
+            "struct", "u32",  "var",   "vec2",    "vec3",     "vec4", "vertex", "while"};
+}
+
 std::vector<std::pair<size_t, size_t>> WgslMutator::GetIdentifiers(const std::string& wgsl_code) {
     std::vector<std::pair<size_t, size_t>> result;
 
+    // To reduce the rate that invalid programs are produced, common keywords will be excluded from
+    // the identifiers that are returned.
+    std::unordered_set<std::string> common_keywords = GetCommonKeywords();
+
     // This regular expression works by looking for a character that
     // is not part of an identifier followed by a WGSL identifier, followed
     // by a character which cannot be part of a WGSL identifer. The regex
@@ -54,6 +65,10 @@
     auto identifiers_end = std::sregex_iterator();
 
     for (std::sregex_iterator i = identifiers_begin; i != identifiers_end; ++i) {
+        if (common_keywords.count(i->str()) > 0) {
+            // This is a common keyword, so skip it.
+            continue;
+        }
         result.push_back(
             {static_cast<size_t>(i->prefix().second - wgsl_code.cbegin()), i->str().size()});
     }
@@ -99,13 +114,16 @@
     return result;
 }
 
-size_t WgslMutator::FindClosingBrace(size_t opening_bracket_pos, const std::string& wgsl_code) {
+size_t WgslMutator::FindClosingBracket(size_t opening_bracket_pos,
+                                       const std::string& wgsl_code,
+                                       char opening_bracket_character,
+                                       char closing_bracket_character) {
     size_t open_bracket_count = 1;
     size_t pos = opening_bracket_pos + 1;
     while (open_bracket_count >= 1 && pos < wgsl_code.size()) {
-        if (wgsl_code[pos] == '{') {
+        if (wgsl_code[pos] == opening_bracket_character) {
             ++open_bracket_count;
-        } else if (wgsl_code[pos] == '}') {
+        } else if (wgsl_code[pos] == closing_bracket_character) {
             --open_bracket_count;
         }
         ++pos;
@@ -160,7 +178,7 @@
     // function body.
     size_t left_bracket_pos = function.first;
 
-    size_t right_bracket_pos = FindClosingBrace(left_bracket_pos, wgsl_code);
+    size_t right_bracket_pos = FindClosingBracket(left_bracket_pos, wgsl_code, '{', '}');
 
     if (right_bracket_pos == 0) {
         return false;
@@ -206,7 +224,7 @@
     // bracket, and find a semi-colon within the loop body.
     size_t left_bracket_pos = generator_.GetRandomElement(loop_body_positions);
 
-    size_t right_bracket_pos = FindClosingBrace(left_bracket_pos, wgsl_code);
+    size_t right_bracket_pos = FindClosingBracket(left_bracket_pos, wgsl_code, '{', '}');
 
     if (right_bracket_pos == 0) {
         return false;
@@ -515,11 +533,10 @@
     // Pick a random function
     auto function = generator_.GetRandomElement(function_body_positions);
 
-    // Find the corresponding closing bracket for the function, and find a semi-colon within the
-    // function body.
+    // Find the corresponding closing bracket for the function.
     size_t left_bracket_pos = function.first;
 
-    size_t right_bracket_pos = FindClosingBrace(left_bracket_pos, wgsl_code);
+    size_t right_bracket_pos = FindClosingBracket(left_bracket_pos, wgsl_code, '{', '}');
 
     if (right_bracket_pos == 0) {
         return false;
@@ -652,4 +669,127 @@
     return true;
 }
 
+bool WgslMutator::AddSwizzle(std::string& wgsl_code) {
+    std::vector<std::pair<size_t, bool>> function_body_positions =
+        GetFunctionBodyPositions(wgsl_code);
+
+    // No function was found in wgsl_code.
+    if (function_body_positions.empty()) {
+        return false;
+    }
+
+    // Pick a random function
+    auto function = generator_.GetRandomElement(function_body_positions);
+
+    // Find the corresponding closing bracket for the function.
+    size_t left_bracket_pos = function.first;
+    size_t right_bracket_pos = FindClosingBracket(left_bracket_pos, wgsl_code, '{', '}');
+
+    if (right_bracket_pos == 0) {
+        return false;
+    }
+
+    std::string function_body(
+        wgsl_code.substr(left_bracket_pos, right_bracket_pos - left_bracket_pos));
+
+    // It makes sense to try applying swizzles to:
+    // - identifiers, because they might be vectors
+    auto identifiers = GetIdentifiers(function_body);
+    // - existing swizzles, e.g. to turn v.xy into v.xy.xx
+    auto swizzles = GetSwizzles(function_body);
+    // - vector constructors, e.g. to turn vec3<f32>(...) into vec3<f32>(...).yyz
+    auto vector_constructors = GetVectorConstructors(function_body);
+
+    // Create a combined vector of all the possibilities for swizzling, so that they can be sampled
+    // from as a whole.
+    std::vector<std::pair<size_t, size_t>> combined;
+    combined.insert(combined.end(), identifiers.begin(), identifiers.end());
+    combined.insert(combined.end(), swizzles.begin(), swizzles.end());
+    combined.insert(combined.end(), vector_constructors.begin(), vector_constructors.end());
+
+    if (combined.empty()) {
+        // No opportunities for swizzling: give up.
+        return false;
+    }
+
+    // Randomly create a swizzle operation. This is done without checking the potential length of
+    // the target vector. For identifiers this isn't possible without proper context. For existing
+    // swizzles and vector constructors it would be possible to check the length, but it is anyway
+    // good to stress-test swizzle validation code paths.
+    std::string swizzle = ".";
+    {
+        // Choose a swizzle length between 1 and 4, inclusive.
+        uint32_t swizzle_length = generator_.GetUInt32(1, 5);
+        // Decide whether to use xyzw or rgba as convenience names.
+        bool use_xyzw = generator_.GetBool();
+        // Randomly choose a convenience name for each component of the swizzle.
+        for (uint32_t i = 0; i < swizzle_length; i++) {
+            switch (generator_.GetUInt32(4)) {
+                case 0:
+                    swizzle += use_xyzw ? "x" : "r";
+                    break;
+                case 1:
+                    swizzle += use_xyzw ? "y" : "g";
+                    break;
+                case 2:
+                    swizzle += use_xyzw ? "z" : "b";
+                    break;
+                case 3:
+                    swizzle += use_xyzw ? "w" : "a";
+                    break;
+                default:
+                    assert(false && "Unreachable");
+                    break;
+            }
+        }
+    }
+    // Choose a random opportunity for swizzling and add the swizzle right after it.
+    auto target = generator_.GetRandomElement(combined);
+    wgsl_code.insert(left_bracket_pos + target.first + target.second, swizzle);
+    return true;
+}
+
+std::vector<std::pair<size_t, size_t>> WgslMutator::GetSwizzles(const std::string& wgsl_code) {
+    std::regex swizzle_regex("\\.(([xyzw]+)|([rgba]+))");
+    std::vector<std::pair<size_t, size_t>> result;
+
+    auto swizzles_begin = std::sregex_iterator(wgsl_code.begin(), wgsl_code.end(), swizzle_regex);
+    auto swizles_end = std::sregex_iterator();
+
+    for (std::sregex_iterator i = swizzles_begin; i != swizles_end; ++i) {
+        result.push_back(
+            {static_cast<size_t>(i->prefix().second - wgsl_code.cbegin()), i->str().size()});
+    }
+    return result;
+}
+
+std::vector<std::pair<size_t, size_t>> WgslMutator::GetVectorConstructors(
+    const std::string& wgsl_code) {
+    // This regex recognises the prefixes of vector constructors, which have the form:
+    // "vecn<type>(", with possible whitespace between tokens.
+    std::regex vector_constructor_prefix_regex("vec\\d[ \\n]*<[ \\n]*[a-z0-9_]+[ \\n]*>[^\\(]*\\(");
+    std::vector<std::pair<size_t, size_t>> result;
+
+    auto vector_constructor_prefixes_begin =
+        std::sregex_iterator(wgsl_code.begin(), wgsl_code.end(), vector_constructor_prefix_regex);
+    auto vector_constructor_prefixes_end = std::sregex_iterator();
+
+    // Look through all of the vector constructor prefixes and see whether each one appears to
+    // correspond to a complete vector construction.
+    for (std::sregex_iterator i = vector_constructor_prefixes_begin;
+         i != vector_constructor_prefixes_end; ++i) {
+        // A prefix is deemed to correspond to a complete vector construction if it is possible to
+        // find a corresponding closing bracket for the "(" at the end of the prefix.
+        size_t closing_bracket = FindClosingBracket(
+            static_cast<size_t>(i->suffix().first - wgsl_code.cbegin()), wgsl_code, '(', ')');
+        if (closing_bracket != 0) {
+            // A closing bracket was found, so record the start and size of the entire vector
+            // constructor.
+            size_t start = static_cast<size_t>(i->prefix().second - wgsl_code.cbegin());
+            result.push_back({start, closing_bracket - start + 1});
+        }
+    }
+    return result;
+}
+
 }  // namespace tint::fuzzers::regex_fuzzer
diff --git a/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.h b/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.h
index fde4611..cd1f2b6 100644
--- a/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.h
+++ b/src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.h
@@ -17,6 +17,7 @@
 
 #include <optional>
 #include <string>
+#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -92,6 +93,12 @@
     /// @return true if a function call replacement happened or false otherwise.
     bool ReplaceFunctionCallWithBuiltin(std::string& wgsl_code);
 
+    /// Given a WGSL-like string, adds a swizzle operation to either (a) an identifier, (b) a vector
+    /// constructor, or (c) an existing swizzle.
+    /// @param wgsl_code - the initial WGSL-like string that will be mutated.
+    /// @return true if a swizzle operation is added or false otherwise.
+    bool AddSwizzle(std::string& wgsl_code);
+
   protected:
     /// Given index idx1 it delets the region of length interval_len
     /// starting at index idx1;
@@ -108,13 +115,18 @@
     /// @param wgsl_code - the string where the swap will occur.
     void DuplicateInterval(size_t idx1, size_t reg1_len, size_t idx2, std::string& wgsl_code);
 
-    /// Finds a possible closing brace corresponding to the opening
-    /// brace at position opening_bracket_pos.
-    /// @param opening_bracket_pos - the position of the opening brace.
-    /// @param wgsl_code - the WGSL-like string where the closing brace.
+    /// Finds a possible closing bracket corresponding to the opening
+    /// bracket at position opening_bracket_pos.
+    /// @param opening_bracket_pos - the position of the opening bracket.
+    /// @param wgsl_code - the WGSL-like string where the closing bracket.
+    /// @param opening_bracket_character - the opening bracket character, e.g. (, {, <, or [
+    /// @param closing_bracket_character - the closing bracket character, e.g. ), }, >, or ]
     /// @return the position of the closing bracket or 0 if there is no closing
-    /// brace.
-    size_t FindClosingBrace(size_t opening_bracket_pos, const std::string& wgsl_code);
+    /// bracket.
+    size_t FindClosingBracket(size_t opening_bracket_pos,
+                              const std::string& wgsl_code,
+                              char opening_bracket_character,
+                              char closing_bracket_character);
 
     /// Returns the starting position of the bodies of the functions identified by an appropriate
     /// function, together with a boolean indicating whether the function returns a value or not.
@@ -195,6 +207,16 @@
         const std::string& wgsl_code,
         uint32_t start_index);
 
+    /// Finds all the swizzle operations in a WGSL-like string.
+    /// @param wgsl_code - the WGSL-like string where the swizzles will be found.
+    /// @return a vector with the positions and lengths of all the swizzles in wgsl_code.
+    std::vector<std::pair<size_t, size_t>> GetSwizzles(const std::string& wgsl_code);
+
+    /// Finds all the vector constructors in a WGSL-like string.
+    /// @param wgsl_code - the WGSL-like string where the vector constructors will be found.
+    /// @return a vector with the positions and lengths of all the vector constructors in wgsl_code.
+    std::vector<std::pair<size_t, size_t>> GetVectorConstructors(const std::string& wgsl_code);
+
   private:
     /// A function that given a delimiter, returns a vector that contains
     /// all the positions of the delimiter in the WGSL code.
@@ -222,6 +244,14 @@
     /// @return another WGSL operator falling into the same category.
     std::string ChooseRandomReplacementForOperator(const std::string& existing_operator);
 
+    /// Yields a fixed set of commonly-used WGSL keywords. The regex fuzzer relies heavily on
+    /// recognizing possible identifiers via regular expressions. There is a high chance that
+    /// keywords will be recognized as identifiers, which will leads to invalid code. It is valuable
+    /// for this to occur to some extent (to stress test validation), but it is useful to be able to
+    /// exclude the most common keywords so that invalidity does not occur too often.
+    /// @return a set of commonly-used WGSL keywords.
+    static std::unordered_set<std::string> GetCommonKeywords();
+
     RandomGenerator& generator_;
 };
 
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 072d38a..6e1d8fb 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -165,6 +165,7 @@
 match scalar_no_i32: f32 | f16 | u32 | bool
 match scalar_no_u32: f32 | f16 | i32 | bool
 match scalar_no_bool: f32 | f16 | i32 | u32
+match fia_fiu32_f16: fa | ia | f32 | i32 | u32 | f16
 match fia_fi32_f16: fa | ia | f32 | i32 | f16
 match fia_fiu32: fa | ia | f32 | i32 | u32
 match fa_f32: fa | f32
@@ -386,48 +387,48 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 // https://gpuweb.github.io/gpuweb/wgsl/#builtin-functions
-fn abs<T: fiu32>(T) -> T
-fn abs<N: num, T: fiu32>(vec<N, T>) -> vec<N, T>
-fn acos(f32) -> f32
-fn acos<N: num>(vec<N, f32>) -> vec<N, f32>
-fn acosh(f32) -> f32
-fn acosh<N: num>(vec<N, f32>) -> vec<N, f32>
+fn abs<T: fiu32_f16>(T) -> T
+fn abs<N: num, T: fiu32_f16>(vec<N, T>) -> vec<N, T>
+fn acos<T: f32_f16>(T) -> T
+fn acos<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn acosh<T: f32_f16>(T) -> T
+fn acosh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
 fn all(bool) -> bool
 fn all<N: num>(vec<N, bool>) -> bool
 fn any(bool) -> bool
 fn any<N: num>(vec<N, bool>) -> bool
 fn arrayLength<T, A: access>(ptr<storage, array<T>, A>) -> u32
-fn asin(f32) -> f32
-fn asin<N: num>(vec<N, f32>) -> vec<N, f32>
-fn asinh(f32) -> f32
-fn asinh<N: num>(vec<N, f32>) -> vec<N, f32>
-fn atan(f32) -> f32
-fn atan<N: num>(vec<N, f32>) -> vec<N, f32>
-@const fn atan2<T: fa_f32>(T, T) -> T
-@const fn atan2<N: num, T: fa_f32>(vec<N, T>, vec<N, T>) -> vec<N, T>
-fn atanh(f32) -> f32
-fn atanh<N: num>(vec<N, f32>) -> vec<N, f32>
-fn ceil(f32) -> f32
-fn ceil<N: num>(vec<N, f32>) -> vec<N, f32>
-@const fn clamp<T: fia_fiu32>(T, T, T) -> T
-@const fn clamp<N: num, T: fia_fiu32>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
-fn cos(f32) -> f32
-fn cos<N: num>(vec<N, f32>) -> vec<N, f32>
-fn cosh(f32) -> f32
-fn cosh<N: num>(vec<N, f32>) -> vec<N, f32>
+fn asin<T: f32_f16>(T) -> T
+fn asin<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn asinh<T: f32_f16>(T) -> T
+fn asinh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn atan<T: f32_f16>(T) -> T
+fn atan<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn atan2<T: fa_f32_f16>(T, T) -> T
+@const fn atan2<T: fa_f32_f16, N: num>(vec<N, T>, vec<N, T>) -> vec<N, T>
+fn atanh<T: f32_f16>(T) -> T
+fn atanh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn ceil<T: f32_f16>(T) -> T
+fn ceil<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn clamp<T: fia_fiu32_f16>(T, T, T) -> T
+@const fn clamp<T: fia_fiu32_f16, N: num>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
+fn cos<T: f32_f16>(T) -> T
+fn cos<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn cosh<T: f32_f16>(T) -> T
+fn cosh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
 fn countLeadingZeros<T: iu32>(T) -> T
 fn countLeadingZeros<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
 fn countOneBits<T: iu32>(T) -> T
 fn countOneBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
 fn countTrailingZeros<T: iu32>(T) -> T
 fn countTrailingZeros<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
-fn cross(vec3<f32>, vec3<f32>) -> vec3<f32>
-fn degrees(f32) -> f32
-fn degrees<N: num>(vec<N, f32>) -> vec<N, f32>
-fn determinant<N: num>(mat<N, N, f32>) -> f32
-fn distance(f32, f32) -> f32
-fn distance<N: num>(vec<N, f32>, vec<N, f32>) -> f32
-fn dot<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> T
+fn cross<T: f32_f16>(vec3<T>, vec3<T>) -> vec3<T>
+fn degrees<T: f32_f16>(T) -> T
+fn degrees<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn determinant<N: num, T: f32_f16>(mat<N, N, T>) -> T
+fn distance<T: f32_f16>(T, T) -> T
+fn distance<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> T
+fn dot<N: num, T: fiu32_f16>(vec<N, T>, vec<N, T>) -> T
 fn dot4I8Packed(u32, u32) -> i32
 fn dot4U8Packed(u32, u32) -> u32
 @stage("fragment") fn dpdx(f32) -> f32
@@ -442,23 +443,23 @@
 @stage("fragment") fn dpdyCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
 @stage("fragment") fn dpdyFine(f32) -> f32
 @stage("fragment") fn dpdyFine<N: num>(vec<N, f32>) -> vec<N, f32>
-fn exp(f32) -> f32
-fn exp<N: num>(vec<N, f32>) -> vec<N, f32>
-fn exp2(f32) -> f32
-fn exp2<N: num>(vec<N, f32>) -> vec<N, f32>
+fn exp<T: f32_f16>(T) -> T
+fn exp<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn exp2<T: f32_f16>(T) -> T
+fn exp2<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
 fn extractBits<T: iu32>(T, u32, u32) -> T
 fn extractBits<N: num, T: iu32>(vec<N, T>, u32, u32) -> vec<N, T>
-fn faceForward<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
+fn faceForward<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
 fn firstLeadingBit<T: iu32>(T) -> T
 fn firstLeadingBit<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
 fn firstTrailingBit<T: iu32>(T) -> T
 fn firstTrailingBit<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
-fn floor(f32) -> f32
-fn floor<N: num>(vec<N, f32>) -> vec<N, f32>
-fn fma(f32, f32, f32) -> f32
-fn fma<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
-fn fract(f32) -> f32
-fn fract<N: num>(vec<N, f32>) -> vec<N, f32>
+fn floor<T: f32_f16>(T) -> T
+fn floor<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn fma<T: f32_f16>(T, T, T) -> T
+fn fma<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
+fn fract<T: f32_f16>(T) -> T
+fn fract<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
 fn frexp(f32) -> __frexp_result
 fn frexp<N: num>(vec<N, f32>) -> __frexp_result_vec<N>
 @stage("fragment") fn fwidth(f32) -> f32
@@ -469,64 +470,64 @@
 @stage("fragment") fn fwidthFine<N: num>(vec<N, f32>) -> vec<N, f32>
 fn insertBits<T: iu32>(T, T, u32, u32) -> T
 fn insertBits<N: num, T: iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T>
-fn inverseSqrt(f32) -> f32
-fn inverseSqrt<N: num>(vec<N, f32>) -> vec<N, f32>
-fn ldexp(f32, i32) -> f32
-fn ldexp<N: num>(vec<N, f32>, vec<N, i32>) -> vec<N, f32>
-fn length(f32) -> f32
-fn length<N: num>(vec<N, f32>) -> f32
-fn log(f32) -> f32
-fn log<N: num>(vec<N, f32>) -> vec<N, f32>
-fn log2(f32) -> f32
-fn log2<N: num>(vec<N, f32>) -> vec<N, f32>
-fn max<T: fiu32>(T, T) -> T
-fn max<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T>
-fn min<T: fiu32>(T, T) -> T
-fn min<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T>
-fn mix(f32, f32, f32) -> f32
-fn mix<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
-fn mix<N: num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32>
+fn inverseSqrt<T: f32_f16>(T) -> T
+fn inverseSqrt<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn ldexp<T: f32_f16>(T, i32) -> T
+fn ldexp<N: num, T: f32_f16>(vec<N, T>, vec<N, i32>) -> vec<N, T>
+fn length<T: f32_f16>(T) -> T
+fn length<N: num, T: f32_f16>(vec<N, T>) -> T
+fn log<T: f32_f16>(T) -> T
+fn log<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn log2<T: f32_f16>(T) -> T
+fn log2<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn max<T: fiu32_f16>(T, T) -> T
+fn max<N: num, T: fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
+fn min<T: fiu32_f16>(T, T) -> T
+fn min<N: num, T: fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
+fn mix<T: f32_f16>(T, T, T) -> T
+fn mix<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
+fn mix<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T>
 fn modf(f32) -> __modf_result
 fn modf<N: num>(vec<N, f32>) -> __modf_result_vec<N>
-fn normalize<N: num>(vec<N, f32>) -> vec<N, f32>
+fn normalize<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
 fn pack2x16float(vec2<f32>) -> u32
 fn pack2x16snorm(vec2<f32>) -> u32
 fn pack2x16unorm(vec2<f32>) -> u32
 fn pack4x8snorm(vec4<f32>) -> u32
 fn pack4x8unorm(vec4<f32>) -> u32
-fn pow(f32, f32) -> f32
-fn pow<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
-fn radians(f32) -> f32
-fn radians<N: num>(vec<N, f32>) -> vec<N, f32>
-fn reflect<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
-fn refract<N: num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32>
+fn pow<T: f32_f16>(T, T) -> T
+fn pow<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
+fn radians<T: f32_f16>(T) -> T
+fn radians<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn reflect<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
+fn refract<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T>
 fn reverseBits<T: iu32>(T) -> T
 fn reverseBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
-fn round(f32) -> f32
-fn round<N: num>(vec<N, f32>) -> vec<N, f32>
-fn select<T: scalar_no_f16>(T, T, bool) -> T
-fn select<T: scalar_no_f16, N: num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T>
-fn select<N: num, T: scalar_no_f16>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T>
-fn sign(f32) -> f32
-fn sign<N: num>(vec<N, f32>) -> vec<N, f32>
-fn sin(f32) -> f32
-fn sin<N: num>(vec<N, f32>) -> vec<N, f32>
-fn sinh(f32) -> f32
-fn sinh<N: num>(vec<N, f32>) -> vec<N, f32>
-fn smoothstep(f32, f32, f32) -> f32
-fn smoothstep<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
-fn sqrt(f32) -> f32
-fn sqrt<N: num>(vec<N, f32>) -> vec<N, f32>
-fn step(f32, f32) -> f32
-fn step<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
+fn round<T: f32_f16>(T) -> T
+fn round<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn select<T: scalar>(T, T, bool) -> T
+fn select<T: scalar, N: num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T>
+fn select<N: num, T: scalar>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T>
+fn sign<T: f32_f16>(T) -> T
+fn sign<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn sin<T: f32_f16>(T) -> T
+fn sin<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn sinh<T: f32_f16>(T) -> T
+fn sinh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn smoothstep<T: f32_f16>(T, T, T) -> T
+fn smoothstep<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
+fn sqrt<T: f32_f16>(T) -> T
+fn sqrt<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn step<T: f32_f16>(T, T) -> T
+fn step<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
 @stage("compute") fn storageBarrier()
-fn tan(f32) -> f32
-fn tan<N: num>(vec<N, f32>) -> vec<N, f32>
-fn tanh(f32) -> f32
-fn tanh<N: num>(vec<N, f32>) -> vec<N, f32>
-fn transpose<M: num, N: num>(mat<M, N, f32>) -> mat<N, M, f32>
-fn trunc(f32) -> f32
-fn trunc<N: num>(vec<N, f32>) -> vec<N, f32>
+fn tan<T: f32_f16>(T) -> T
+fn tan<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn tanh<T: f32_f16>(T) -> T
+fn tanh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+fn transpose<M: num, N: num, T: f32_f16>(mat<M, N, T>) -> mat<N, M, T>
+fn trunc<T: f32_f16>(T) -> T
+fn trunc<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
 fn unpack2x16float(u32) -> vec2<f32>
 fn unpack2x16snorm(u32) -> vec2<f32>
 fn unpack2x16unorm(u32) -> vec2<f32>
diff --git a/src/tint/number.cc b/src/tint/number.cc
index 6371442..91dbb45 100644
--- a/src/tint/number.cc
+++ b/src/tint/number.cc
@@ -34,10 +34,10 @@
 }
 
 f16::type f16::Quantize(f16::type value) {
-    if (value > kHighest) {
+    if (value > kHighestValue) {
         return std::numeric_limits<f16::type>::infinity();
     }
-    if (value < kLowest) {
+    if (value < kLowestValue) {
         return -std::numeric_limits<f16::type>::infinity();
     }
     // Below value must be within the finite range of a f16.
@@ -82,17 +82,17 @@
     // 2. We can decide whether a given normal f32 number v is in the set R, by looking at its
     // mantissa bits and biased exponent `e`. Recall that biased exponent e is unbiased exponent +
     // 127, and in the range of 1 to 254 for normal f32 number.
-    //   2.1. If e >= 143, i.e. abs(v) >= 2^16 > f16::kHighest = 0x1.ffcp15, v is larger than any
-    //   finite f16 value and can not be in set R.
-    //   2.2. If 142 >= e >= 113, or f16::kHighest >= abs(v) >= f16::kSmallest = 2^-14, v falls in
-    //   the range of normal f16 values. In this case, v is in the set R iff the lowest 13 mantissa
-    //   bits are all 0. (See below for proof)
+    //   2.1. If e >= 143, i.e. abs(v) >= 2^16 > f16::kHighestValue = 0x1.ffcp15, v is larger than
+    //   any finite f16 value and can not be in set R. 2.2. If 142 >= e >= 113, or
+    //   f16::kHighestValue >= abs(v) >= f16::kSmallestValue = 2^-14, v falls in the range of normal
+    //   f16 values. In this case, v is in the set R iff the lowest 13 mantissa bits are all 0. (See
+    //   below for proof)
     //     2.2.1. If we let v' be v with lowest 13 mantissa bits masked to 0, v' will be in set R
     //     and the largest one in set R that no larger than v. Such v' is the quantized value of v.
-    //   2.3. If 112 >= e >= 103, i.e. 2^-14 > abs(v) >= f16::kSmallestSubnormal = 2^-24, v falls in
-    //   the range of subnormal f16 values. In this case, v is in the set R iff the lowest 126-e
-    //   mantissa bits are all 0. Notice that 126-e is in range 14 to 23, inclusive. (See below for
-    //   proof)
+    //   2.3. If 112 >= e >= 103, i.e. 2^-14 > abs(v) >= f16::kSmallestSubnormalValue = 2^-24, v
+    //   falls in the range of subnormal f16 values. In this case, v is in the set R iff the lowest
+    //   126-e mantissa bits are all 0. Notice that 126-e is in range 14 to 23, inclusive. (See
+    //   below for proof)
     //     2.3.1. If we let v' be v with lowest 126-e mantissa bits masked to 0, v' will be in set R
     //     and the largest on in set R that no larger than v. Such v' is the quantized value of v.
     //   2.4. If 2^-24 > abs(v) > 0, i.e. 103 > e, v is smaller than any finite f16 value and not
@@ -174,17 +174,17 @@
     // in range [103, 112], or unbiased exponent in [-24, -15].
 
     float abs_value = std::fabs(value);
-    if (abs_value >= kSmallest) {
+    if (abs_value >= kSmallestValue) {
         // Value falls in the normal f16 range, quantize it to a normal f16 value by masking out
         // lowest 13 mantissa bits.
         u32 = u32 & ~((1u << 13) - 1);
-    } else if (abs_value >= kSmallestSubnormal) {
+    } else if (abs_value >= kSmallestSubnormalValue) {
         // Value should be quantized to a subnormal f16 value.
 
         // Get the biased exponent `e` of f32 value, e.g. value 127 representing exponent 2^0.
         uint32_t biased_exponent_original = (u32 & exponent_mask) >> 23;
-        // Since we ensure that kSmallest = 0x1f-14 > abs(value) >= kSmallestSubnormal = 0x1f-24,
-        // value will have a unbiased exponent in range -24 to -15 (inclusive), and the
+        // Since we ensure that kSmallestValue = 0x1f-14 > abs(value) >= kSmallestSubnormalValue =
+        // 0x1f-24, value will have a unbiased exponent in range -24 to -15 (inclusive), and the
         // corresponding biased exponent in f32 is in range 103 to 112 (inclusive).
         TINT_ASSERT(Semantic,
                     (103 <= biased_exponent_original) && (biased_exponent_original <= 112));
diff --git a/src/tint/number.h b/src/tint/number.h
index 32cca59..13ba76c 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -68,26 +68,47 @@
 template <typename T>
 constexpr bool IsNumeric = IsInteger<T> || IsFloatingPoint<T>;
 
+/// Resolves to the underlying type for a Number.
+template <typename T>
+using UnwrapNumber = typename detail::NumberUnwrapper<T>::type;
+
+/// NumberBase is a CRTP base class for Number<T>
+template <typename NumberT>
+struct NumberBase {
+    /// @returns value of type `Number<T>` with the highest value for that type.
+    static NumberT Highest() { return NumberT(NumberT::kHighestValue); }
+    /// @returns value of type `Number<T>` with the lowest value for that type.
+    static NumberT Lowest() { return NumberT(NumberT::kLowestValue); }
+    /// @returns value of type `Number<T>` with the smallest value for that type.
+    static NumberT Smallest() { return NumberT(NumberT::kSmallestValue); }
+    /// @returns value of type `Number<T>` that represents NaN for that type.
+    static NumberT NaN() {
+        return NumberT(std::numeric_limits<UnwrapNumber<NumberT>>::quiet_NaN());
+    }
+    /// @returns value of type `Number<T>` that represents infinity for that type.
+    static NumberT Inf() { return NumberT(std::numeric_limits<UnwrapNumber<NumberT>>::infinity()); }
+};
+
 /// Number wraps a integer or floating point number, enforcing explicit casting.
 template <typename T>
-struct Number {
+struct Number : NumberBase<Number<T>> {
     static_assert(IsNumeric<T>, "Number<T> constructed with non-numeric type");
 
     /// type is the underlying type of the Number
     using type = T;
 
     /// Highest finite representable value of this type.
-    static constexpr type kHighest = std::numeric_limits<type>::max();
+    static constexpr type kHighestValue = std::numeric_limits<type>::max();
 
     /// Lowest finite representable value of this type.
-    static constexpr type kLowest = std::numeric_limits<type>::lowest();
+    static constexpr type kLowestValue = std::numeric_limits<type>::lowest();
 
     /// Smallest positive normal value of this type.
-    static constexpr type kSmallest =
+    static constexpr type kSmallestValue =
         std::is_integral_v<type> ? 0 : std::numeric_limits<type>::min();
 
     /// Smallest positive subnormal value of this type, 0 for integral type.
-    static constexpr type kSmallestSubnormal =
+    static constexpr type kSmallestSubnormalValue =
         std::is_integral_v<type> ? 0 : std::numeric_limits<type>::denorm_min();
 
     /// Constructor. The value is zero-initialized.
@@ -123,10 +144,6 @@
     type value = {};
 };
 
-/// Resolves to the underlying type for a Number.
-template <typename T>
-using UnwrapNumber = typename detail::NumberUnwrapper<T>::type;
-
 /// Writes the number to the ostream.
 /// @param out the std::ostream to write to
 /// @param num the Number
@@ -139,23 +156,23 @@
 /// The partial specification of Number for f16 type, storing the f16 value as float,
 /// and enforcing proper explicit casting.
 template <>
-struct Number<detail::NumberKindF16> {
+struct Number<detail::NumberKindF16> : NumberBase<Number<detail::NumberKindF16>> {
     /// C++ does not have a native float16 type, so we use a 32-bit float instead.
     using type = float;
 
     /// Highest finite representable value of this type.
-    static constexpr type kHighest = 65504.0f;  // 2¹⁵ × (1 + 1023/1024)
+    static constexpr type kHighestValue = 65504.0f;  // 2¹⁵ × (1 + 1023/1024)
 
     /// Lowest finite representable value of this type.
-    static constexpr type kLowest = -65504.0f;
+    static constexpr type kLowestValue = -65504.0f;
 
     /// Smallest positive normal value of this type.
     /// binary16 0_00001_0000000000, value is 2⁻¹⁴.
-    static constexpr type kSmallest = 0x1p-14f;
+    static constexpr type kSmallestValue = 0x1p-14f;
 
     /// Smallest positive subnormal value of this type.
     /// binary16 0_00000_0000000001, value is 2⁻¹⁴ * 2⁻¹⁰ = 2⁻²⁴.
-    static constexpr type kSmallestSubnormal = 0x1p-24f;
+    static constexpr type kSmallestSubnormalValue = 0x1p-24f;
 
     /// Constructor. The value is zero-initialized.
     Number() = default;
@@ -239,10 +256,10 @@
     using T = std::conditional_t<IsFloatingPoint<UnwrapNumber<TO>> || IsFloatingPoint<FROM>,
                                  AFloat::type, AInt::type>;
     const auto value = static_cast<T>(num.value);
-    if (value > static_cast<T>(TO::kHighest)) {
+    if (value > static_cast<T>(TO::kHighestValue)) {
         return ConversionFailure::kExceedsPositiveLimit;
     }
-    if (value < static_cast<T>(TO::kLowest)) {
+    if (value < static_cast<T>(TO::kLowestValue)) {
         return ConversionFailure::kExceedsNegativeLimit;
     }
     return TO(value);  // Success
@@ -333,11 +350,11 @@
     }
 #else   // TINT_HAS_OVERFLOW_BUILTINS
     if (a.value >= 0) {
-        if (AInt::kHighest - a.value < b.value) {
+        if (AInt::kHighestValue - a.value < b.value) {
             return {};
         }
     } else {
-        if (b.value < AInt::kLowest - a.value) {
+        if (b.value < AInt::kLowestValue - a.value) {
             return {};
         }
     }
@@ -356,21 +373,21 @@
 #else   // TINT_HAS_OVERFLOW_BUILTINS
     if (a > 0) {
         if (b > 0) {
-            if (a > (AInt::kHighest / b)) {
+            if (a > (AInt::kHighestValue / b)) {
                 return {};
             }
         } else {
-            if (b < (AInt::kLowest / a)) {
+            if (b < (AInt::kLowestValue / a)) {
                 return {};
             }
         }
     } else {
         if (b > 0) {
-            if (a < (AInt::kLowest / b)) {
+            if (a < (AInt::kLowestValue / b)) {
                 return {};
             }
         } else {
-            if ((a != 0) && (b < (AInt::kHighest / a))) {
+            if ((a != 0) && (b < (AInt::kHighestValue / a))) {
                 return {};
             }
         }
diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc
index eeb31ed..16925ed 100644
--- a/src/tint/number_test.cc
+++ b/src/tint/number_test.cc
@@ -26,38 +26,19 @@
 namespace tint {
 namespace {
 
-constexpr int64_t kHighestI32 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
-constexpr int64_t kHighestU32 = static_cast<int64_t>(std::numeric_limits<uint32_t>::max());
-constexpr int64_t kLowestI32 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
-constexpr int64_t kLowestU32 = static_cast<int64_t>(std::numeric_limits<uint32_t>::min());
-
-// Highest float32 value.
-constexpr double kHighestF32 = 0x1.fffffep+127;
-
 // Next ULP up from kHighestF32 for a float64.
 constexpr double kHighestF32NextULP = 0x1.fffffe0000001p+127;
 
-// Smallest positive normal float32 value.
-constexpr double kSmallestF32 = 0x1p-126;
-
 // Highest subnormal value for a float32.
 constexpr double kHighestF32Subnormal = 0x0.fffffep-126;
 
-// Highest float16 value.
-constexpr double kHighestF16 = 0x1.ffcp+15;
-
 // Next ULP up from kHighestF16 for a float64.
 constexpr double kHighestF16NextULP = 0x1.ffc0000000001p+15;
 
-// Smallest positive normal float16 value.
-constexpr double kSmallestF16 = 0x1p-14;
-
 // Highest subnormal value for a float16.
 constexpr double kHighestF16Subnormal = 0x0.ffcp-14;
 
-constexpr double kLowestF32 = -kHighestF32;
 constexpr double kLowestF32NextULP = -kHighestF32NextULP;
-constexpr double kLowestF16 = -kHighestF16;
 constexpr double kLowestF16NextULP = -kHighestF16NextULP;
 
 // MSVC (only in release builds) can grumble about some of the inlined numerical overflow /
@@ -155,38 +136,38 @@
 }
 
 TEST(NumberTest, CheckedConvertLargestValue) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kHighestI32)), i32(kHighestI32));
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kHighestU32)), u32(kHighestU32));
-    EXPECT_EQ(CheckedConvert<u32>(i32(kHighestI32)), u32(kHighestI32));
-    EXPECT_EQ(CheckedConvert<f32>(AFloat(kHighestF32)), f32(kHighestF32));
-    EXPECT_EQ(CheckedConvert<f16>(AFloat(kHighestF16)), f16(kHighestF16));
+    EXPECT_EQ(CheckedConvert<i32>(AInt(i32::Highest())), i32::Highest());
+    EXPECT_EQ(CheckedConvert<u32>(AInt(u32::Highest())), u32::Highest());
+    EXPECT_EQ(CheckedConvert<u32>(i32::Highest()), u32(i32::Highest()));
+    EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Highest())), f32::Highest());
+    EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Highest())), f16::Highest());
 }
 
 TEST(NumberTest, CheckedConvertLowestValue) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kLowestI32)), i32(kLowestI32));
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kLowestU32)), u32(kLowestU32));
-    EXPECT_EQ(CheckedConvert<f32>(AFloat(kLowestF32)), f32(kLowestF32));
-    EXPECT_EQ(CheckedConvert<f16>(AFloat(kLowestF16)), f16(kLowestF16));
+    EXPECT_EQ(CheckedConvert<i32>(AInt(i32::Lowest())), i32::Lowest());
+    EXPECT_EQ(CheckedConvert<u32>(AInt(u32::Lowest())), u32::Lowest());
+    EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Lowest())), f32::Lowest());
+    EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Lowest())), f16::Lowest());
 }
 
 TEST(NumberTest, CheckedConvertSmallestValue) {
     EXPECT_EQ(CheckedConvert<i32>(AInt(0)), i32(0));
     EXPECT_EQ(CheckedConvert<u32>(AInt(0)), u32(0));
-    EXPECT_EQ(CheckedConvert<f32>(AFloat(kSmallestF32)), f32(kSmallestF32));
-    EXPECT_EQ(CheckedConvert<f16>(AFloat(kSmallestF16)), f16(kSmallestF16));
+    EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Smallest())), f32::Smallest());
+    EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Smallest())), f16::Smallest());
 }
 
 TEST(NumberTest, CheckedConvertExceedsPositiveLimit) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kHighestI32 + 1)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kHighestU32 + 1)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<i32>(u32(kHighestU32)), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AInt(static_cast<int64_t>(i32::Highest()) + 1)),
+              ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AInt(static_cast<uint64_t>(u32::Highest()) + 1)),
+              ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(u32::Highest()), ConversionFailure::kExceedsPositiveLimit);
     EXPECT_EQ(CheckedConvert<i32>(u32(0x80000000)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<u32>(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<i32>(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AFloat(AFloat::kHighest)),
-              ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<i32>(AFloat(AFloat::kHighest)),
-              ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<u32>(f32::Highest()), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(f32::Highest()), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AFloat::Highest()), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AFloat::Highest()), ConversionFailure::kExceedsPositiveLimit);
     EXPECT_EQ(CheckedConvert<f32>(AFloat(kHighestF32NextULP)),
               ConversionFailure::kExceedsPositiveLimit);
     EXPECT_EQ(CheckedConvert<f16>(AFloat(kHighestF16NextULP)),
@@ -194,16 +175,16 @@
 }
 
 TEST(NumberTest, CheckedConvertExceedsNegativeLimit) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kLowestI32 - 1)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kLowestU32 - 1)), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AInt(static_cast<int64_t>(i32::Lowest()) - 1)),
+              ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AInt(static_cast<uint64_t>(u32::Lowest()) - 1)),
+              ConversionFailure::kExceedsNegativeLimit);
     EXPECT_EQ(CheckedConvert<u32>(i32(-1)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(i32(kLowestI32)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<i32>(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AFloat(AFloat::kLowest)),
-              ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<i32>(AFloat(AFloat::kLowest)),
-              ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(i32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(f32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<i32>(f32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AFloat::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AFloat::Lowest()), ConversionFailure::kExceedsNegativeLimit);
     EXPECT_EQ(CheckedConvert<f32>(AFloat(kLowestF32NextULP)),
               ConversionFailure::kExceedsNegativeLimit);
     EXPECT_EQ(CheckedConvert<f16>(AFloat(kLowestF16NextULP)),
@@ -401,19 +382,19 @@
         {AInt(-1), AInt(-2), AInt(1)},
         {AInt(0x300), AInt(0x100), AInt(0x200)},
         {AInt(0x100), AInt(-0x100), AInt(0x200)},
-        {AInt(AInt::kHighest), AInt(1), AInt(AInt::kHighest - 1)},
-        {AInt(AInt::kLowest), AInt(-1), AInt(AInt::kLowest + 1)},
-        {AInt(AInt::kHighest), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
-        {AInt(AInt::kHighest), AInt(AInt::kHighest), AInt(0)},
-        {AInt(AInt::kLowest), AInt(AInt::kLowest), AInt(0)},
-        {OVERFLOW, AInt(1), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(-1), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(2), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(-2), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(10000), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(-10000), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(AInt::kLowest), AInt(AInt::kLowest)},
+        {AInt::Highest(), AInt(1), AInt(AInt::kHighestValue - 1)},
+        {AInt::Lowest(), AInt(-1), AInt(AInt::kLowestValue + 1)},
+        {AInt::Highest(), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
+        {AInt::Highest(), AInt::Highest(), AInt(0)},
+        {AInt::Lowest(), AInt::Lowest(), AInt(0)},
+        {OVERFLOW, AInt(1), AInt::Highest()},
+        {OVERFLOW, AInt(-1), AInt::Lowest()},
+        {OVERFLOW, AInt(2), AInt::Highest()},
+        {OVERFLOW, AInt(-2), AInt::Lowest()},
+        {OVERFLOW, AInt(10000), AInt::Highest()},
+        {OVERFLOW, AInt(-10000), AInt::Lowest()},
+        {OVERFLOW, AInt::Highest(), AInt::Highest()},
+        {OVERFLOW, AInt::Lowest(), AInt::Lowest()},
         ////////////////////////////////////////////////////////////////////////
     }));
 
@@ -452,14 +433,14 @@
         {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4)},
         {AInt(-0x8000000000000000ll), AInt(0x1000000000000000ll), AInt(-8)},
         {AInt(-0x8000000000000000ll), AInt(-0x1000000000000000ll), AInt(8)},
-        {AInt(0), AInt(AInt::kHighest), AInt(0)},
-        {AInt(0), AInt(AInt::kLowest), AInt(0)},
+        {AInt(0), AInt::Highest(), AInt(0)},
+        {AInt(0), AInt::Lowest(), AInt(0)},
         {OVERFLOW, AInt(0x1000000000000000ll), AInt(8)},
         {OVERFLOW, AInt(-0x1000000000000000ll), AInt(-8)},
         {OVERFLOW, AInt(0x800000000000000ll), AInt(0x10)},
         {OVERFLOW, AInt(0x80000000ll), AInt(0x100000000ll)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kLowest)},
+        {OVERFLOW, AInt::Highest(), AInt::Highest()},
+        {OVERFLOW, AInt::Highest(), AInt::Lowest()},
         ////////////////////////////////////////////////////////////////////////
     }));
 
@@ -489,8 +470,8 @@
         {AInt(-1), AInt(-1), AInt(1), AInt(0)},
         {AInt(2), AInt(2), AInt(1), AInt(0)},
         {AInt(-2), AInt(-2), AInt(1), AInt(0)},
-        {AInt(0), AInt(AInt::kHighest), AInt(0), AInt(0)},
-        {AInt(0), AInt(AInt::kLowest), AInt(0), AInt(0)},
+        {AInt(0), AInt::Highest(), AInt(0), AInt(0)},
+        {AInt(0), AInt::Lowest(), AInt(0), AInt(0)},
         {AInt(3), AInt(1), AInt(2), AInt(1)},
         {AInt(0x300), AInt(1), AInt(0x100), AInt(0x200)},
         {AInt(0x100), AInt(1), AInt(-0x100), AInt(0x200)},
@@ -511,27 +492,27 @@
         {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4), AInt(0)},
         {AInt(-0x8000000000000000ll), AInt(0x1000000000000000ll), AInt(-8), AInt(0)},
         {AInt(-0x8000000000000000ll), AInt(-0x1000000000000000ll), AInt(8), AInt(0)},
-        {AInt(AInt::kHighest), AInt(1), AInt(1), AInt(AInt::kHighest - 1)},
-        {AInt(AInt::kLowest), AInt(1), AInt(-1), AInt(AInt::kLowest + 1)},
-        {AInt(AInt::kHighest), AInt(1), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
-        {AInt(AInt::kHighest), AInt(1), AInt(AInt::kHighest), AInt(0)},
-        {AInt(AInt::kLowest), AInt(1), AInt(AInt::kLowest), AInt(0)},
+        {AInt::Highest(), AInt(1), AInt(1), AInt(AInt::kHighestValue - 1)},
+        {AInt::Lowest(), AInt(1), AInt(-1), AInt(AInt::kLowestValue + 1)},
+        {AInt::Highest(), AInt(1), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
+        {AInt::Highest(), AInt(1), AInt::Highest(), AInt(0)},
+        {AInt::Lowest(), AInt(1), AInt::Lowest(), AInt(0)},
         {OVERFLOW, AInt(0x1000000000000000ll), AInt(8), AInt(0)},
         {OVERFLOW, AInt(-0x1000000000000000ll), AInt(-8), AInt(0)},
         {OVERFLOW, AInt(0x800000000000000ll), AInt(0x10), AInt(0)},
         {OVERFLOW, AInt(0x80000000ll), AInt(0x100000000ll), AInt(0)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest), AInt(0)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kLowest), AInt(0)},
-        {OVERFLOW, AInt(1), AInt(1), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(-1), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(2), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(-2), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(10000), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(-10000), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(AInt::kHighest), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(AInt::kLowest), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(AInt::kHighest), AInt(1)},
-        {OVERFLOW, AInt(1), AInt(AInt::kLowest), AInt(-1)},
+        {OVERFLOW, AInt::Highest(), AInt::Highest(), AInt(0)},
+        {OVERFLOW, AInt::Highest(), AInt::Lowest(), AInt(0)},
+        {OVERFLOW, AInt(1), AInt(1), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt(-1), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt(2), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt(-2), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt(10000), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt(-10000), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt::Highest(), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt::Lowest(), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt::Highest(), AInt(1)},
+        {OVERFLOW, AInt(1), AInt::Lowest(), AInt(-1)},
     }));
 
 TINT_END_DISABLE_WARNING(CONSTANT_OVERFLOW);
diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc
index c9056e0..778cb3f 100644
--- a/src/tint/reader/wgsl/lexer.cc
+++ b/src/tint/reader/wgsl/lexer.cc
@@ -706,8 +706,8 @@
 
     if (has_f_suffix) {
         // Check value fits in f32
-        if (result_f64 < static_cast<double>(f32::kLowest) ||
-            result_f64 > static_cast<double>(f32::kHighest)) {
+        if (result_f64 < static_cast<double>(f32::kLowestValue) ||
+            result_f64 > static_cast<double>(f32::kHighestValue)) {
             return {Token::Type::kError, source, "value cannot be represented as 'f32'"};
         }
         // Check the value can be exactly represented, i.e. only high 23 mantissa bits are valid for
@@ -715,13 +715,14 @@
         // 0.
         int valid_mantissa_bits = 0;
         double abs_result_f64 = std::fabs(result_f64);
-        if (abs_result_f64 >= static_cast<double>(f32::kSmallest)) {
+        if (abs_result_f64 >= static_cast<double>(f32::kSmallestValue)) {
             // The result shall be a normal f32 value.
             valid_mantissa_bits = 23;
-        } else if (abs_result_f64 >= static_cast<double>(f32::kSmallestSubnormal)) {
+        } else if (abs_result_f64 >= static_cast<double>(f32::kSmallestSubnormalValue)) {
             // The result shall be a subnormal f32 value, represented as double.
-            // The smallest positive normal f32 is f32::kSmallest = 2^-126 = 0x1.0p-126, and the
-            //   smallest positive subnormal f32 is f32::kSmallestSubnormal = 2^-149. Thus, the
+            // The smallest positive normal f32 is f32::kSmallestValue = 2^-126 = 0x1.0p-126, and
+            // the
+            //   smallest positive subnormal f32 is f32::kSmallestSubnormalValue = 2^-149. Thus, the
             //   value v in range 2^-126 > v >= 2^-149 must be represented as a subnormal f32
             //   number, but is still normal double (f64) number, and has a exponent in range -127
             //   to -149, inclusive.
@@ -758,8 +759,8 @@
         return {Token::Type::kFloatLiteral_F, source, result_f64};
     } else if (has_h_suffix) {
         // Check value fits in f16
-        if (result_f64 < static_cast<double>(f16::kLowest) ||
-            result_f64 > static_cast<double>(f16::kHighest)) {
+        if (result_f64 < static_cast<double>(f16::kLowestValue) ||
+            result_f64 > static_cast<double>(f16::kHighestValue)) {
             return {Token::Type::kError, source, "value cannot be represented as 'f16'"};
         }
         // Check the value can be exactly represented, i.e. only high 10 mantissa bits are valid for
@@ -767,15 +768,15 @@
         // 0.
         int valid_mantissa_bits = 0;
         double abs_result_f64 = std::fabs(result_f64);
-        if (abs_result_f64 >= static_cast<double>(f16::kSmallest)) {
+        if (abs_result_f64 >= static_cast<double>(f16::kSmallestValue)) {
             // The result shall be a normal f16 value.
             valid_mantissa_bits = 10;
-        } else if (abs_result_f64 >= static_cast<double>(f16::kSmallestSubnormal)) {
+        } else if (abs_result_f64 >= static_cast<double>(f16::kSmallestSubnormalValue)) {
             // The result shall be a subnormal f16 value, represented as double.
-            // The smallest positive normal f16 is f16::kSmallest = 2^-14 = 0x1.0p-14, and the
-            //   smallest positive subnormal f16 is f16::kSmallestSubnormal = 2^-24. Thus, the value
-            //   v in range 2^-14 > v >= 2^-24 must be represented as a subnormal f16 number, but
-            //   is still normal double (f64) number, and has a exponent in range -15 to -24,
+            // The smallest positive normal f16 is f16::kSmallestValue = 2^-14 = 0x1.0p-14, and the
+            //   smallest positive subnormal f16 is f16::kSmallestSubnormalValue = 2^-24. Thus, the
+            //   value v in range 2^-14 > v >= 2^-24 must be represented as a subnormal f16 number,
+            //   but is still normal double (f64) number, and has a exponent in range -15 to -24,
             //   inclusive.
             // A value v, if 2^-14 > v >= 2^-15, its binary16 representation will have binary form
             //   s_00000_1xxxxxxxxx, having mantissa of 1 leading 1 bit and 9 arbitrary bits. Since
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index eaaa9c2..7bb7eb2 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -129,9 +129,9 @@
               R"(error: no matching call to select()
 
 3 candidate functions:
-  select(T, T, bool) -> T  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, i32, u32 or bool
+  select(T, T, bool) -> T  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
 )");
 }
 
@@ -145,9 +145,9 @@
               R"(error: no matching call to select(i32, i32, i32)
 
 3 candidate functions:
-  select(T, T, bool) -> T  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, i32, u32 or bool
+  select(T, T, bool) -> T  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
 )");
 }
 
@@ -162,9 +162,9 @@
               R"(error: no matching call to select(mat2x2<f32>, mat2x2<f32>, bool)
 
 3 candidate functions:
-  select(T, T, bool) -> T  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, i32, u32 or bool
+  select(T, T, bool) -> T  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
 )");
 }
 
@@ -178,9 +178,9 @@
               R"(error: no matching call to select(f32, vec2<f32>, bool)
 
 3 candidate functions:
-  select(T, T, bool) -> T  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, i32, u32 or bool
+  select(T, T, bool) -> T  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
 )");
 }
 
@@ -194,9 +194,9 @@
               R"(error: no matching call to select(vec2<f32>, vec3<f32>, bool)
 
 3 candidate functions:
-  select(T, T, bool) -> T  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, i32, u32 or bool
-  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, i32, u32 or bool
+  select(T, T, bool) -> T  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, bool) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
+  select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T>  where: T is f32, f16, i32, u32 or bool
 )");
 }
 
@@ -458,6 +458,206 @@
     }
 }
 
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, OneParam_Scalar_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, 1_h);
+    WrapInFunction(call);
+
+    if (param.args_number == 1u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(),
+                    HasSubstr("error: no matching call to " + std::string(param.name) + "(f16)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, OneParam_Vector_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    if (param.args_number == 1u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->is_float_vector());
+        EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+        ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
+        EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
+                                            std::string(param.name) + "(vec3<f16>)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, TwoParams_Scalar_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, 1_h, 1_h);
+    WrapInFunction(call);
+
+    if (param.args_number == 2u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
+                                            std::string(param.name) + "(f16, f16)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, TwoParams_Vector_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    if (param.args_number == 2u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->is_float_vector());
+        EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+        ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
+        EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
+                                            std::string(param.name) + "(vec3<f16>, vec3<f16>)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Scalar_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, 1_h, 1_h, 1_h);
+    WrapInFunction(call);
+
+    if (param.args_number == 3u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
+                                            std::string(param.name) + "(f16, f16, f16)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Vector_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h),
+                      vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    if (param.args_number == 3u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->is_float_vector());
+        EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+        ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
+        EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(),
+                    HasSubstr("error: no matching call to " + std::string(param.name) +
+                              "(vec3<f16>, vec3<f16>, vec3<f16>)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, FourParams_Scalar_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, 1_h, 1_h, 1_h, 1_h);
+    WrapInFunction(call);
+
+    if (param.args_number == 4u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
+                                            std::string(param.name) + "(f16, f16, f16, f16)"));
+    }
+}
+
+TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, FourParams_Vector_f16) {
+    auto param = GetParam();
+
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h),
+                      vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    if (param.args_number == 4u) {
+        // Parameter count matched.
+        EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+        ASSERT_NE(TypeOf(call), nullptr);
+        EXPECT_TRUE(TypeOf(call)->is_float_vector());
+        EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+        ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
+        EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+    } else {
+        // Invalid parameter count.
+        EXPECT_FALSE(r()->Resolve());
+
+        EXPECT_THAT(r()->error(),
+                    HasSubstr("error: no matching call to " + std::string(param.name) +
+                              "(vec3<f16>, vec3<f16>, vec3<f16>, vec3<f16>)"));
+    }
+}
+
 INSTANTIATE_TEST_SUITE_P(
     ResolverTest,
     ResolverBuiltinTest_FloatBuiltin_IdenticalType,
@@ -526,6 +726,20 @@
     EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Cross_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("cross", vec3<f16>(1_h, 2_h, 3_h), vec3<f16>(1_h, 2_h, 3_h));
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->is_float_vector());
+    EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+    EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinFloatTest, Cross_Error_NoArgs) {
     auto* call = Call("cross");
     WrapInFunction(call);
@@ -535,7 +749,7 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to cross()
 
 1 candidate function:
-  cross(vec3<f32>, vec3<f32>) -> vec3<f32>
+  cross(vec3<T>, vec3<T>) -> vec3<T>  where: T is f32 or f16
 )");
 }
 
@@ -548,7 +762,7 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to cross(f32, f32)
 
 1 candidate function:
-  cross(vec3<f32>, vec3<f32>) -> vec3<f32>
+  cross(vec3<T>, vec3<T>) -> vec3<T>  where: T is f32 or f16
 )");
 }
 
@@ -562,7 +776,7 @@
               R"(error: no matching call to cross(vec3<i32>, vec3<i32>)
 
 1 candidate function:
-  cross(vec3<f32>, vec3<f32>) -> vec3<f32>
+  cross(vec3<T>, vec3<T>) -> vec3<T>  where: T is f32 or f16
 )");
 }
 
@@ -577,7 +791,7 @@
               R"(error: no matching call to cross(vec4<f32>, vec4<f32>)
 
 1 candidate function:
-  cross(vec3<f32>, vec3<f32>) -> vec3<f32>
+  cross(vec3<T>, vec3<T>) -> vec3<T>  where: T is f32 or f16
 )");
 }
 
@@ -593,7 +807,7 @@
               R"(error: no matching call to cross(vec3<f32>, vec3<f32>, vec3<f32>)
 
 1 candidate function:
-  cross(vec3<f32>, vec3<f32>) -> vec3<f32>
+  cross(vec3<T>, vec3<T>) -> vec3<T>  where: T is f32 or f16
 )");
 }
 
@@ -608,6 +822,18 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Distance_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("distance", 1_h, 1_h);
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinFloatTest, Distance_Vector_f32) {
     auto* call = Call("distance", vec3<f32>(1_f, 1_f, 3_f), vec3<f32>(1_f, 1_f, 3_f));
     WrapInFunction(call);
@@ -618,31 +844,44 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Distance_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("distance", vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinFloatTest, Distance_TooManyParams) {
-    auto* call = Call("distance", 1_f, 1_f, 3_f);
+    auto* call = Call("distance", vec3<f32>(1_f, 1_f, 3_f), vec3<f32>(1_f, 1_f, 3_f),
+                      vec3<f32>(1_f, 1_f, 3_f));
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
 
-    EXPECT_EQ(r()->error(), R"(error: no matching call to distance(f32, f32, f32)
+    EXPECT_EQ(r()->error(), R"(error: no matching call to distance(vec3<f32>, vec3<f32>, vec3<f32>)
 
 2 candidate functions:
-  distance(f32, f32) -> f32
-  distance(vecN<f32>, vecN<f32>) -> f32
+  distance(T, T) -> T  where: T is f32 or f16
+  distance(vecN<T>, vecN<T>) -> T  where: T is f32 or f16
 )");
 }
 
 TEST_F(ResolverBuiltinFloatTest, Distance_TooFewParams) {
-    auto* call = Call("distance", 1_f);
+    auto* call = Call("distance", vec3<f32>(1_f, 1_f, 3_f));
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
 
-    EXPECT_EQ(r()->error(), R"(error: no matching call to distance(f32)
+    EXPECT_EQ(r()->error(), R"(error: no matching call to distance(vec3<f32>)
 
 2 candidate functions:
-  distance(f32, f32) -> f32
-  distance(vecN<f32>, vecN<f32>) -> f32
+  distance(T, T) -> T  where: T is f32 or f16
+  distance(vecN<T>, vecN<T>) -> T  where: T is f32 or f16
 )");
 }
 
@@ -655,8 +894,8 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to distance()
 
 2 candidate functions:
-  distance(f32, f32) -> f32
-  distance(vecN<f32>, vecN<f32>) -> f32
+  distance(T, T) -> T  where: T is f32 or f16
+  distance(vecN<T>, vecN<T>) -> T  where: T is f32 or f16
 )");
 }
 
@@ -796,6 +1035,18 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Length_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("length", 1_h);
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinFloatTest, Length_FloatVector_f32) {
     auto* call = Call("length", vec3<f32>(1_f, 1_f, 3_f));
     WrapInFunction(call);
@@ -806,6 +1057,18 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Length_FloatVector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("length", vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinFloatTest, Length_NoParams) {
     auto* call = Call("length");
     WrapInFunction(call);
@@ -815,8 +1078,8 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to length()
 
 2 candidate functions:
-  length(f32) -> f32
-  length(vecN<f32>) -> f32
+  length(T) -> T  where: T is f32 or f16
+  length(vecN<T>) -> T  where: T is f32 or f16
 )");
 }
 
@@ -829,8 +1092,8 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to length(f32, f32)
 
 2 candidate functions:
-  length(f32) -> f32
-  length(vecN<f32>) -> f32
+  length(T) -> T  where: T is f32 or f16
+  length(vecN<T>) -> T  where: T is f32 or f16
 )");
 }
 
@@ -849,6 +1112,21 @@
     EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Mix_VectorScalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("mix", vec3<f16>(1_h, 1_h, 1_h), vec3<f16>(1_h, 1_h, 1_h), 4_h);
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->is_float_vector());
+    EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+    ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
+    EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+}
+
 // modf: (f32) -> __modf_result, (vecN<f32>) -> __modf_result_vecN
 TEST_F(ResolverBuiltinFloatTest, ModfScalar) {
     auto* call = Call("modf", 1_f);
@@ -987,6 +1265,20 @@
     EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinFloatTest, Normalize_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* call = Call("normalize", vec3<f16>(1_h, 1_h, 3_h));
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->is_float_vector());
+    EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
+    EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinFloatTest, Normalize_Error_NoParams) {
     auto* call = Call("normalize");
     WrapInFunction(call);
@@ -996,7 +1288,7 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to normalize()
 
 1 candidate function:
-  normalize(vecN<f32>) -> vecN<f32>
+  normalize(vecN<T>) -> vecN<T>  where: T is f32 or f16
 )");
 }
 
@@ -1436,6 +1728,20 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinTest, Determinant_2x2_f16) {
+    Enable(ast::Extension::kF16);
+
+    GlobalVar("var", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
+
+    auto* call = Call("determinant", "var");
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinTest, Determinant_3x3_f32) {
     GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
 
@@ -1448,6 +1754,20 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinTest, Determinant_3x3_f16) {
+    Enable(ast::Extension::kF16);
+
+    GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+
+    auto* call = Call("determinant", "var");
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinTest, Determinant_4x4_f32) {
     GlobalVar("var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
 
@@ -1460,6 +1780,20 @@
     EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinTest, Determinant_4x4_f16) {
+    Enable(ast::Extension::kF16);
+
+    GlobalVar("var", ty.mat4x4<f16>(), ast::StorageClass::kPrivate);
+
+    auto* call = Call("determinant", "var");
+    WrapInFunction(call);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(call), nullptr);
+    EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinTest, Determinant_NotSquare) {
     GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
 
@@ -1471,7 +1805,7 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to determinant(mat2x3<f32>)
 
 1 candidate function:
-  determinant(matNxN<f32>) -> f32
+  determinant(matNxN<T>) -> T  where: T is f32 or f16
 )");
 }
 
@@ -1486,7 +1820,7 @@
     EXPECT_EQ(r()->error(), R"(error: no matching call to determinant(f32)
 
 1 candidate function:
-  determinant(matNxN<f32>) -> f32
+  determinant(matNxN<T>) -> T  where: T is f32 or f16
 )");
 }
 
@@ -1507,6 +1841,20 @@
     EXPECT_TRUE(TypeOf(expr)->Is<sem::F32>());
 }
 
+TEST_F(ResolverBuiltinTest, Dot_Vec2_f16) {
+    Enable(ast::Extension::kF16);
+
+    GlobalVar("my_var", ty.vec2<f16>(), ast::StorageClass::kPrivate);
+
+    auto* expr = Call("dot", "my_var", "my_var");
+    WrapInFunction(expr);
+
+    EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+    ASSERT_NE(TypeOf(expr), nullptr);
+    EXPECT_TRUE(TypeOf(expr)->Is<sem::F16>());
+}
+
 TEST_F(ResolverBuiltinTest, Dot_Vec3_i32) {
     GlobalVar("my_var", ty.vec3<i32>(), ast::StorageClass::kPrivate);
 
@@ -1541,7 +1889,7 @@
               R"(error: no matching call to dot(f32, f32)
 
 1 candidate function:
-  dot(vecN<T>, vecN<T>) -> T  where: T is f32, i32 or u32
+  dot(vecN<T>, vecN<T>) -> T  where: T is f32, i32, u32 or f16
 )");
 }
 
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index c2c6313..dec4992 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -73,33 +73,32 @@
         [&](const sem::AbstractFloat*) { return f(cs->template As<AFloat>()...); },
         [&](const sem::F32*) { return f(cs->template As<f32>()...); },
         [&](const sem::I32*) { return f(cs->template As<i32>()...); },
-        [&](const sem::F16*) {
-            // TODO(crbug.com/tint/1502): Support const eval for f16
-            return nullptr;
-        });
+        [&](const sem::F16*) { return f(cs->template As<f16>()...); });
 }
 
 /// Helper that calls `f` passing in the value of all `cs`.
 /// Assumes all `cs` are of the same type.
 template <typename F, typename... CONSTANTS>
-auto Dispatch_fia_fiu32(F&& f, CONSTANTS&&... cs) {
+auto Dispatch_fia_fiu32_f16(F&& f, CONSTANTS&&... cs) {
     return Switch(
         First(cs...)->Type(),  //
         [&](const sem::AbstractInt*) { return f(cs->template As<AInt>()...); },
         [&](const sem::AbstractFloat*) { return f(cs->template As<AFloat>()...); },
         [&](const sem::F32*) { return f(cs->template As<f32>()...); },
         [&](const sem::I32*) { return f(cs->template As<i32>()...); },
-        [&](const sem::U32*) { return f(cs->template As<u32>()...); });
+        [&](const sem::U32*) { return f(cs->template As<u32>()...); },
+        [&](const sem::F16*) { return f(cs->template As<f16>()...); });
 }
 
 /// Helper that calls `f` passing in the value of all `cs`.
 /// Assumes all `cs` are of the same type.
 template <typename F, typename... CONSTANTS>
-auto Dispatch_fa_f32(F&& f, CONSTANTS&&... cs) {
+auto Dispatch_fa_f32_f16(F&& f, CONSTANTS&&... cs) {
     return Switch(
         First(cs...)->Type(),  //
         [&](const sem::AbstractFloat*) { return f(cs->template As<AFloat>()...); },
-        [&](const sem::F32*) { return f(cs->template As<f32>()...); });
+        [&](const sem::F32*) { return f(cs->template As<f32>()...); },
+        [&](const sem::F16*) { return f(cs->template As<f16>()...); });
 }
 
 /// ZeroTypeDispatch is a helper for calling the function `f`, passing a single zero-value argument
@@ -210,21 +209,20 @@
             } else if constexpr (IsFloatingPoint<UnwrapNumber<TO>>) {
                 // [x -> floating-point] - number not exactly representable
                 // https://www.w3.org/TR/WGSL/#floating-point-conversion
-                constexpr auto kInf = std::numeric_limits<double>::infinity();
                 switch (conv.Failure()) {
                     case ConversionFailure::kExceedsNegativeLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(-kInf));
+                        return builder.create<Element<TO>>(target_ty, -TO::Inf());
                     case ConversionFailure::kExceedsPositiveLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(kInf));
+                        return builder.create<Element<TO>>(target_ty, TO::Inf());
                 }
             } else {
                 // [x -> integer] - number not exactly representable
                 // https://www.w3.org/TR/WGSL/#floating-point-conversion
                 switch (conv.Failure()) {
                     case ConversionFailure::kExceedsNegativeLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(TO::kLowest));
+                        return builder.create<Element<TO>>(target_ty, TO::Lowest());
                     case ConversionFailure::kExceedsPositiveLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(TO::kHighest));
+                        return builder.create<Element<TO>>(target_ty, TO::Highest());
                 }
             }
             return nullptr;  // Expression is not constant.
@@ -362,7 +360,7 @@
             return nullptr;
         },
         [&](const sem::Struct* s) -> const Constant* {
-            std::unordered_map<sem::Type*, const Constant*> zero_by_type;
+            std::unordered_map<const sem::Type*, const Constant*> zero_by_type;
             utils::Vector<const sem::Constant*, 4> zeros;
             zeros.Reserve(s->Members().size());
             for (auto* member : s->Members()) {
@@ -730,7 +728,7 @@
         auto create = [&](auto i, auto j) {
             return CreateElement(builder, c0->Type(), decltype(i)(std::atan2(i.value, j.value)));
         };
-        return Dispatch_fa_f32(create, c0, c1);
+        return Dispatch_fa_f32_f16(create, c0, c1);
     };
     return TransformElements(builder, transform, args[0]->ConstantValue(),
                              args[1]->ConstantValue());
@@ -744,7 +742,7 @@
             return CreateElement(builder, c0->Type(),
                                  decltype(e)(std::min(std::max(e, low), high)));
         };
-        return Dispatch_fia_fiu32(create, c0, c1, c2);
+        return Dispatch_fia_fiu32_f16(create, c0, c1, c2);
     };
     return TransformElements(builder, transform, args[0]->ConstantValue(), args[1]->ConstantValue(),
                              args[2]->ConstantValue());
diff --git a/src/tint/resolver/const_eval_test.cc b/src/tint/resolver/const_eval_test.cc
index cd1855b..3a6c971 100644
--- a/src/tint/resolver/const_eval_test.cc
+++ b/src/tint/resolver/const_eval_test.cc
@@ -30,18 +30,6 @@
 namespace {
 
 template <typename T>
-const auto kHighest = T(T::kHighest);
-
-template <typename T>
-const auto kLowest = T(T::kLowest);
-
-template <typename T>
-const auto kNaN = T(std::numeric_limits<UnwrapNumber<T>>::quiet_NaN());
-
-template <typename T>
-const auto kInf = T(std::numeric_limits<UnwrapNumber<T>>::infinity());
-
-template <typename T>
 const auto kPi = T(UnwrapNumber<T>(3.14159265358979323846));
 
 template <typename T>
@@ -1336,17 +1324,17 @@
     EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), i32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), i32::Highest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), i32::kLowest);
+    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), i32::Lowest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), i32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), i32::Highest());
 }
 
 TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_u32) {
@@ -1369,17 +1357,17 @@
     EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), u32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), u32::Highest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), u32::kLowest);
+    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), u32::Lowest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), u32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), u32::Highest());
 }
 
 TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_f16) {
@@ -2994,7 +2982,8 @@
 };
 
 struct Case {
-    std::variant<Values<AInt>, Values<AFloat>, Values<u32>, Values<i32>, Values<f32>> values;
+    std::variant<Values<AInt>, Values<AFloat>, Values<u32>, Values<i32>, Values<f32>, Values<f16>>
+        values;
 };
 
 static std::ostream& operator<<(std::ostream& o, const Case& c) {
@@ -3070,37 +3059,46 @@
                                               C(-0_a, 0_a),
                                               C(1_a, -1_a),
                                               C(-1_a, 1_a),
-                                              C(kHighest<AInt>, -kHighest<AInt>),
-                                              C(-kHighest<AInt>, kHighest<AInt>),
-                                              C(kLowest<AInt>, Negate(kLowest<AInt>)),
-                                              C(Negate(kLowest<AInt>), kLowest<AInt>),
+                                              C(AInt::Highest(), -AInt::Highest()),
+                                              C(-AInt::Highest(), AInt::Highest()),
+                                              C(AInt::Lowest(), Negate(AInt::Lowest())),
+                                              C(Negate(AInt::Lowest()), AInt::Lowest()),
                                               // i32
                                               C(0_i, -0_i),
                                               C(-0_i, 0_i),
                                               C(1_i, -1_i),
                                               C(-1_i, 1_i),
-                                              C(kHighest<i32>, -kHighest<i32>),
-                                              C(-kHighest<i32>, kHighest<i32>),
-                                              C(kLowest<i32>, Negate(kLowest<i32>)),
-                                              C(Negate(kLowest<i32>), kLowest<i32>),
+                                              C(i32::Highest(), -i32::Highest()),
+                                              C(-i32::Highest(), i32::Highest()),
+                                              C(i32::Lowest(), Negate(i32::Lowest())),
+                                              C(Negate(i32::Lowest()), i32::Lowest()),
                                               // AFloat
                                               C(0.0_a, -0.0_a),
                                               C(-0.0_a, 0.0_a),
                                               C(1.0_a, -1.0_a),
                                               C(-1.0_a, 1.0_a),
-                                              C(kHighest<AFloat>, -kHighest<AFloat>),
-                                              C(-kHighest<AFloat>, kHighest<AFloat>),
-                                              C(kLowest<AFloat>, Negate(kLowest<AFloat>)),
-                                              C(Negate(kLowest<AFloat>), kLowest<AFloat>),
+                                              C(AFloat::Highest(), -AFloat::Highest()),
+                                              C(-AFloat::Highest(), AFloat::Highest()),
+                                              C(AFloat::Lowest(), Negate(AFloat::Lowest())),
+                                              C(Negate(AFloat::Lowest()), AFloat::Lowest()),
                                               // f32
                                               C(0.0_f, -0.0_f),
                                               C(-0.0_f, 0.0_f),
                                               C(1.0_f, -1.0_f),
                                               C(-1.0_f, 1.0_f),
-                                              C(kHighest<f32>, -kHighest<f32>),
-                                              C(-kHighest<f32>, kHighest<f32>),
-                                              C(kLowest<f32>, Negate(kLowest<f32>)),
-                                              C(Negate(kLowest<f32>), kLowest<f32>),
+                                              C(f32::Highest(), -f32::Highest()),
+                                              C(-f32::Highest(), f32::Highest()),
+                                              C(f32::Lowest(), Negate(f32::Lowest())),
+                                              C(Negate(f32::Lowest()), f32::Lowest()),
+                                              // f16
+                                              C(0.0_h, -0.0_h),
+                                              C(-0.0_h, 0.0_h),
+                                              C(1.0_h, -1.0_h),
+                                              C(-1.0_h, 1.0_h),
+                                              C(f16::Highest(), -f16::Highest()),
+                                              C(-f16::Highest(), f16::Highest()),
+                                              C(f16::Lowest(), Negate(f16::Lowest())),
+                                              C(Negate(f16::Lowest()), f16::Lowest()),
                                           })));
 
 // Make sure UBSan doesn't trip on C++'s undefined behaviour of negating the smallest negative
@@ -3212,33 +3210,33 @@
     if constexpr (!finite_only) {
         std::vector<Case> non_finite_cases = {
             // If y is +/-INF and x is finite, +/-PI/2 is returned
-            C({kInf<T>, T(0.0)}, kPiOver2<T>, true),
-            C({-kInf<T>, T(0.0)}, kPiOver2<T>, true),
+            C({T::Inf(), T(0.0)}, kPiOver2<T>, true),
+            C({-T::Inf(), T(0.0)}, kPiOver2<T>, true),
 
             // If y is +/-INF and x is -INF, +/-3PI/4 is returned
-            C({kInf<T>, -kInf<T>}, k3PiOver4<T>, true),
-            C({-kInf<T>, -kInf<T>}, k3PiOver4<T>, true),
+            C({T::Inf(), -T::Inf()}, k3PiOver4<T>, true),
+            C({-T::Inf(), -T::Inf()}, k3PiOver4<T>, true),
 
             // If y is +/-INF and x is +INF, +/-PI/4 is returned
-            C({kInf<T>, kInf<T>}, kPiOver4<T>, true),
-            C({-kInf<T>, kInf<T>}, kPiOver4<T>, true),
+            C({T::Inf(), T::Inf()}, kPiOver4<T>, true),
+            C({-T::Inf(), T::Inf()}, kPiOver4<T>, true),
 
             // If x is -INF and y is finite and positive, +PI is returned
-            C({T(0.0), -kInf<T>}, kPi<T>),
+            C({T(0.0), -T::Inf()}, kPi<T>),
 
             // If x is -INF and y is finite and negative, -PI is returned
-            C({-T(0.0), -kInf<T>}, -kPi<T>),
+            C({-T(0.0), -T::Inf()}, -kPi<T>),
 
             // If x is +INF and y is finite and positive, +0 is returned
-            C({T(0.0), kInf<T>}, T(0.0)),
+            C({T(0.0), T::Inf()}, T(0.0)),
 
             // If x is +INF and y is finite and negative, -0 is returned
-            C({-T(0.0), kInf<T>}, -T(0.0)),
+            C({-T(0.0), T::Inf()}, -T(0.0)),
 
             // If either x is NaN or y is NaN, NaN is returned
-            C({kNaN<T>, T(0.0)}, kNaN<T>),
-            C({T(0.0), kNaN<T>}, kNaN<T>),
-            C({kNaN<T>, kNaN<T>}, kNaN<T>),
+            C({T::NaN(), T(0.0)}, T::NaN()),
+            C({T(0.0), T::NaN()}, T::NaN()),
+            C({T::NaN(), T::NaN()}, T::NaN()),
         };
 
         cases = Concat(cases, non_finite_cases);
@@ -3252,20 +3250,21 @@
     ResolverConstEvalBuiltinTest,
     testing::Combine(testing::Values(sem::BuiltinType::kAtan2),
                      testing::ValuesIn(Concat(Atan2Cases<AFloat, true>(),  //
-                                              Atan2Cases<f32, false>()))));
+                                              Atan2Cases<f32, false>(),
+                                              Atan2Cases<f16, false>()))));
 
 template <typename T>
 std::vector<Case> ClampCases() {
     return {
         C({T(0), T(0), T(0)}, T(0)),
-        C({T(0), T(42), kHighest<T>}, T(42)),
-        C({kLowest<T>, T(0), T(42)}, T(0)),
-        C({T(0), kLowest<T>, kHighest<T>}, T(0)),
-        C({T(0), kHighest<T>, kLowest<T>}, kLowest<T>),
-        C({kHighest<T>, kHighest<T>, kHighest<T>}, kHighest<T>),
-        C({kLowest<T>, kLowest<T>, kLowest<T>}, kLowest<T>),
-        C({kHighest<T>, kLowest<T>, kHighest<T>}, kHighest<T>),
-        C({kLowest<T>, kLowest<T>, kHighest<T>}, kLowest<T>),
+        C({T(0), T(42), T::Highest()}, T(42)),
+        C({T::Lowest(), T(0), T(42)}, T(0)),
+        C({T(0), T::Lowest(), T::Highest()}, T(0)),
+        C({T(0), T::Highest(), T::Lowest()}, T::Lowest()),
+        C({T::Highest(), T::Highest(), T::Highest()}, T::Highest()),
+        C({T::Lowest(), T::Lowest(), T::Lowest()}, T::Lowest()),
+        C({T::Highest(), T::Lowest(), T::Highest()}, T::Highest()),
+        C({T::Lowest(), T::Lowest(), T::Highest()}, T::Lowest()),
     };
 }
 
@@ -3277,7 +3276,8 @@
                                               ClampCases<i32>(),
                                               ClampCases<u32>(),
                                               ClampCases<AFloat>(),
-                                              ClampCases<f32>()))));
+                                              ClampCases<f32>(),
+                                              ClampCases<f16>()))));
 
 }  // namespace builtin
 
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index 8e6d72d..bb5791f 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -131,7 +131,7 @@
         if (existing == ty) {
             return ty;
         }
-        ty = sem::Type::Common({existing, ty});
+        ty = sem::Type::Common(utils::Vector{existing, ty});
         if (ty) {
             res.first->second = ty;
         }
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index 76fa443..28bcc51 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -1814,6 +1814,52 @@
   return ss.str();
 }
 
+/// TypeMatcher for 'match fia_fiu32_f16'
+class FiaFiu32F16 : public TypeMatcher {
+ public:
+  /// Checks whether the given type matches the matcher rules, and returns the
+  /// expected, canonicalized type on success.
+  /// Match may define and refine the template types and numbers in state.
+  /// @param state the MatchState
+  /// @param type the type to match
+  /// @returns the canonicalized type on match, otherwise nullptr
+  const sem::Type* Match(MatchState& state,
+                         const sem::Type* type) const override;
+  /// @param state the MatchState
+  /// @return a string representation of the matcher.
+  std::string String(MatchState* state) const override;
+};
+
+const sem::Type* FiaFiu32F16::Match(MatchState& state, const sem::Type* ty) const {
+  if (match_fa(ty)) {
+    return build_fa(state);
+  }
+  if (match_ia(ty)) {
+    return build_ia(state);
+  }
+  if (match_i32(ty)) {
+    return build_i32(state);
+  }
+  if (match_u32(ty)) {
+    return build_u32(state);
+  }
+  if (match_f32(ty)) {
+    return build_f32(state);
+  }
+  if (match_f16(ty)) {
+    return build_f16(state);
+  }
+  return nullptr;
+}
+
+std::string FiaFiu32F16::String(MatchState*) const {
+  std::stringstream ss;
+  // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+  // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+  ss << Fa().String(nullptr) << ", " << Ia().String(nullptr) << ", " << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << F16().String(nullptr);
+  return ss.str();
+}
+
 /// TypeMatcher for 'match fia_fi32_f16'
 class FiaFi32F16 : public TypeMatcher {
  public:
@@ -2513,6 +2559,7 @@
   ScalarNoI32 ScalarNoI32_;
   ScalarNoU32 ScalarNoU32_;
   ScalarNoBool ScalarNoBool_;
+  FiaFiu32F16 FiaFiu32F16_;
   FiaFi32F16 FiaFi32F16_;
   FiaFiu32 FiaFiu32_;
   FaF32 FaF32_;
@@ -2540,7 +2587,7 @@
   ~Matchers();
 
   /// The template types, types, and type matchers
-  TypeMatcher const* const type[68] = {
+  TypeMatcher const* const type[69] = {
     /* [0] */ &template_type_0_,
     /* [1] */ &template_type_1_,
     /* [2] */ &Bool_,
@@ -2598,17 +2645,18 @@
     /* [54] */ &ScalarNoI32_,
     /* [55] */ &ScalarNoU32_,
     /* [56] */ &ScalarNoBool_,
-    /* [57] */ &FiaFi32F16_,
-    /* [58] */ &FiaFiu32_,
-    /* [59] */ &FaF32_,
-    /* [60] */ &FaF32F16_,
-    /* [61] */ &IaIu32_,
-    /* [62] */ &Fiu32F16_,
-    /* [63] */ &Fiu32_,
-    /* [64] */ &Fi32F16_,
-    /* [65] */ &Fi32_,
-    /* [66] */ &F32F16_,
-    /* [67] */ &Iu32_,
+    /* [57] */ &FiaFiu32F16_,
+    /* [58] */ &FiaFi32F16_,
+    /* [59] */ &FiaFiu32_,
+    /* [60] */ &FaF32_,
+    /* [61] */ &FaF32F16_,
+    /* [62] */ &IaIu32_,
+    /* [63] */ &Fiu32F16_,
+    /* [64] */ &Fiu32_,
+    /* [65] */ &Fi32F16_,
+    /* [66] */ &Fi32_,
+    /* [67] */ &F32F16_,
+    /* [68] */ &Iu32_,
   };
 
   /// The template numbers, and number matchers
@@ -2658,221 +2706,213 @@
   /* [24] */ 2,
   /* [25] */ 0,
   /* [26] */ 22,
-  /* [27] */ 1,
+  /* [27] */ 0,
   /* [28] */ 0,
-  /* [29] */ 7,
-  /* [30] */ 22,
+  /* [29] */ 0,
+  /* [30] */ 21,
   /* [31] */ 0,
-  /* [32] */ 1,
-  /* [33] */ 7,
-  /* [34] */ 22,
-  /* [35] */ 0,
-  /* [36] */ 0,
-  /* [37] */ 7,
-  /* [38] */ 21,
-  /* [39] */ 0,
+  /* [32] */ 0,
+  /* [33] */ 43,
+  /* [34] */ 5,
+  /* [35] */ 6,
+  /* [36] */ 42,
+  /* [37] */ 5,
+  /* [38] */ 6,
+  /* [39] */ 21,
   /* [40] */ 0,
-  /* [41] */ 21,
-  /* [42] */ 0,
-  /* [43] */ 7,
-  /* [44] */ 43,
-  /* [45] */ 5,
-  /* [46] */ 6,
-  /* [47] */ 42,
-  /* [48] */ 5,
-  /* [49] */ 6,
-  /* [50] */ 21,
-  /* [51] */ 0,
-  /* [52] */ 2,
-  /* [53] */ 41,
-  /* [54] */ 5,
-  /* [55] */ 6,
-  /* [56] */ 42,
-  /* [57] */ 0,
-  /* [58] */ 1,
-  /* [59] */ 40,
-  /* [60] */ 5,
-  /* [61] */ 6,
-  /* [62] */ 43,
-  /* [63] */ 4,
-  /* [64] */ 6,
-  /* [65] */ 42,
-  /* [66] */ 4,
-  /* [67] */ 6,
-  /* [68] */ 41,
-  /* [69] */ 4,
-  /* [70] */ 6,
-  /* [71] */ 40,
-  /* [72] */ 4,
-  /* [73] */ 6,
-  /* [74] */ 43,
-  /* [75] */ 3,
-  /* [76] */ 6,
-  /* [77] */ 21,
-  /* [78] */ 1,
+  /* [41] */ 2,
+  /* [42] */ 41,
+  /* [43] */ 5,
+  /* [44] */ 6,
+  /* [45] */ 42,
+  /* [46] */ 0,
+  /* [47] */ 1,
+  /* [48] */ 40,
+  /* [49] */ 5,
+  /* [50] */ 6,
+  /* [51] */ 43,
+  /* [52] */ 4,
+  /* [53] */ 6,
+  /* [54] */ 42,
+  /* [55] */ 4,
+  /* [56] */ 6,
+  /* [57] */ 41,
+  /* [58] */ 4,
+  /* [59] */ 6,
+  /* [60] */ 21,
+  /* [61] */ 0,
+  /* [62] */ 7,
+  /* [63] */ 40,
+  /* [64] */ 4,
+  /* [65] */ 6,
+  /* [66] */ 43,
+  /* [67] */ 3,
+  /* [68] */ 6,
+  /* [69] */ 21,
+  /* [70] */ 1,
+  /* [71] */ 0,
+  /* [72] */ 42,
+  /* [73] */ 3,
+  /* [74] */ 6,
+  /* [75] */ 41,
+  /* [76] */ 3,
+  /* [77] */ 6,
+  /* [78] */ 43,
   /* [79] */ 0,
-  /* [80] */ 42,
-  /* [81] */ 3,
-  /* [82] */ 6,
-  /* [83] */ 41,
-  /* [84] */ 3,
-  /* [85] */ 6,
-  /* [86] */ 43,
-  /* [87] */ 0,
-  /* [88] */ 1,
-  /* [89] */ 41,
-  /* [90] */ 0,
-  /* [91] */ 1,
-  /* [92] */ 40,
-  /* [93] */ 0,
-  /* [94] */ 1,
-  /* [95] */ 21,
-  /* [96] */ 0,
-  /* [97] */ 5,
-  /* [98] */ 21,
-  /* [99] */ 0,
-  /* [100] */ 6,
-  /* [101] */ 40,
-  /* [102] */ 3,
-  /* [103] */ 6,
-  /* [104] */ 17,
-  /* [105] */ 0,
-  /* [106] */ 10,
-  /* [107] */ 1,
+  /* [80] */ 1,
+  /* [81] */ 41,
+  /* [82] */ 0,
+  /* [83] */ 1,
+  /* [84] */ 40,
+  /* [85] */ 0,
+  /* [86] */ 1,
+  /* [87] */ 21,
+  /* [88] */ 0,
+  /* [89] */ 5,
+  /* [90] */ 21,
+  /* [91] */ 0,
+  /* [92] */ 6,
+  /* [93] */ 40,
+  /* [94] */ 3,
+  /* [95] */ 6,
+  /* [96] */ 17,
+  /* [97] */ 0,
+  /* [98] */ 10,
+  /* [99] */ 1,
+  /* [100] */ 10,
+  /* [101] */ 7,
+  /* [102] */ 10,
+  /* [103] */ 8,
+  /* [104] */ 10,
+  /* [105] */ 5,
+  /* [106] */ 9,
+  /* [107] */ 0,
   /* [108] */ 10,
-  /* [109] */ 7,
+  /* [109] */ 0,
   /* [110] */ 10,
-  /* [111] */ 8,
+  /* [111] */ 6,
   /* [112] */ 10,
-  /* [113] */ 5,
-  /* [114] */ 9,
+  /* [113] */ 2,
+  /* [114] */ 11,
   /* [115] */ 0,
-  /* [116] */ 10,
-  /* [117] */ 0,
-  /* [118] */ 10,
-  /* [119] */ 6,
-  /* [120] */ 10,
-  /* [121] */ 2,
-  /* [122] */ 11,
-  /* [123] */ 0,
+  /* [116] */ 9,
+  /* [117] */ 2,
+  /* [118] */ 9,
+  /* [119] */ 1,
+  /* [120] */ 11,
+  /* [121] */ 7,
+  /* [122] */ 9,
+  /* [123] */ 6,
   /* [124] */ 9,
-  /* [125] */ 2,
+  /* [125] */ 5,
   /* [126] */ 9,
-  /* [127] */ 1,
-  /* [128] */ 11,
+  /* [127] */ 8,
+  /* [128] */ 9,
   /* [129] */ 7,
-  /* [130] */ 9,
-  /* [131] */ 6,
-  /* [132] */ 9,
-  /* [133] */ 5,
-  /* [134] */ 9,
-  /* [135] */ 8,
-  /* [136] */ 9,
-  /* [137] */ 7,
-  /* [138] */ 46,
+  /* [130] */ 46,
+  /* [131] */ 0,
+  /* [132] */ 28,
+  /* [133] */ 0,
+  /* [134] */ 11,
+  /* [135] */ 1,
+  /* [136] */ 29,
+  /* [137] */ 0,
+  /* [138] */ 30,
   /* [139] */ 0,
-  /* [140] */ 28,
-  /* [141] */ 0,
-  /* [142] */ 11,
-  /* [143] */ 1,
-  /* [144] */ 29,
-  /* [145] */ 0,
-  /* [146] */ 30,
+  /* [140] */ 11,
+  /* [141] */ 8,
+  /* [142] */ 31,
+  /* [143] */ 0,
+  /* [144] */ 11,
+  /* [145] */ 5,
+  /* [146] */ 32,
   /* [147] */ 0,
-  /* [148] */ 11,
-  /* [149] */ 8,
-  /* [150] */ 31,
-  /* [151] */ 0,
-  /* [152] */ 11,
-  /* [153] */ 5,
-  /* [154] */ 32,
-  /* [155] */ 0,
-  /* [156] */ 33,
+  /* [148] */ 33,
+  /* [149] */ 0,
+  /* [150] */ 11,
+  /* [151] */ 6,
+  /* [152] */ 34,
+  /* [153] */ 0,
+  /* [154] */ 11,
+  /* [155] */ 2,
+  /* [156] */ 12,
   /* [157] */ 0,
-  /* [158] */ 11,
-  /* [159] */ 6,
-  /* [160] */ 34,
-  /* [161] */ 0,
-  /* [162] */ 11,
-  /* [163] */ 2,
-  /* [164] */ 12,
+  /* [158] */ 12,
+  /* [159] */ 7,
+  /* [160] */ 31,
+  /* [161] */ 7,
+  /* [162] */ 12,
+  /* [163] */ 8,
+  /* [164] */ 13,
   /* [165] */ 0,
-  /* [166] */ 12,
-  /* [167] */ 7,
-  /* [168] */ 31,
+  /* [166] */ 48,
+  /* [167] */ 0,
+  /* [168] */ 13,
   /* [169] */ 7,
-  /* [170] */ 12,
+  /* [170] */ 13,
   /* [171] */ 8,
-  /* [172] */ 13,
+  /* [172] */ 14,
   /* [173] */ 0,
-  /* [174] */ 48,
-  /* [175] */ 0,
-  /* [176] */ 13,
-  /* [177] */ 7,
-  /* [178] */ 13,
-  /* [179] */ 8,
-  /* [180] */ 14,
-  /* [181] */ 0,
-  /* [182] */ 14,
-  /* [183] */ 7,
-  /* [184] */ 14,
-  /* [185] */ 8,
-  /* [186] */ 15,
-  /* [187] */ 0,
-  /* [188] */ 15,
-  /* [189] */ 7,
-  /* [190] */ 15,
-  /* [191] */ 8,
-  /* [192] */ 16,
-  /* [193] */ 0,
-  /* [194] */ 16,
-  /* [195] */ 7,
-  /* [196] */ 16,
-  /* [197] */ 8,
-  /* [198] */ 17,
-  /* [199] */ 7,
-  /* [200] */ 17,
-  /* [201] */ 8,
-  /* [202] */ 18,
+  /* [174] */ 14,
+  /* [175] */ 7,
+  /* [176] */ 14,
+  /* [177] */ 8,
+  /* [178] */ 15,
+  /* [179] */ 0,
+  /* [180] */ 15,
+  /* [181] */ 7,
+  /* [182] */ 15,
+  /* [183] */ 8,
+  /* [184] */ 16,
+  /* [185] */ 0,
+  /* [186] */ 16,
+  /* [187] */ 7,
+  /* [188] */ 16,
+  /* [189] */ 8,
+  /* [190] */ 17,
+  /* [191] */ 7,
+  /* [192] */ 17,
+  /* [193] */ 8,
+  /* [194] */ 18,
+  /* [195] */ 0,
+  /* [196] */ 18,
+  /* [197] */ 7,
+  /* [198] */ 18,
+  /* [199] */ 8,
+  /* [200] */ 19,
+  /* [201] */ 0,
+  /* [202] */ 49,
   /* [203] */ 0,
-  /* [204] */ 18,
+  /* [204] */ 28,
   /* [205] */ 7,
-  /* [206] */ 18,
-  /* [207] */ 8,
-  /* [208] */ 19,
-  /* [209] */ 0,
-  /* [210] */ 49,
-  /* [211] */ 0,
-  /* [212] */ 28,
-  /* [213] */ 7,
-  /* [214] */ 29,
+  /* [206] */ 29,
+  /* [207] */ 7,
+  /* [208] */ 30,
+  /* [209] */ 7,
+  /* [210] */ 19,
+  /* [211] */ 7,
+  /* [212] */ 19,
+  /* [213] */ 8,
+  /* [214] */ 32,
   /* [215] */ 7,
-  /* [216] */ 30,
+  /* [216] */ 33,
   /* [217] */ 7,
-  /* [218] */ 19,
-  /* [219] */ 7,
-  /* [220] */ 19,
-  /* [221] */ 8,
-  /* [222] */ 32,
-  /* [223] */ 7,
-  /* [224] */ 33,
-  /* [225] */ 7,
-  /* [226] */ 20,
-  /* [227] */ 0,
-  /* [228] */ 20,
-  /* [229] */ 7,
-  /* [230] */ 20,
-  /* [231] */ 8,
-  /* [232] */ 26,
-  /* [233] */ 38,
-  /* [234] */ 27,
-  /* [235] */ 37,
-  /* [236] */ 36,
-  /* [237] */ 35,
-  /* [238] */ 44,
-  /* [239] */ 39,
-  /* [240] */ 45,
-  /* [241] */ 47,
+  /* [218] */ 20,
+  /* [219] */ 0,
+  /* [220] */ 20,
+  /* [221] */ 7,
+  /* [222] */ 20,
+  /* [223] */ 8,
+  /* [224] */ 26,
+  /* [225] */ 38,
+  /* [226] */ 27,
+  /* [227] */ 37,
+  /* [228] */ 36,
+  /* [229] */ 35,
+  /* [230] */ 44,
+  /* [231] */ 39,
+  /* [232] */ 45,
+  /* [233] */ 47,
 };
 
 // Assert that the MatcherIndex is big enough to index all the matchers, plus
@@ -3210,57 +3250,57 @@
   {
     /* [65] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [66] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [67] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [68] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [69] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [70] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [71] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [72] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [73] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [74] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [75] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [76] */
@@ -3270,37 +3310,37 @@
   {
     /* [77] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [78] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [79] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [80] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [81] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [82] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [83] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [84] */
@@ -3335,122 +3375,122 @@
   {
     /* [90] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [91] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [92] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [93] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [94] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [95] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [96] */
     /* usage */ ParameterUsage::kComponent,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [97] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [98] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [99] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [100] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [101] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [102] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [103] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [104] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [105] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [106] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [107] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [108] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [109] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [110] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [111] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [112] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [113] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [114] */
@@ -3485,52 +3525,52 @@
   {
     /* [120] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[224],
+    /* matcher indices */ &kMatcherIndices[216],
   },
   {
     /* [121] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [122] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [123] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [124] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [125] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [126] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [127] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [128] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [129] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [130] */
@@ -3540,27 +3580,27 @@
   {
     /* [131] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [132] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [133] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [134] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [135] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [136] */
@@ -3570,27 +3610,27 @@
   {
     /* [137] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [138] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [139] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [140] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [141] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [142] */
@@ -3600,27 +3640,27 @@
   {
     /* [143] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [144] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [145] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [146] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [147] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [148] */
@@ -3630,27 +3670,27 @@
   {
     /* [149] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [150] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [151] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [152] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [153] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [154] */
@@ -3660,22 +3700,22 @@
   {
     /* [155] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [156] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [157] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [158] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [159] */
@@ -3685,97 +3725,97 @@
   {
     /* [160] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [161] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [162] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [163] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [164] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [165] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [166] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [167] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [168] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [169] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [170] */
     /* usage */ ParameterUsage::kComponent,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [171] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[156],
+    /* matcher indices */ &kMatcherIndices[148],
   },
   {
     /* [172] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [173] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [174] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [175] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [176] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [177] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [178] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [179] */
@@ -3785,42 +3825,42 @@
   {
     /* [180] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [181] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [182] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [183] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [184] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [185] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [186] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [187] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [188] */
@@ -3830,27 +3870,27 @@
   {
     /* [189] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [190] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [191] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [192] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [193] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [194] */
@@ -3860,17 +3900,17 @@
   {
     /* [195] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [196] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [197] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [198] */
@@ -3880,22 +3920,22 @@
   {
     /* [199] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [200] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [201] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [202] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [203] */
@@ -3905,22 +3945,22 @@
   {
     /* [204] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [205] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [206] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [207] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [208] */
@@ -3930,27 +3970,27 @@
   {
     /* [209] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [210] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [211] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [212] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [213] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [214] */
@@ -3960,47 +4000,47 @@
   {
     /* [215] */
     /* usage */ ParameterUsage::kComponent,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [216] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [217] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [218] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [219] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [220] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [221] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [222] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [223] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [224] */
@@ -4010,17 +4050,17 @@
   {
     /* [225] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [226] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [227] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [228] */
@@ -4030,72 +4070,72 @@
   {
     /* [229] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [230] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [231] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [232] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [233] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [234] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [235] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [236] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [237] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [238] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [239] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [240] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [241] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [242] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [243] */
@@ -4105,102 +4145,102 @@
   {
     /* [244] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [245] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[222],
+    /* matcher indices */ &kMatcherIndices[214],
   },
   {
     /* [246] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [247] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [248] */
     /* usage */ ParameterUsage::kDdx,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [249] */
     /* usage */ ParameterUsage::kDdy,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [250] */
     /* usage */ ParameterUsage::kComponent,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [251] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[144],
+    /* matcher indices */ &kMatcherIndices[136],
   },
   {
     /* [252] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [253] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [254] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [255] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [256] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [257] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [258] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [259] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [260] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [261] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [262] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [263] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [264] */
@@ -4210,17 +4250,17 @@
   {
     /* [265] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [266] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [267] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [268] */
@@ -4230,77 +4270,77 @@
   {
     /* [269] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [270] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [271] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [272] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [273] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [274] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [275] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [276] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [277] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [278] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [279] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [280] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[224],
+    /* matcher indices */ &kMatcherIndices[216],
   },
   {
     /* [281] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [282] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [283] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [284] */
@@ -4310,22 +4350,22 @@
   {
     /* [285] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[224],
+    /* matcher indices */ &kMatcherIndices[216],
   },
   {
     /* [286] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [287] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [288] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [289] */
@@ -4335,22 +4375,22 @@
   {
     /* [290] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [291] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [292] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [293] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [294] */
@@ -4360,17 +4400,17 @@
   {
     /* [295] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[222],
+    /* matcher indices */ &kMatcherIndices[214],
   },
   {
     /* [296] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [297] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [298] */
@@ -4380,17 +4420,17 @@
   {
     /* [299] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [300] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [301] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [302] */
@@ -4400,77 +4440,77 @@
   {
     /* [303] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [304] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [305] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [306] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [307] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [308] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [309] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [310] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [311] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[65],
+    /* matcher indices */ &kMatcherIndices[54],
   },
   {
     /* [312] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [313] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [314] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[152],
+    /* matcher indices */ &kMatcherIndices[144],
   },
   {
     /* [315] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [316] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [317] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [318] */
@@ -4480,137 +4520,137 @@
   {
     /* [319] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [320] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [321] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [322] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [323] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [324] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [325] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [326] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [327] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[224],
+    /* matcher indices */ &kMatcherIndices[216],
   },
   {
     /* [328] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [329] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [330] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [331] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [332] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [333] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [334] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [335] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[80],
+    /* matcher indices */ &kMatcherIndices[72],
   },
   {
     /* [336] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [337] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [338] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[128],
+    /* matcher indices */ &kMatcherIndices[120],
   },
   {
     /* [339] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [340] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [341] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [342] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [343] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [344] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [345] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [346] */
@@ -4620,57 +4660,57 @@
   {
     /* [347] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[216],
+    /* matcher indices */ &kMatcherIndices[208],
   },
   {
     /* [348] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [349] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [350] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [351] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [352] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [353] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [354] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [355] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [356] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [357] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [358] */
@@ -4680,57 +4720,57 @@
   {
     /* [359] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[47],
+    /* matcher indices */ &kMatcherIndices[36],
   },
   {
     /* [360] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [361] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [362] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[158],
+    /* matcher indices */ &kMatcherIndices[150],
   },
   {
     /* [363] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [364] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [365] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [366] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [367] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [368] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [369] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [370] */
@@ -4740,17 +4780,17 @@
   {
     /* [371] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [372] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [373] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [374] */
@@ -4760,117 +4800,117 @@
   {
     /* [375] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [376] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [377] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [378] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [379] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [380] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [381] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [382] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [383] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [384] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [385] */
     /* usage */ ParameterUsage::kArrayIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [386] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [387] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [388] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [389] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [390] */
     /* usage */ ParameterUsage::kOffset,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [391] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [392] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [393] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [394] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [395] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [396] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [397] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [398] */
@@ -4900,17 +4940,17 @@
   {
     /* [403] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [404] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [405] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [406] */
@@ -4920,22 +4960,22 @@
   {
     /* [407] */
     /* usage */ ParameterUsage::kComponent,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [408] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[154],
+    /* matcher indices */ &kMatcherIndices[146],
   },
   {
     /* [409] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [410] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [411] */
@@ -4960,37 +5000,37 @@
   {
     /* [415] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [416] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [417] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [418] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [419] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [420] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[234],
+    /* matcher indices */ &kMatcherIndices[226],
   },
   {
     /* [421] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [422] */
@@ -5010,67 +5050,67 @@
   {
     /* [425] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [426] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [427] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [428] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [429] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [430] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [431] */
     /* usage */ ParameterUsage::kComponent,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [432] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[144],
+    /* matcher indices */ &kMatcherIndices[136],
   },
   {
     /* [433] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [434] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [435] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[222],
+    /* matcher indices */ &kMatcherIndices[214],
   },
   {
     /* [436] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [437] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [438] */
@@ -5080,17 +5120,17 @@
   {
     /* [439] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [440] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [441] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [442] */
@@ -5100,82 +5140,82 @@
   {
     /* [443] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [444] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [445] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [446] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [447] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [448] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [449] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [450] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [451] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [452] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [453] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [454] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [455] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [456] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [457] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [458] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [459] */
@@ -5185,262 +5225,262 @@
   {
     /* [460] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [461] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [462] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [463] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [464] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [465] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[53],
+    /* matcher indices */ &kMatcherIndices[42],
   },
   {
     /* [466] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [467] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[158],
+    /* matcher indices */ &kMatcherIndices[150],
   },
   {
     /* [468] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [469] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [470] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [471] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[238],
+    /* matcher indices */ &kMatcherIndices[230],
   },
   {
     /* [472] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [473] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [474] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [475] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [476] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [477] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [478] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [479] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [480] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [481] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [482] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [483] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [484] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [485] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [486] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[101],
+    /* matcher indices */ &kMatcherIndices[93],
   },
   {
     /* [487] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [488] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[128],
+    /* matcher indices */ &kMatcherIndices[120],
   },
   {
     /* [489] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[222],
+    /* matcher indices */ &kMatcherIndices[214],
   },
   {
     /* [490] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [491] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [492] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[83],
+    /* matcher indices */ &kMatcherIndices[75],
   },
   {
     /* [493] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [494] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[128],
+    /* matcher indices */ &kMatcherIndices[120],
   },
   {
     /* [495] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[168],
+    /* matcher indices */ &kMatcherIndices[160],
   },
   {
     /* [496] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [497] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [498] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[74],
+    /* matcher indices */ &kMatcherIndices[66],
   },
   {
     /* [499] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [500] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[128],
+    /* matcher indices */ &kMatcherIndices[120],
   },
   {
     /* [501] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[71],
+    /* matcher indices */ &kMatcherIndices[63],
   },
   {
     /* [502] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [503] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[152],
+    /* matcher indices */ &kMatcherIndices[144],
   },
   {
     /* [504] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[68],
+    /* matcher indices */ &kMatcherIndices[57],
   },
   {
     /* [505] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [506] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[152],
+    /* matcher indices */ &kMatcherIndices[144],
   },
   {
     /* [507] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[214],
+    /* matcher indices */ &kMatcherIndices[206],
   },
   {
     /* [508] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [509] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [510] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[212],
+    /* matcher indices */ &kMatcherIndices[204],
   },
   {
     /* [511] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [512] */
@@ -5450,122 +5490,122 @@
   {
     /* [513] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[62],
+    /* matcher indices */ &kMatcherIndices[51],
   },
   {
     /* [514] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [515] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[152],
+    /* matcher indices */ &kMatcherIndices[144],
   },
   {
     /* [516] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[59],
+    /* matcher indices */ &kMatcherIndices[48],
   },
   {
     /* [517] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [518] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[158],
+    /* matcher indices */ &kMatcherIndices[150],
   },
   {
     /* [519] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[44],
+    /* matcher indices */ &kMatcherIndices[33],
   },
   {
     /* [520] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [521] */
     /* usage */ ParameterUsage::kValue,
-    /* matcher indices */ &kMatcherIndices[158],
+    /* matcher indices */ &kMatcherIndices[150],
   },
   {
     /* [522] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[140],
+    /* matcher indices */ &kMatcherIndices[132],
   },
   {
     /* [523] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [524] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [525] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [526] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [527] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [528] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[144],
+    /* matcher indices */ &kMatcherIndices[136],
   },
   {
     /* [529] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [530] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [531] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[150],
+    /* matcher indices */ &kMatcherIndices[142],
   },
   {
     /* [532] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[112],
+    /* matcher indices */ &kMatcherIndices[104],
   },
   {
     /* [533] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [534] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [535] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [536] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [537] */
@@ -5600,12 +5640,12 @@
   {
     /* [543] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [544] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [545] */
@@ -5615,77 +5655,77 @@
   {
     /* [546] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [547] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [548] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [549] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[160],
+    /* matcher indices */ &kMatcherIndices[152],
   },
   {
     /* [550] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [551] */
     /* usage */ ParameterUsage::kSampleIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [552] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [553] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [554] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [555] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[239],
+    /* matcher indices */ &kMatcherIndices[231],
   },
   {
     /* [556] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [557] */
     /* usage */ ParameterUsage::kSampleIndex,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [558] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [559] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [560] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [561] */
@@ -5705,7 +5745,7 @@
   {
     /* [564] */
     /* usage */ ParameterUsage::kXy,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [565] */
@@ -5720,32 +5760,32 @@
   {
     /* [567] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [568] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [569] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [570] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [571] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [572] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [573] */
@@ -5755,7 +5795,7 @@
   {
     /* [574] */
     /* usage */ ParameterUsage::kYz,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [575] */
@@ -5775,52 +5815,52 @@
   {
     /* [578] */
     /* usage */ ParameterUsage::kZw,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [579] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [580] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [581] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [582] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [583] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [584] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [585] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [586] */
     /* usage */ ParameterUsage::kSampler,
-    /* matcher indices */ &kMatcherIndices[232],
+    /* matcher indices */ &kMatcherIndices[224],
   },
   {
     /* [587] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[108],
+    /* matcher indices */ &kMatcherIndices[100],
   },
   {
     /* [588] */
@@ -5850,42 +5890,42 @@
   {
     /* [593] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [594] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [595] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [596] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [597] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [598] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [599] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [600] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [601] */
@@ -5895,12 +5935,12 @@
   {
     /* [602] */
     /* usage */ ParameterUsage::kZyw,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [603] */
     /* usage */ ParameterUsage::kXyz,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [604] */
@@ -5910,12 +5950,12 @@
   {
     /* [605] */
     /* usage */ ParameterUsage::kXy,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [606] */
     /* usage */ ParameterUsage::kZw,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [607] */
@@ -5925,12 +5965,12 @@
   {
     /* [608] */
     /* usage */ ParameterUsage::kYz,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [609] */
     /* usage */ ParameterUsage::kXy,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [610] */
@@ -5960,22 +6000,22 @@
   {
     /* [615] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [616] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[98],
+    /* matcher indices */ &kMatcherIndices[90],
   },
   {
     /* [617] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[140],
+    /* matcher indices */ &kMatcherIndices[132],
   },
   {
     /* [618] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [619] */
@@ -5985,37 +6025,37 @@
   {
     /* [620] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [621] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[144],
+    /* matcher indices */ &kMatcherIndices[136],
   },
   {
     /* [622] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [623] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [624] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[98],
+    /* matcher indices */ &kMatcherIndices[90],
   },
   {
     /* [625] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [626] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [627] */
@@ -6025,37 +6065,37 @@
   {
     /* [628] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [629] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[150],
+    /* matcher indices */ &kMatcherIndices[142],
   },
   {
     /* [630] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [631] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [632] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [633] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[154],
+    /* matcher indices */ &kMatcherIndices[146],
   },
   {
     /* [634] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [635] */
@@ -6070,22 +6110,22 @@
   {
     /* [637] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[156],
+    /* matcher indices */ &kMatcherIndices[148],
   },
   {
     /* [638] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [639] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [640] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [641] */
@@ -6100,32 +6140,32 @@
   {
     /* [643] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [644] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [645] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [646] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [647] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [648] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [649] */
@@ -6140,32 +6180,32 @@
   {
     /* [651] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [652] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [653] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [654] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [655] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [656] */
     /* usage */ ParameterUsage::kLevel,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [657] */
@@ -6190,12 +6230,12 @@
   {
     /* [661] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [662] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [663] */
@@ -6230,32 +6270,32 @@
   {
     /* [669] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [670] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [671] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [672] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [673] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [674] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [675] */
@@ -6270,12 +6310,12 @@
   {
     /* [677] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [678] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [679] */
@@ -6290,12 +6330,12 @@
   {
     /* [681] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [682] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [683] */
@@ -6310,12 +6350,12 @@
   {
     /* [685] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [686] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [687] */
@@ -6330,12 +6370,12 @@
   {
     /* [689] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [690] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [691] */
@@ -6355,12 +6395,12 @@
   {
     /* [694] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [695] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [696] */
@@ -6370,22 +6410,22 @@
   {
     /* [697] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [698] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [699] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [700] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [701] */
@@ -6400,17 +6440,17 @@
   {
     /* [703] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [704] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [705] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [706] */
@@ -6420,12 +6460,12 @@
   {
     /* [707] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [708] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [709] */
@@ -6450,7 +6490,7 @@
   {
     /* [713] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[77],
+    /* matcher indices */ &kMatcherIndices[69],
   },
   {
     /* [714] */
@@ -6465,7 +6505,7 @@
   {
     /* [716] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [717] */
@@ -6495,12 +6535,12 @@
   {
     /* [722] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [723] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [724] */
@@ -6510,12 +6550,12 @@
   {
     /* [725] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [726] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [727] */
@@ -6545,12 +6585,12 @@
   {
     /* [732] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [733] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [734] */
@@ -6560,12 +6600,12 @@
   {
     /* [735] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [736] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [737] */
@@ -6580,12 +6620,12 @@
   {
     /* [739] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [740] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [741] */
@@ -6605,12 +6645,12 @@
   {
     /* [744] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [745] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [746] */
@@ -6620,12 +6660,12 @@
   {
     /* [747] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [748] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [749] */
@@ -6640,12 +6680,12 @@
   {
     /* [751] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [752] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [753] */
@@ -6670,12 +6710,12 @@
   {
     /* [757] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [758] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [759] */
@@ -6690,12 +6730,12 @@
   {
     /* [761] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [762] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [763] */
@@ -6770,22 +6810,22 @@
   {
     /* [777] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [778] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[95],
+    /* matcher indices */ &kMatcherIndices[87],
   },
   {
     /* [779] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [780] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [781] */
@@ -6795,17 +6835,17 @@
   {
     /* [782] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [783] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[238],
+    /* matcher indices */ &kMatcherIndices[230],
   },
   {
     /* [784] */
     /* usage */ ParameterUsage::kCoords,
-    /* matcher indices */ &kMatcherIndices[132],
+    /* matcher indices */ &kMatcherIndices[124],
   },
   {
     /* [785] */
@@ -6820,57 +6860,57 @@
   {
     /* [787] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [788] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [789] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [790] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [791] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [792] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [793] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [794] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [795] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [796] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [797] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [798] */
@@ -6880,27 +6920,27 @@
   {
     /* [799] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [800] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [801] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [802] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [803] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [804] */
@@ -6910,7 +6950,7 @@
   {
     /* [805] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [806] */
@@ -6920,22 +6960,22 @@
   {
     /* [807] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [808] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [809] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [810] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [811] */
@@ -6945,7 +6985,7 @@
   {
     /* [812] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [813] */
@@ -6955,7 +6995,7 @@
   {
     /* [814] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [815] */
@@ -6965,7 +7005,7 @@
   {
     /* [816] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [817] */
@@ -6975,7 +7015,7 @@
   {
     /* [818] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [819] */
@@ -6985,7 +7025,7 @@
   {
     /* [820] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [821] */
@@ -7000,7 +7040,7 @@
   {
     /* [823] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [824] */
@@ -7010,7 +7050,7 @@
   {
     /* [825] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [826] */
@@ -7020,27 +7060,27 @@
   {
     /* [827] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[34],
+    /* matcher indices */ &kMatcherIndices[26],
   },
   {
     /* [828] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [829] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [830] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [831] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [832] */
@@ -7050,7 +7090,7 @@
   {
     /* [833] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [834] */
@@ -7060,12 +7100,12 @@
   {
     /* [835] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [836] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [837] */
@@ -7075,47 +7115,47 @@
   {
     /* [838] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [839] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [840] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [841] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [842] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [843] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [844] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [845] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [846] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [847] */
@@ -7125,37 +7165,37 @@
   {
     /* [848] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [849] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [850] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [851] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [852] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [853] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [854] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [855] */
@@ -7165,12 +7205,12 @@
   {
     /* [856] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [857] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [858] */
@@ -7180,7 +7220,7 @@
   {
     /* [859] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [860] */
@@ -7190,7 +7230,7 @@
   {
     /* [861] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [862] */
@@ -7200,132 +7240,132 @@
   {
     /* [863] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [864] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [865] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [866] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[136],
+    /* matcher indices */ &kMatcherIndices[128],
   },
   {
     /* [867] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[128],
+    /* matcher indices */ &kMatcherIndices[120],
   },
   {
     /* [868] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[128],
+    /* matcher indices */ &kMatcherIndices[120],
   },
   {
     /* [869] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[239],
+    /* matcher indices */ &kMatcherIndices[231],
   },
   {
     /* [870] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[160],
+    /* matcher indices */ &kMatcherIndices[152],
   },
   {
     /* [871] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [872] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [873] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [874] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [875] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[156],
+    /* matcher indices */ &kMatcherIndices[148],
   },
   {
     /* [876] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[154],
+    /* matcher indices */ &kMatcherIndices[146],
   },
   {
     /* [877] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[150],
+    /* matcher indices */ &kMatcherIndices[142],
   },
   {
     /* [878] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [879] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[144],
+    /* matcher indices */ &kMatcherIndices[136],
   },
   {
     /* [880] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[140],
+    /* matcher indices */ &kMatcherIndices[132],
   },
   {
     /* [881] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[56],
+    /* matcher indices */ &kMatcherIndices[45],
   },
   {
     /* [882] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[233],
+    /* matcher indices */ &kMatcherIndices[225],
   },
   {
     /* [883] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [884] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[156],
+    /* matcher indices */ &kMatcherIndices[148],
   },
   {
     /* [885] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [886] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [887] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [888] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [889] */
@@ -7335,157 +7375,157 @@
   {
     /* [890] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [891] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [892] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [893] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [894] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [895] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [896] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [897] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [898] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [899] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [900] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [901] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[238],
+    /* matcher indices */ &kMatcherIndices[230],
   },
   {
     /* [902] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[86],
+    /* matcher indices */ &kMatcherIndices[78],
   },
   {
     /* [903] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[56],
+    /* matcher indices */ &kMatcherIndices[45],
   },
   {
     /* [904] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[89],
+    /* matcher indices */ &kMatcherIndices[81],
   },
   {
     /* [905] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[92],
+    /* matcher indices */ &kMatcherIndices[84],
   },
   {
     /* [906] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[230],
+    /* matcher indices */ &kMatcherIndices[222],
   },
   {
     /* [907] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[239],
+    /* matcher indices */ &kMatcherIndices[231],
   },
   {
     /* [908] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[228],
+    /* matcher indices */ &kMatcherIndices[220],
   },
   {
     /* [909] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[235],
+    /* matcher indices */ &kMatcherIndices[227],
   },
   {
     /* [910] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[236],
+    /* matcher indices */ &kMatcherIndices[228],
   },
   {
     /* [911] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[237],
+    /* matcher indices */ &kMatcherIndices[229],
   },
   {
     /* [912] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[160],
+    /* matcher indices */ &kMatcherIndices[152],
   },
   {
     /* [913] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[156],
+    /* matcher indices */ &kMatcherIndices[148],
   },
   {
     /* [914] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[154],
+    /* matcher indices */ &kMatcherIndices[146],
   },
   {
     /* [915] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[150],
+    /* matcher indices */ &kMatcherIndices[142],
   },
   {
     /* [916] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[146],
+    /* matcher indices */ &kMatcherIndices[138],
   },
   {
     /* [917] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[144],
+    /* matcher indices */ &kMatcherIndices[136],
   },
   {
     /* [918] */
     /* usage */ ParameterUsage::kTexture,
-    /* matcher indices */ &kMatcherIndices[140],
+    /* matcher indices */ &kMatcherIndices[132],
   },
   {
     /* [919] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [920] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[45],
+    /* matcher indices */ &kMatcherIndices[34],
   },
   {
     /* [921] */
@@ -7495,12 +7535,12 @@
   {
     /* [922] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[226],
+    /* matcher indices */ &kMatcherIndices[218],
   },
   {
     /* [923] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [924] */
@@ -7510,7 +7550,7 @@
   {
     /* [925] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[220],
+    /* matcher indices */ &kMatcherIndices[212],
   },
   {
     /* [926] */
@@ -7525,12 +7565,12 @@
   {
     /* [928] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[218],
+    /* matcher indices */ &kMatcherIndices[210],
   },
   {
     /* [929] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[111],
+    /* matcher indices */ &kMatcherIndices[103],
   },
   {
     /* [930] */
@@ -7540,7 +7580,7 @@
   {
     /* [931] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [932] */
@@ -7555,12 +7595,12 @@
   {
     /* [934] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [935] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[114],
+    /* matcher indices */ &kMatcherIndices[106],
   },
   {
     /* [936] */
@@ -7570,42 +7610,42 @@
   {
     /* [937] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [938] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[126],
+    /* matcher indices */ &kMatcherIndices[118],
   },
   {
     /* [939] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[126],
+    /* matcher indices */ &kMatcherIndices[118],
   },
   {
     /* [940] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[126],
+    /* matcher indices */ &kMatcherIndices[118],
   },
   {
     /* [941] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[126],
+    /* matcher indices */ &kMatcherIndices[118],
   },
   {
     /* [942] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[126],
+    /* matcher indices */ &kMatcherIndices[118],
   },
   {
     /* [943] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[208],
+    /* matcher indices */ &kMatcherIndices[200],
   },
   {
     /* [944] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[116],
+    /* matcher indices */ &kMatcherIndices[108],
   },
   {
     /* [945] */
@@ -7615,52 +7655,52 @@
   {
     /* [946] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [947] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [948] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [949] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[106],
+    /* matcher indices */ &kMatcherIndices[98],
   },
   {
     /* [950] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[106],
+    /* matcher indices */ &kMatcherIndices[98],
   },
   {
     /* [951] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[106],
+    /* matcher indices */ &kMatcherIndices[98],
   },
   {
     /* [952] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[106],
+    /* matcher indices */ &kMatcherIndices[98],
   },
   {
     /* [953] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[106],
+    /* matcher indices */ &kMatcherIndices[98],
   },
   {
     /* [954] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[206],
+    /* matcher indices */ &kMatcherIndices[198],
   },
   {
     /* [955] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[122],
+    /* matcher indices */ &kMatcherIndices[114],
   },
   {
     /* [956] */
@@ -7670,17 +7710,17 @@
   {
     /* [957] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [958] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [959] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [960] */
@@ -7690,72 +7730,72 @@
   {
     /* [961] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [962] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[46],
+    /* matcher indices */ &kMatcherIndices[35],
   },
   {
     /* [963] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [964] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [965] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[142],
+    /* matcher indices */ &kMatcherIndices[134],
   },
   {
     /* [966] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[142],
+    /* matcher indices */ &kMatcherIndices[134],
   },
   {
     /* [967] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[142],
+    /* matcher indices */ &kMatcherIndices[134],
   },
   {
     /* [968] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[142],
+    /* matcher indices */ &kMatcherIndices[134],
   },
   {
     /* [969] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[204],
+    /* matcher indices */ &kMatcherIndices[196],
   },
   {
     /* [970] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[164],
+    /* matcher indices */ &kMatcherIndices[156],
   },
   {
     /* [971] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [972] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[30],
+    /* matcher indices */ &kMatcherIndices[10],
   },
   {
     /* [973] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[166],
+    /* matcher indices */ &kMatcherIndices[158],
   },
   {
     /* [974] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[170],
+    /* matcher indices */ &kMatcherIndices[162],
   },
   {
     /* [975] */
@@ -7765,27 +7805,27 @@
   {
     /* [976] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[172],
+    /* matcher indices */ &kMatcherIndices[164],
   },
   {
     /* [977] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[50],
+    /* matcher indices */ &kMatcherIndices[39],
   },
   {
     /* [978] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [979] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[176],
+    /* matcher indices */ &kMatcherIndices[168],
   },
   {
     /* [980] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[178],
+    /* matcher indices */ &kMatcherIndices[170],
   },
   {
     /* [981] */
@@ -7795,102 +7835,102 @@
   {
     /* [982] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[180],
+    /* matcher indices */ &kMatcherIndices[172],
   },
   {
     /* [983] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [984] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [985] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[182],
+    /* matcher indices */ &kMatcherIndices[174],
   },
   {
     /* [986] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[184],
+    /* matcher indices */ &kMatcherIndices[176],
   },
   {
     /* [987] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[202],
+    /* matcher indices */ &kMatcherIndices[194],
   },
   {
     /* [988] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[186],
+    /* matcher indices */ &kMatcherIndices[178],
   },
   {
     /* [989] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [990] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [991] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[188],
+    /* matcher indices */ &kMatcherIndices[180],
   },
   {
     /* [992] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[190],
+    /* matcher indices */ &kMatcherIndices[182],
   },
   {
     /* [993] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[200],
+    /* matcher indices */ &kMatcherIndices[192],
   },
   {
     /* [994] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[192],
+    /* matcher indices */ &kMatcherIndices[184],
   },
   {
     /* [995] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[4],
+    /* matcher indices */ &kMatcherIndices[1],
   },
   {
     /* [996] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[38],
+    /* matcher indices */ &kMatcherIndices[30],
   },
   {
     /* [997] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[194],
+    /* matcher indices */ &kMatcherIndices[186],
   },
   {
     /* [998] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[196],
+    /* matcher indices */ &kMatcherIndices[188],
   },
   {
     /* [999] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[198],
+    /* matcher indices */ &kMatcherIndices[190],
   },
   {
     /* [1000] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[104],
+    /* matcher indices */ &kMatcherIndices[96],
   },
   {
     /* [1001] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[41],
+    /* matcher indices */ &kMatcherIndices[60],
   },
   {
     /* [1002] */
@@ -7900,7 +7940,7 @@
   {
     /* [1003] */
     /* usage */ ParameterUsage::kNone,
-    /* matcher indices */ &kMatcherIndices[142],
+    /* matcher indices */ &kMatcherIndices[134],
   },
 };
 
@@ -7918,87 +7958,87 @@
   {
     /* [2] */
     /* name */ "T",
-    /* matcher index */ 8,
+    /* matcher index */ 7,
   },
   {
     /* [3] */
     /* name */ "U",
-    /* matcher index */ 53,
+    /* matcher index */ 52,
   },
   {
     /* [4] */
     /* name */ "T",
-    /* matcher index */ 5,
+    /* matcher index */ 8,
   },
   {
     /* [5] */
     /* name */ "U",
-    /* matcher index */ 54,
+    /* matcher index */ 53,
   },
   {
     /* [6] */
     /* name */ "T",
-    /* matcher index */ 6,
+    /* matcher index */ 5,
   },
   {
     /* [7] */
     /* name */ "U",
-    /* matcher index */ 55,
+    /* matcher index */ 54,
   },
   {
     /* [8] */
     /* name */ "T",
-    /* matcher index */ 7,
+    /* matcher index */ 6,
   },
   {
     /* [9] */
     /* name */ "U",
-    /* matcher index */ 52,
+    /* matcher index */ 55,
   },
   {
     /* [10] */
     /* name */ "T",
-    /* matcher index */ 67,
+    /* matcher index */ 68,
   },
   {
     /* [11] */
     /* name */ "T",
-    /* matcher index */ 60,
+    /* matcher index */ 67,
   },
   {
     /* [12] */
     /* name */ "T",
-    /* matcher index */ 59,
+    /* matcher index */ 61,
   },
   {
     /* [13] */
     /* name */ "T",
-    /* matcher index */ 66,
+    /* matcher index */ 57,
   },
   {
     /* [14] */
     /* name */ "T",
-    /* matcher index */ 58,
+    /* matcher index */ 63,
   },
   {
     /* [15] */
     /* name */ "T",
-    /* matcher index */ 63,
+    /* matcher index */ 51,
   },
   {
     /* [16] */
     /* name */ "T",
-    /* matcher index */ 50,
+    /* matcher index */ 64,
   },
   {
     /* [17] */
     /* name */ "T",
-    /* matcher index */ kNoMatcher,
+    /* matcher index */ 50,
   },
   {
     /* [18] */
     /* name */ "T",
-    /* matcher index */ 51,
+    /* matcher index */ kNoMatcher,
   },
   {
     /* [19] */
@@ -8028,17 +8068,12 @@
   {
     /* [24] */
     /* name */ "T",
-    /* matcher index */ 62,
+    /* matcher index */ 58,
   },
   {
     /* [25] */
     /* name */ "T",
-    /* matcher index */ 57,
-  },
-  {
-    /* [26] */
-    /* name */ "T",
-    /* matcher index */ 61,
+    /* matcher index */ 62,
   },
 };
 
@@ -8101,10 +8136,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[918],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8113,10 +8148,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[617],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8125,10 +8160,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[917],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8137,10 +8172,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[621],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8149,10 +8184,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[916],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8161,10 +8196,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[625],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8173,10 +8208,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[915],
-    /* return matcher indices */ &kMatcherIndices[112],
+    /* return matcher indices */ &kMatcherIndices[104],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8185,10 +8220,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[629],
-    /* return matcher indices */ &kMatcherIndices[112],
+    /* return matcher indices */ &kMatcherIndices[104],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8197,10 +8232,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[914],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8209,10 +8244,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[633],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8221,10 +8256,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[913],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8233,10 +8268,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[637],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8245,10 +8280,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[912],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8257,10 +8292,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[911],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8269,10 +8304,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[643],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8281,10 +8316,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[910],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8293,10 +8328,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[647],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8305,10 +8340,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[909],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8317,10 +8352,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[651],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8329,10 +8364,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[835],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8341,10 +8376,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[655],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8353,10 +8388,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[907],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8365,10 +8400,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[3],
     /* parameters */ &kParameters[905],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8377,10 +8412,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[3],
     /* parameters */ &kParameters[904],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8389,10 +8424,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[3],
     /* parameters */ &kParameters[903],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8401,10 +8436,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[3],
     /* parameters */ &kParameters[902],
-    /* return matcher indices */ &kMatcherIndices[112],
+    /* return matcher indices */ &kMatcherIndices[104],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8413,10 +8448,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[901],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8425,10 +8460,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -8437,10 +8472,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[955],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -8449,10 +8484,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[956],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecSplat,
   },
@@ -8461,10 +8496,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[399],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorS,
   },
@@ -8473,10 +8508,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[564],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -8485,10 +8520,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[573],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -8497,10 +8532,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[576],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -8509,10 +8544,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[605],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -8521,10 +8556,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[603],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -8533,10 +8568,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[601],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -8545,10 +8580,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1003],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -8557,10 +8592,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[965],
-    /* return matcher indices */ &kMatcherIndices[148],
+    /* return matcher indices */ &kMatcherIndices[140],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -8569,10 +8604,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[4],
+    /* template types */ &kTemplateTypes[6],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[966],
-    /* return matcher indices */ &kMatcherIndices[152],
+    /* return matcher indices */ &kMatcherIndices[144],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -8581,10 +8616,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[6],
+    /* template types */ &kTemplateTypes[8],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[967],
-    /* return matcher indices */ &kMatcherIndices[158],
+    /* return matcher indices */ &kMatcherIndices[150],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -8596,7 +8631,7 @@
     /* template types */ &kTemplateTypes[0],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[968],
-    /* return matcher indices */ &kMatcherIndices[162],
+    /* return matcher indices */ &kMatcherIndices[154],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -8605,10 +8640,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[510],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8617,10 +8652,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[507],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8629,10 +8664,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[351],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8641,10 +8676,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[347],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8653,10 +8688,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[230],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8665,10 +8700,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[495],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8677,10 +8712,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[331],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8689,10 +8724,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[489],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8701,10 +8736,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[327],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -8713,7 +8748,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[474],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8725,7 +8760,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[323],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8737,7 +8772,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[319],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8749,7 +8784,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[165],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8761,7 +8796,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[462],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8773,7 +8808,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[339],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8785,10 +8820,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[315],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8797,10 +8832,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[265],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8809,10 +8844,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[260],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8821,10 +8856,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[132],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8833,10 +8868,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[299],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8845,10 +8880,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[205],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8857,10 +8892,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[295],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8869,10 +8904,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[285],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8881,7 +8916,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[303],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8893,7 +8928,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[275],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8905,7 +8940,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[270],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8917,7 +8952,7 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[90],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8929,7 +8964,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[307],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8941,7 +8976,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[255],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -8953,10 +8988,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[471],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8965,10 +9000,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[431],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8977,10 +9012,10 @@
     /* num parameters */ 5,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[250],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -8989,10 +9024,10 @@
     /* num parameters */ 5,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[215],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9001,10 +9036,10 @@
     /* num parameters */ 6,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[96],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9013,10 +9048,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[407],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9025,10 +9060,10 @@
     /* num parameters */ 5,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[170],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9037,10 +9072,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[558],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9049,10 +9084,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[387],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9061,10 +9096,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[379],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9073,10 +9108,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[160],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9085,10 +9120,10 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[585],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9097,10 +9132,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[375],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9109,7 +9144,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[486],
     /* return matcher indices */ nullptr,
@@ -9121,7 +9156,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[492],
     /* return matcher indices */ nullptr,
@@ -9133,7 +9168,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[335],
     /* return matcher indices */ nullptr,
@@ -9145,7 +9180,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[498],
     /* return matcher indices */ nullptr,
@@ -9157,7 +9192,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[501],
     /* return matcher indices */ nullptr,
@@ -9169,7 +9204,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[504],
     /* return matcher indices */ nullptr,
@@ -9181,7 +9216,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[311],
     /* return matcher indices */ nullptr,
@@ -9193,7 +9228,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[513],
     /* return matcher indices */ nullptr,
@@ -9205,7 +9240,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[516],
     /* return matcher indices */ nullptr,
@@ -9217,7 +9252,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[465],
     /* return matcher indices */ nullptr,
@@ -9229,7 +9264,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[359],
     /* return matcher indices */ nullptr,
@@ -9241,7 +9276,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[519],
     /* return matcher indices */ nullptr,
@@ -9253,10 +9288,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[116],
+    /* return matcher indices */ &kMatcherIndices[108],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -9265,10 +9300,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[944],
-    /* return matcher indices */ &kMatcherIndices[116],
+    /* return matcher indices */ &kMatcherIndices[108],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -9277,10 +9312,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[945],
-    /* return matcher indices */ &kMatcherIndices[116],
+    /* return matcher indices */ &kMatcherIndices[108],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecSplat,
   },
@@ -9289,10 +9324,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[588],
-    /* return matcher indices */ &kMatcherIndices[116],
+    /* return matcher indices */ &kMatcherIndices[108],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorS,
   },
@@ -9301,10 +9336,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[609],
-    /* return matcher indices */ &kMatcherIndices[116],
+    /* return matcher indices */ &kMatcherIndices[108],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -9313,10 +9348,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[607],
-    /* return matcher indices */ &kMatcherIndices[116],
+    /* return matcher indices */ &kMatcherIndices[108],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorM,
   },
@@ -9325,10 +9360,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[949],
-    /* return matcher indices */ &kMatcherIndices[108],
+    /* return matcher indices */ &kMatcherIndices[100],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9337,10 +9372,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[950],
-    /* return matcher indices */ &kMatcherIndices[110],
+    /* return matcher indices */ &kMatcherIndices[102],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9349,10 +9384,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[4],
+    /* template types */ &kTemplateTypes[6],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[951],
-    /* return matcher indices */ &kMatcherIndices[112],
+    /* return matcher indices */ &kMatcherIndices[104],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9361,10 +9396,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[6],
+    /* template types */ &kTemplateTypes[8],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[952],
-    /* return matcher indices */ &kMatcherIndices[118],
+    /* return matcher indices */ &kMatcherIndices[110],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9376,7 +9411,7 @@
     /* template types */ &kTemplateTypes[0],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[953],
-    /* return matcher indices */ &kMatcherIndices[120],
+    /* return matcher indices */ &kMatcherIndices[112],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9385,10 +9420,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[880],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9397,10 +9432,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[879],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9409,10 +9444,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[878],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9421,10 +9456,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[877],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9433,10 +9468,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[876],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9445,10 +9480,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[875],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9457,10 +9492,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[874],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9469,10 +9504,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[873],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9481,10 +9516,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[872],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9493,10 +9528,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[871],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9505,7 +9540,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[727],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -9517,10 +9552,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[725],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9529,10 +9564,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[723],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9541,10 +9576,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[721],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9553,7 +9588,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[719],
     /* return matcher indices */ &kMatcherIndices[10],
@@ -9565,7 +9600,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[717],
     /* return matcher indices */ &kMatcherIndices[10],
@@ -9577,10 +9612,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[1],
     /* parameters */ &kParameters[715],
-    /* return matcher indices */ &kMatcherIndices[77],
+    /* return matcher indices */ &kMatcherIndices[69],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9589,10 +9624,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[1],
     /* parameters */ &kParameters[713],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9601,7 +9636,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 3,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[0],
     /* parameters */ &kParameters[711],
     /* return matcher indices */ &kMatcherIndices[22],
@@ -9613,10 +9648,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[522],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9625,10 +9660,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[528],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9637,10 +9672,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[363],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9649,10 +9684,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[531],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9661,10 +9696,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[549],
-    /* return matcher indices */ &kMatcherIndices[122],
+    /* return matcher indices */ &kMatcherIndices[114],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9673,7 +9708,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[552],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -9685,7 +9720,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[383],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -9697,7 +9732,7 @@
     /* num parameters */ 3,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[555],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -9709,10 +9744,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[783],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9721,10 +9756,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[114],
+    /* return matcher indices */ &kMatcherIndices[106],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -9733,10 +9768,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[935],
-    /* return matcher indices */ &kMatcherIndices[114],
+    /* return matcher indices */ &kMatcherIndices[106],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -9745,10 +9780,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[936],
-    /* return matcher indices */ &kMatcherIndices[114],
+    /* return matcher indices */ &kMatcherIndices[106],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecSplat,
   },
@@ -9757,10 +9792,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[16],
+    /* template types */ &kTemplateTypes[17],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[611],
-    /* return matcher indices */ &kMatcherIndices[114],
+    /* return matcher indices */ &kMatcherIndices[106],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::VecCtorS,
   },
@@ -9769,10 +9804,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[938],
-    /* return matcher indices */ &kMatcherIndices[136],
+    /* return matcher indices */ &kMatcherIndices[128],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9781,10 +9816,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[939],
-    /* return matcher indices */ &kMatcherIndices[134],
+    /* return matcher indices */ &kMatcherIndices[126],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9793,10 +9828,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[4],
+    /* template types */ &kTemplateTypes[6],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[940],
-    /* return matcher indices */ &kMatcherIndices[132],
+    /* return matcher indices */ &kMatcherIndices[124],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9805,10 +9840,10 @@
     /* num parameters */ 1,
     /* num template types */ 2,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[6],
+    /* template types */ &kTemplateTypes[8],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[941],
-    /* return matcher indices */ &kMatcherIndices[130],
+    /* return matcher indices */ &kMatcherIndices[122],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9820,7 +9855,7 @@
     /* template types */ &kTemplateTypes[0],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[942],
-    /* return matcher indices */ &kMatcherIndices[124],
+    /* return matcher indices */ &kMatcherIndices[116],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -9829,10 +9864,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[180],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9841,10 +9876,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[108],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9853,10 +9888,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[102],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9865,10 +9900,10 @@
     /* num parameters */ 7,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[65],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9877,10 +9912,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[235],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9889,10 +9924,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[78],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9901,10 +9936,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[245],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9913,10 +9948,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[120],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -9925,10 +9960,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[343],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -9937,10 +9972,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[225],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -9949,10 +9984,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[150],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -9961,10 +9996,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[144],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -9973,10 +10008,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[439],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -9985,10 +10020,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[200],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -9997,10 +10032,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[435],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -10009,10 +10044,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[280],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -10021,10 +10056,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[226],
+    /* return matcher indices */ &kMatcherIndices[218],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10033,10 +10068,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[922],
-    /* return matcher indices */ &kMatcherIndices[226],
+    /* return matcher indices */ &kMatcherIndices[218],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10045,10 +10080,10 @@
     /* num parameters */ 16,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[0],
-    /* return matcher indices */ &kMatcherIndices[226],
+    /* return matcher indices */ &kMatcherIndices[218],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10057,10 +10092,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[443],
-    /* return matcher indices */ &kMatcherIndices[226],
+    /* return matcher indices */ &kMatcherIndices[218],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10069,10 +10104,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[908],
-    /* return matcher indices */ &kMatcherIndices[230],
+    /* return matcher indices */ &kMatcherIndices[222],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10081,10 +10116,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[906],
-    /* return matcher indices */ &kMatcherIndices[228],
+    /* return matcher indices */ &kMatcherIndices[220],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10093,7 +10128,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[419],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10105,7 +10140,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[240],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10117,7 +10152,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[220],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10129,7 +10164,7 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[138],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10141,7 +10176,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[403],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10153,7 +10188,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[290],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10165,10 +10200,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[180],
+    /* return matcher indices */ &kMatcherIndices[172],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10177,10 +10212,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[982],
-    /* return matcher indices */ &kMatcherIndices[180],
+    /* return matcher indices */ &kMatcherIndices[172],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10189,10 +10224,10 @@
     /* num parameters */ 8,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[57],
-    /* return matcher indices */ &kMatcherIndices[180],
+    /* return matcher indices */ &kMatcherIndices[172],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10201,10 +10236,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[593],
-    /* return matcher indices */ &kMatcherIndices[180],
+    /* return matcher indices */ &kMatcherIndices[172],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10213,10 +10248,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[985],
-    /* return matcher indices */ &kMatcherIndices[184],
+    /* return matcher indices */ &kMatcherIndices[176],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10225,10 +10260,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[986],
-    /* return matcher indices */ &kMatcherIndices[182],
+    /* return matcher indices */ &kMatcherIndices[174],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10237,10 +10272,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[164],
+    /* return matcher indices */ &kMatcherIndices[156],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10249,10 +10284,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[970],
-    /* return matcher indices */ &kMatcherIndices[164],
+    /* return matcher indices */ &kMatcherIndices[156],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10261,10 +10296,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[411],
-    /* return matcher indices */ &kMatcherIndices[164],
+    /* return matcher indices */ &kMatcherIndices[156],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10273,10 +10308,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[597],
-    /* return matcher indices */ &kMatcherIndices[164],
+    /* return matcher indices */ &kMatcherIndices[156],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10285,10 +10320,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[973],
-    /* return matcher indices */ &kMatcherIndices[170],
+    /* return matcher indices */ &kMatcherIndices[162],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10297,10 +10332,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[974],
-    /* return matcher indices */ &kMatcherIndices[166],
+    /* return matcher indices */ &kMatcherIndices[158],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10309,7 +10344,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[395],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10321,7 +10356,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[195],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10333,7 +10368,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[155],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10345,7 +10380,7 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[72],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10357,7 +10392,7 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[371],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10369,7 +10404,7 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[175],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -10381,10 +10416,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[367],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10393,10 +10428,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[185],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10405,10 +10440,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[190],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10417,10 +10452,10 @@
     /* num parameters */ 6,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[126],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10429,10 +10464,10 @@
     /* num parameters */ 4,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[355],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10441,10 +10476,10 @@
     /* num parameters */ 5,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[210],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10453,10 +10488,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[172],
+    /* return matcher indices */ &kMatcherIndices[164],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10465,10 +10500,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[976],
-    /* return matcher indices */ &kMatcherIndices[172],
+    /* return matcher indices */ &kMatcherIndices[164],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10477,10 +10512,10 @@
     /* num parameters */ 6,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[84],
-    /* return matcher indices */ &kMatcherIndices[172],
+    /* return matcher indices */ &kMatcherIndices[164],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10489,10 +10524,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[595],
-    /* return matcher indices */ &kMatcherIndices[172],
+    /* return matcher indices */ &kMatcherIndices[164],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10501,10 +10536,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[979],
-    /* return matcher indices */ &kMatcherIndices[178],
+    /* return matcher indices */ &kMatcherIndices[170],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10513,10 +10548,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[980],
-    /* return matcher indices */ &kMatcherIndices[176],
+    /* return matcher indices */ &kMatcherIndices[168],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10525,10 +10560,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[202],
+    /* return matcher indices */ &kMatcherIndices[194],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10537,10 +10572,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[987],
-    /* return matcher indices */ &kMatcherIndices[202],
+    /* return matcher indices */ &kMatcherIndices[194],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10549,10 +10584,10 @@
     /* num parameters */ 8,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[49],
-    /* return matcher indices */ &kMatcherIndices[202],
+    /* return matcher indices */ &kMatcherIndices[194],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10561,10 +10596,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[415],
-    /* return matcher indices */ &kMatcherIndices[202],
+    /* return matcher indices */ &kMatcherIndices[194],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10573,10 +10608,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[969],
-    /* return matcher indices */ &kMatcherIndices[206],
+    /* return matcher indices */ &kMatcherIndices[198],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10585,10 +10620,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[954],
-    /* return matcher indices */ &kMatcherIndices[204],
+    /* return matcher indices */ &kMatcherIndices[196],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10597,10 +10632,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[208],
+    /* return matcher indices */ &kMatcherIndices[200],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10609,10 +10644,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[943],
-    /* return matcher indices */ &kMatcherIndices[208],
+    /* return matcher indices */ &kMatcherIndices[200],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10621,10 +10656,10 @@
     /* num parameters */ 12,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[16],
-    /* return matcher indices */ &kMatcherIndices[208],
+    /* return matcher indices */ &kMatcherIndices[200],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10633,10 +10668,10 @@
     /* num parameters */ 4,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[391],
-    /* return matcher indices */ &kMatcherIndices[208],
+    /* return matcher indices */ &kMatcherIndices[200],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10645,10 +10680,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[928],
-    /* return matcher indices */ &kMatcherIndices[220],
+    /* return matcher indices */ &kMatcherIndices[212],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10657,10 +10692,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[925],
-    /* return matcher indices */ &kMatcherIndices[218],
+    /* return matcher indices */ &kMatcherIndices[210],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10669,10 +10704,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[104],
+    /* return matcher indices */ &kMatcherIndices[96],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10681,10 +10716,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1000],
-    /* return matcher indices */ &kMatcherIndices[104],
+    /* return matcher indices */ &kMatcherIndices[96],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10693,10 +10728,10 @@
     /* num parameters */ 12,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[28],
-    /* return matcher indices */ &kMatcherIndices[104],
+    /* return matcher indices */ &kMatcherIndices[96],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10705,10 +10740,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[468],
-    /* return matcher indices */ &kMatcherIndices[104],
+    /* return matcher indices */ &kMatcherIndices[96],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10717,10 +10752,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[999],
-    /* return matcher indices */ &kMatcherIndices[200],
+    /* return matcher indices */ &kMatcherIndices[192],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10729,10 +10764,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[993],
-    /* return matcher indices */ &kMatcherIndices[198],
+    /* return matcher indices */ &kMatcherIndices[190],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10741,10 +10776,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[192],
+    /* return matcher indices */ &kMatcherIndices[184],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10753,10 +10788,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[994],
-    /* return matcher indices */ &kMatcherIndices[192],
+    /* return matcher indices */ &kMatcherIndices[184],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10765,10 +10800,10 @@
     /* num parameters */ 9,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[40],
-    /* return matcher indices */ &kMatcherIndices[192],
+    /* return matcher indices */ &kMatcherIndices[184],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10777,10 +10812,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[582],
-    /* return matcher indices */ &kMatcherIndices[192],
+    /* return matcher indices */ &kMatcherIndices[184],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10789,10 +10824,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[997],
-    /* return matcher indices */ &kMatcherIndices[196],
+    /* return matcher indices */ &kMatcherIndices[188],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10801,10 +10836,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[998],
-    /* return matcher indices */ &kMatcherIndices[194],
+    /* return matcher indices */ &kMatcherIndices[186],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10813,10 +10848,10 @@
     /* num parameters */ 0,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[186],
+    /* return matcher indices */ &kMatcherIndices[178],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -10825,10 +10860,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[988],
-    /* return matcher indices */ &kMatcherIndices[186],
+    /* return matcher indices */ &kMatcherIndices[178],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -10837,10 +10872,10 @@
     /* num parameters */ 6,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[114],
-    /* return matcher indices */ &kMatcherIndices[186],
+    /* return matcher indices */ &kMatcherIndices[178],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorS,
   },
@@ -10849,10 +10884,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[11],
+    /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[579],
-    /* return matcher indices */ &kMatcherIndices[186],
+    /* return matcher indices */ &kMatcherIndices[178],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::MatCtorV,
   },
@@ -10861,10 +10896,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[2],
+    /* template types */ &kTemplateTypes[4],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[991],
-    /* return matcher indices */ &kMatcherIndices[190],
+    /* return matcher indices */ &kMatcherIndices[182],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10873,10 +10908,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[8],
+    /* template types */ &kTemplateTypes[2],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[992],
-    /* return matcher indices */ &kMatcherIndices[188],
+    /* return matcher indices */ &kMatcherIndices[180],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -10885,7 +10920,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[737],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -10897,10 +10932,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[735],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10909,10 +10944,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[733],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10921,10 +10956,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[731],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10933,7 +10968,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[729],
     /* return matcher indices */ &kMatcherIndices[10],
@@ -10945,10 +10980,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[885],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10957,10 +10992,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[884],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10969,10 +11004,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[883],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10981,10 +11016,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[882],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -10993,10 +11028,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[3],
     /* parameters */ &kParameters[881],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11005,7 +11040,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[749],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11017,10 +11052,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[747],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11029,10 +11064,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[745],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11041,10 +11076,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[743],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11053,7 +11088,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[13],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[741],
     /* return matcher indices */ &kMatcherIndices[10],
@@ -11065,7 +11100,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[701],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11077,10 +11112,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[699],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11089,10 +11124,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[695],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11101,10 +11136,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[693],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11113,7 +11148,7 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[687],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -11125,10 +11160,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[685],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11152,7 +11187,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[681],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11161,7 +11196,7 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[679],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -11173,10 +11208,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[677],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11200,7 +11235,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[673],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11209,7 +11244,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[709],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11221,10 +11256,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[707],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11233,10 +11268,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[705],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11245,10 +11280,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[781],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11257,10 +11292,10 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -11269,10 +11304,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[920],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -11284,7 +11319,7 @@
     /* template types */ &kTemplateTypes[23],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[921],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -11293,7 +11328,7 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -11305,7 +11340,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[932],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -11329,10 +11364,10 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[111],
+    /* return matcher indices */ &kMatcherIndices[103],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -11341,10 +11376,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[929],
-    /* return matcher indices */ &kMatcherIndices[111],
+    /* return matcher indices */ &kMatcherIndices[103],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -11356,7 +11391,7 @@
     /* template types */ &kTemplateTypes[20],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[930],
-    /* return matcher indices */ &kMatcherIndices[111],
+    /* return matcher indices */ &kMatcherIndices[103],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
@@ -11365,7 +11400,7 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -11377,7 +11412,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[926],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -11401,7 +11436,7 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[20],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[540],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11413,10 +11448,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[20],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[543],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11425,10 +11460,10 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[20],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[546],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11437,10 +11472,10 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Zero,
   },
@@ -11449,10 +11484,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[923],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Identity,
   },
@@ -11464,43 +11499,43 @@
     /* template types */ &kTemplateTypes[22],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[924],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::Conv,
   },
   {
     /* [281] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[477],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [282] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[480],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [283] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[483],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11509,7 +11544,7 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[26],
+    /* template types */ &kTemplateTypes[25],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[860],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11521,10 +11556,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[26],
+    /* template types */ &kTemplateTypes[25],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[861],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::OpComplement,
   },
@@ -11533,10 +11568,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[798],
-    /* return matcher indices */ &kMatcherIndices[241],
+    /* return matcher indices */ &kMatcherIndices[233],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11545,10 +11580,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[810],
-    /* return matcher indices */ &kMatcherIndices[174],
+    /* return matcher indices */ &kMatcherIndices[166],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11557,7 +11592,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[822],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -11569,34 +11604,34 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[823],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
   {
     /* [290] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[800],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [291] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[799],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11605,7 +11640,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[826],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -11617,10 +11652,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[830],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -11644,127 +11679,127 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[427],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [296] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[846],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [297] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[848],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [298] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[779],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [299] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[777],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [300] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[849],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [301] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[850],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [302] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[851],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [303] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[852],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [304] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[853],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [305] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[854],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11773,7 +11808,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[763],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11785,10 +11820,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[761],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11797,7 +11832,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[759],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -11809,34 +11844,34 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[757],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [310] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[450],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [311] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[447],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11845,10 +11880,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[855],
-    /* return matcher indices */ &kMatcherIndices[240],
+    /* return matcher indices */ &kMatcherIndices[232],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11857,34 +11892,34 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[856],
-    /* return matcher indices */ &kMatcherIndices[138],
+    /* return matcher indices */ &kMatcherIndices[130],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [314] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[802],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [315] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[801],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11893,7 +11928,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[824],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -11905,10 +11940,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[825],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -11932,7 +11967,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[805],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -11956,103 +11991,103 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[456],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [322] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[808],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [323] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[807],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [324] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[886],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [325] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[809],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [326] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[739],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [327] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[703],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [328] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[887],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [329] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[888],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12061,7 +12096,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[811],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -12073,10 +12108,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[1001],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -12085,7 +12120,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[813],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -12097,10 +12132,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[812],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -12124,31 +12159,31 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[890],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [336] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[891],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [337] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[892],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12157,7 +12192,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[815],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -12169,154 +12204,154 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[814],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
   {
     /* [340] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[893],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [341] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[894],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [342] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[895],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [343] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[896],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [344] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[897],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [345] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[898],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [346] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[567],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [347] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[570],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [348] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[899],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [349] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[900],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [350] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[671],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [351] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[669],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12340,55 +12375,55 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[803],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [354] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[919],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [355] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[797],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [356] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[984],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [357] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[978],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12397,7 +12432,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[817],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -12409,34 +12444,34 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[816],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
   {
     /* [360] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[964],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [361] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[963],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12445,7 +12480,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[819],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -12457,10 +12492,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[818],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -12484,7 +12519,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[615],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12493,7 +12528,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[821],
     /* return matcher indices */ &kMatcherIndices[4],
@@ -12505,10 +12540,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[820],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[60],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
     /* const eval */ nullptr,
   },
@@ -12517,7 +12552,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[635],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -12529,10 +12564,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[631],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12541,7 +12576,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[641],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -12553,10 +12588,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[639],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12565,7 +12600,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[649],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -12577,58 +12612,58 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[645],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [374] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[787],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [375] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[789],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [376] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[829],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [377] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[828],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12637,7 +12672,7 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1002],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -12649,10 +12684,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[996],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12676,7 +12711,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[831],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12700,7 +12735,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[833],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12709,10 +12744,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[16],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[870],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12721,10 +12756,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[869],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12748,7 +12783,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[836],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12757,7 +12792,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[657],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -12769,58 +12804,58 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[24],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[653],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [390] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[839],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [391] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[838],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [392] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[841],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [393] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[840],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12829,7 +12864,7 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[14],
+    /* template types */ &kTemplateTypes[13],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[537],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -12841,58 +12876,58 @@
     /* num parameters */ 3,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[14],
+    /* template types */ &kTemplateTypes[13],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[534],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::clamp,
   },
   {
     /* [396] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[843],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [397] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[842],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [398] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[845],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [399] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[844],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12916,7 +12951,7 @@
     /* template types */ &kTemplateTypes[12],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[751],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::atan2,
   },
@@ -12925,7 +12960,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[659],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -12937,10 +12972,10 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[599],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -12949,7 +12984,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[663],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -12961,58 +12996,58 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[18],
+    /* template types */ &kTemplateTypes[15],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[661],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [406] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[934],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [407] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[931],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [408] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[957],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [409] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[946],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13036,31 +13071,31 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[689],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [412] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[959],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [413] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[958],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13069,7 +13104,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[975],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13081,7 +13116,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[971],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13093,7 +13128,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[981],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13105,7 +13140,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[977],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13115,48 +13150,48 @@
   {
     /* [418] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[989],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [419] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[983],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [420] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[995],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [421] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[990],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13165,7 +13200,7 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[25],
+    /* template types */ &kTemplateTypes[24],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[862],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -13177,10 +13212,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[25],
+    /* template types */ &kTemplateTypes[24],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[863],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ &ConstEval::OpMinus,
   },
@@ -13189,7 +13224,7 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[858],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13201,10 +13236,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[859],
-    /* return matcher indices */ &kMatcherIndices[50],
+    /* return matcher indices */ &kMatcherIndices[39],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13228,7 +13263,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[623],
-    /* return matcher indices */ &kMatcherIndices[38],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13240,7 +13275,7 @@
     /* template types */ &kTemplateTypes[10],
     /* template numbers */ &kTemplateNumbers[9],
     /* parameters */ &kParameters[561],
-    /* return matcher indices */ &kMatcherIndices[210],
+    /* return matcher indices */ &kMatcherIndices[202],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13345,7 +13380,7 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[667],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13357,7 +13392,7 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[665],
     /* return matcher indices */ &kMatcherIndices[16],
@@ -13393,7 +13428,7 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
     /* return matcher indices */ nullptr,
@@ -13405,7 +13440,7 @@
     /* num parameters */ 0,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[1004],
     /* return matcher indices */ nullptr,
@@ -13417,10 +13452,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[937],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13429,10 +13464,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[947],
-    /* return matcher indices */ &kMatcherIndices[128],
+    /* return matcher indices */ &kMatcherIndices[120],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13441,10 +13476,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[948],
-    /* return matcher indices */ &kMatcherIndices[136],
+    /* return matcher indices */ &kMatcherIndices[128],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13453,10 +13488,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[961],
-    /* return matcher indices */ &kMatcherIndices[136],
+    /* return matcher indices */ &kMatcherIndices[128],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13465,46 +13500,46 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[962],
-    /* return matcher indices */ &kMatcherIndices[136],
+    /* return matcher indices */ &kMatcherIndices[128],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [448] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 2,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[5],
     /* parameters */ &kParameters[972],
-    /* return matcher indices */ &kMatcherIndices[26],
+    /* return matcher indices */ &kMatcherIndices[18],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [449] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[525],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [450] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[697],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13513,10 +13548,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[868],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13525,10 +13560,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[867],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13537,10 +13572,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[866],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13549,31 +13584,31 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[865],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [455] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[857],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
   {
     /* [456] */
     /* num parameters */ 2,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[785],
     /* return matcher indices */ &kMatcherIndices[108],
@@ -13583,12 +13618,12 @@
   {
     /* [457] */
     /* num parameters */ 3,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[453],
-    /* return matcher indices */ &kMatcherIndices[41],
+    /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13597,10 +13632,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[795],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13609,10 +13644,10 @@
     /* num parameters */ 2,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[793],
-    /* return matcher indices */ &kMatcherIndices[45],
+    /* return matcher indices */ &kMatcherIndices[34],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13621,7 +13656,7 @@
     /* num parameters */ 2,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[15],
+    /* template types */ &kTemplateTypes[14],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[791],
     /* return matcher indices */ &kMatcherIndices[1],
@@ -13631,12 +13666,12 @@
   {
     /* [461] */
     /* num parameters */ 1,
-    /* num template types */ 0,
+    /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[11],
     /* template numbers */ &kTemplateNumbers[6],
     /* parameters */ &kParameters[827],
-    /* return matcher indices */ &kMatcherIndices[4],
+    /* return matcher indices */ &kMatcherIndices[1],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13645,10 +13680,10 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[17],
+    /* template types */ &kTemplateTypes[18],
     /* template numbers */ &kTemplateNumbers[8],
     /* parameters */ &kParameters[960],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13657,10 +13692,10 @@
     /* num parameters */ 1,
     /* num template types */ 0,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[27],
+    /* template types */ &kTemplateTypes[26],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[864],
-    /* return matcher indices */ &kMatcherIndices[46],
+    /* return matcher indices */ &kMatcherIndices[35],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
     /* const eval */ nullptr,
   },
@@ -13669,22 +13704,22 @@
 constexpr IntrinsicInfo kBuiltins[] = {
   {
     /* [0] */
-    /* fn abs<T : fiu32>(T) -> T */
-    /* fn abs<N : num, T : fiu32>(vec<N, T>) -> vec<N, T> */
+    /* fn abs<T : fiu32_f16>(T) -> T */
+    /* fn abs<N : num, T : fiu32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[378],
   },
   {
     /* [1] */
-    /* fn acos(f32) -> f32 */
-    /* fn acos<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn acos<T : f32_f16>(T) -> T */
+    /* fn acos<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[420],
   },
   {
     /* [2] */
-    /* fn acosh(f32) -> f32 */
-    /* fn acosh<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn acosh<T : f32_f16>(T) -> T */
+    /* fn acosh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[418],
   },
@@ -13710,64 +13745,64 @@
   },
   {
     /* [6] */
-    /* fn asin(f32) -> f32 */
-    /* fn asin<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn asin<T : f32_f16>(T) -> T */
+    /* fn asin<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[412],
   },
   {
     /* [7] */
-    /* fn asinh(f32) -> f32 */
-    /* fn asinh<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn asinh<T : f32_f16>(T) -> T */
+    /* fn asinh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[408],
   },
   {
     /* [8] */
-    /* fn atan(f32) -> f32 */
-    /* fn atan<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn atan<T : f32_f16>(T) -> T */
+    /* fn atan<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[406],
   },
   {
     /* [9] */
-    /* fn atan2<T : fa_f32>(T, T) -> T */
-    /* fn atan2<N : num, T : fa_f32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+    /* fn atan2<T : fa_f32_f16>(T, T) -> T */
+    /* fn atan2<T : fa_f32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[400],
   },
   {
     /* [10] */
-    /* fn atanh(f32) -> f32 */
-    /* fn atanh<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn atanh<T : f32_f16>(T) -> T */
+    /* fn atanh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[398],
   },
   {
     /* [11] */
-    /* fn ceil(f32) -> f32 */
-    /* fn ceil<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn ceil<T : f32_f16>(T) -> T */
+    /* fn ceil<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[396],
   },
   {
     /* [12] */
-    /* fn clamp<T : fia_fiu32>(T, T, T) -> T */
-    /* fn clamp<N : num, T : fia_fiu32>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
+    /* fn clamp<T : fia_fiu32_f16>(T, T, T) -> T */
+    /* fn clamp<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[394],
   },
   {
     /* [13] */
-    /* fn cos(f32) -> f32 */
-    /* fn cos<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn cos<T : f32_f16>(T) -> T */
+    /* fn cos<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[392],
   },
   {
     /* [14] */
-    /* fn cosh(f32) -> f32 */
-    /* fn cosh<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn cosh<T : f32_f16>(T) -> T */
+    /* fn cosh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[390],
   },
@@ -13794,33 +13829,33 @@
   },
   {
     /* [18] */
-    /* fn cross(vec3<f32>, vec3<f32>) -> vec3<f32> */
+    /* fn cross<T : f32_f16>(vec3<T>, vec3<T>) -> vec3<T> */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[456],
   },
   {
     /* [19] */
-    /* fn degrees(f32) -> f32 */
-    /* fn degrees<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn degrees<T : f32_f16>(T) -> T */
+    /* fn degrees<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[376],
   },
   {
     /* [20] */
-    /* fn determinant<N : num>(mat<N, N, f32>) -> f32 */
+    /* fn determinant<N : num, T : f32_f16>(mat<N, N, T>) -> T */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[461],
   },
   {
     /* [21] */
-    /* fn distance(f32, f32) -> f32 */
-    /* fn distance<N : num>(vec<N, f32>, vec<N, f32>) -> f32 */
+    /* fn distance<T : f32_f16>(T, T) -> T */
+    /* fn distance<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> T */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[374],
   },
   {
     /* [22] */
-    /* fn dot<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> T */
+    /* fn dot<N : num, T : fiu32_f16>(vec<N, T>, vec<N, T>) -> T */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[460],
   },
@@ -13880,15 +13915,15 @@
   },
   {
     /* [31] */
-    /* fn exp(f32) -> f32 */
-    /* fn exp<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn exp<T : f32_f16>(T) -> T */
+    /* fn exp<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[324],
   },
   {
     /* [32] */
-    /* fn exp2(f32) -> f32 */
-    /* fn exp2<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn exp2<T : f32_f16>(T) -> T */
+    /* fn exp2<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[322],
   },
@@ -13901,7 +13936,7 @@
   },
   {
     /* [34] */
-    /* fn faceForward<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+    /* fn faceForward<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[457],
   },
@@ -13921,22 +13956,22 @@
   },
   {
     /* [37] */
-    /* fn floor(f32) -> f32 */
-    /* fn floor<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn floor<T : f32_f16>(T) -> T */
+    /* fn floor<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[314],
   },
   {
     /* [38] */
-    /* fn fma(f32, f32, f32) -> f32 */
-    /* fn fma<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+    /* fn fma<T : f32_f16>(T, T, T) -> T */
+    /* fn fma<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[310],
   },
   {
     /* [39] */
-    /* fn fract(f32) -> f32 */
-    /* fn fract<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn fract<T : f32_f16>(T) -> T */
+    /* fn fract<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[290],
   },
@@ -13977,58 +14012,58 @@
   },
   {
     /* [45] */
-    /* fn inverseSqrt(f32) -> f32 */
-    /* fn inverseSqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn inverseSqrt<T : f32_f16>(T) -> T */
+    /* fn inverseSqrt<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[296],
   },
   {
     /* [46] */
-    /* fn ldexp(f32, i32) -> f32 */
-    /* fn ldexp<N : num>(vec<N, f32>, vec<N, i32>) -> vec<N, f32> */
+    /* fn ldexp<T : f32_f16>(T, i32) -> T */
+    /* fn ldexp<N : num, T : f32_f16>(vec<N, T>, vec<N, i32>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[298],
   },
   {
     /* [47] */
-    /* fn length(f32) -> f32 */
-    /* fn length<N : num>(vec<N, f32>) -> f32 */
+    /* fn length<T : f32_f16>(T) -> T */
+    /* fn length<N : num, T : f32_f16>(vec<N, T>) -> T */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[300],
   },
   {
     /* [48] */
-    /* fn log(f32) -> f32 */
-    /* fn log<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn log<T : f32_f16>(T) -> T */
+    /* fn log<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[302],
   },
   {
     /* [49] */
-    /* fn log2(f32) -> f32 */
-    /* fn log2<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn log2<T : f32_f16>(T) -> T */
+    /* fn log2<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[304],
   },
   {
     /* [50] */
-    /* fn max<T : fiu32>(T, T) -> T */
-    /* fn max<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+    /* fn max<T : fiu32_f16>(T, T) -> T */
+    /* fn max<N : num, T : fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[306],
   },
   {
     /* [51] */
-    /* fn min<T : fiu32>(T, T) -> T */
-    /* fn min<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+    /* fn min<T : fiu32_f16>(T, T) -> T */
+    /* fn min<N : num, T : fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[308],
   },
   {
     /* [52] */
-    /* fn mix(f32, f32, f32) -> f32 */
-    /* fn mix<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
-    /* fn mix<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
+    /* fn mix<T : f32_f16>(T, T, T) -> T */
+    /* fn mix<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
+    /* fn mix<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T> */
     /* num overloads */ 3,
     /* overloads */ &kOverloads[281],
   },
@@ -14041,7 +14076,7 @@
   },
   {
     /* [54] */
-    /* fn normalize<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn normalize<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[455],
   },
@@ -14077,27 +14112,27 @@
   },
   {
     /* [60] */
-    /* fn pow(f32, f32) -> f32 */
-    /* fn pow<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+    /* fn pow<T : f32_f16>(T, T) -> T */
+    /* fn pow<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[326],
   },
   {
     /* [61] */
-    /* fn radians(f32) -> f32 */
-    /* fn radians<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn radians<T : f32_f16>(T) -> T */
+    /* fn radians<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[328],
   },
   {
     /* [62] */
-    /* fn reflect<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+    /* fn reflect<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[450],
   },
   {
     /* [63] */
-    /* fn refract<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
+    /* fn refract<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T> */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[449],
   },
@@ -14110,58 +14145,58 @@
   },
   {
     /* [65] */
-    /* fn round(f32) -> f32 */
-    /* fn round<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn round<T : f32_f16>(T) -> T */
+    /* fn round<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[336],
   },
   {
     /* [66] */
-    /* fn select<T : scalar_no_f16>(T, T, bool) -> T */
-    /* fn select<T : scalar_no_f16, N : num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T> */
-    /* fn select<N : num, T : scalar_no_f16>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T> */
+    /* fn select<T : scalar>(T, T, bool) -> T */
+    /* fn select<T : scalar, N : num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T> */
+    /* fn select<N : num, T : scalar>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T> */
     /* num overloads */ 3,
     /* overloads */ &kOverloads[275],
   },
   {
     /* [67] */
-    /* fn sign(f32) -> f32 */
-    /* fn sign<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn sign<T : f32_f16>(T) -> T */
+    /* fn sign<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[340],
   },
   {
     /* [68] */
-    /* fn sin(f32) -> f32 */
-    /* fn sin<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn sin<T : f32_f16>(T) -> T */
+    /* fn sin<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[342],
   },
   {
     /* [69] */
-    /* fn sinh(f32) -> f32 */
-    /* fn sinh<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn sinh<T : f32_f16>(T) -> T */
+    /* fn sinh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[344],
   },
   {
     /* [70] */
-    /* fn smoothstep(f32, f32, f32) -> f32 */
-    /* fn smoothstep<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+    /* fn smoothstep<T : f32_f16>(T, T, T) -> T */
+    /* fn smoothstep<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[346],
   },
   {
     /* [71] */
-    /* fn sqrt(f32) -> f32 */
-    /* fn sqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn sqrt<T : f32_f16>(T) -> T */
+    /* fn sqrt<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[348],
   },
   {
     /* [72] */
-    /* fn step(f32, f32) -> f32 */
-    /* fn step<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+    /* fn step<T : f32_f16>(T, T) -> T */
+    /* fn step<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[350],
   },
@@ -14173,28 +14208,28 @@
   },
   {
     /* [74] */
-    /* fn tan(f32) -> f32 */
-    /* fn tan<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn tan<T : f32_f16>(T) -> T */
+    /* fn tan<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[354],
   },
   {
     /* [75] */
-    /* fn tanh(f32) -> f32 */
-    /* fn tanh<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn tanh<T : f32_f16>(T) -> T */
+    /* fn tanh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[356],
   },
   {
     /* [76] */
-    /* fn transpose<M : num, N : num>(mat<M, N, f32>) -> mat<N, M, f32> */
+    /* fn transpose<M : num, N : num, T : f32_f16>(mat<M, N, T>) -> mat<N, M, T> */
     /* num overloads */ 1,
     /* overloads */ &kOverloads[448],
   },
   {
     /* [77] */
-    /* fn trunc(f32) -> f32 */
-    /* fn trunc<N : num>(vec<N, f32>) -> vec<N, f32> */
+    /* fn trunc<T : f32_f16>(T) -> T */
+    /* fn trunc<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[360],
   },
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 56492b0..bd363c1 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -35,14 +35,6 @@
 using f32M = builder::mat<3, 2, f32>;
 using i32Varr = builder::array<3, i32>;
 
-constexpr double kHighestU32 = static_cast<double>(u32::kHighest);
-constexpr double kLowestU32 = static_cast<double>(u32::kLowest);
-constexpr double kHighestI32 = static_cast<double>(i32::kHighest);
-constexpr double kLowestI32 = static_cast<double>(i32::kLowest);
-constexpr double kHighestF32 = static_cast<double>(f32::kHighest);
-constexpr double kLowestF32 = static_cast<double>(f32::kLowest);
-// constexpr double kHighestF16 = static_cast<double>(f16::kHighest);
-// constexpr double kLowestF16 = static_cast<double>(f16::kLowest);
 constexpr double kTooBigF32 = static_cast<double>(3.5e+38);
 // constexpr double kTooBigF16 = static_cast<double>(6.6e+4);
 constexpr double kPiF64 = 3.141592653589793;
@@ -460,142 +452,148 @@
 INSTANTIATE_TEST_SUITE_P(
     MaterializeScalar,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kScalarMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32, AInt>(0_a, 0.0),                                        //
-                         Types<i32, AInt>(1_a, 1.0),                                        //
-                         Types<i32, AInt>(-1_a, -1.0),                                      //
-                         Types<i32, AInt>(AInt(kHighestI32), kHighestI32),                  //
-                         Types<i32, AInt>(AInt(kLowestI32), kLowestI32),                    //
-                         Types<u32, AInt>(0_a, 0.0),                                        //
-                         Types<u32, AInt>(1_a, 1.0),                                        //
-                         Types<u32, AInt>(AInt(kHighestU32), kHighestU32),                  //
-                         Types<u32, AInt>(AInt(kLowestU32), kLowestU32),                    //
-                         Types<f32, AFloat>(0.0_a, 0.0),                                    //
-                         Types<f32, AFloat>(AFloat(kHighestF32), kHighestF32),              //
-                         Types<f32, AFloat>(AFloat(kLowestF32), kLowestF32),                //
-                         Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                        //
-                         Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),          //
-                         Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),        //
-                         /* Types<f16, AFloat>(0.0_a, 0.0),                             */  //
-                         /* Types<f16, AFloat>(1.0_a, 1.0),                             */  //
-                         /* Types<f16, AFloat>(AFloat(kHighestF16), kHighestF16),       */  //
-                         /* Types<f16, AFloat>(AFloat(kLowestF16), kLowestF16),         */  //
-                         /* Types<f16, AFloat>(AFloat(kPiF16), kPiF64),                 */  //
-                         /* Types<f16, AFloat>(AFloat(kSubnormalF16), kSubnormalF16),   */  //
-                         /* Types<f16, AFloat>(AFloat(-kSubnormalF16), -kSubnormalF16), */  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kScalarMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32, AInt>(0_a, 0.0),                                                       //
+            Types<i32, AInt>(1_a, 1.0),                                                       //
+            Types<i32, AInt>(-1_a, -1.0),                                                     //
+            Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<u32, AInt>(0_a, 0.0),                                                       //
+            Types<u32, AInt>(1_a, 1.0),                                                       //
+            Types<u32, AInt>(AInt(u32::Highest()), u32::Highest()),                           //
+            Types<u32, AInt>(AInt(u32::Lowest()), u32::Lowest()),                             //
+            Types<f32, AFloat>(0.0_a, 0.0),                                                   //
+            Types<f32, AFloat>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32, AFloat>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+            /* Types<f16, AFloat>(0.0_a, 0.0),                             */                 //
+            /* Types<f16, AFloat>(1.0_a, 1.0),                             */                 //
+            /* Types<f16, AFloat>(AFloat(kHighestF16), kHighestF16),       */                 //
+            /* Types<f16, AFloat>(AFloat(kLowestF16), kLowestF16),         */                 //
+            /* Types<f16, AFloat>(AFloat(kPiF16), kPiF64),                 */                 //
+            /* Types<f16, AFloat>(AFloat(kSubnormalF16), kSubnormalF16),   */                 //
+            /* Types<f16, AFloat>(AFloat(-kSubnormalF16), -kSubnormalF16), */                 //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeVector,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kVectorMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32V, AIntV>(0_a, 0.0),                                        //
-                         Types<i32V, AIntV>(1_a, 1.0),                                        //
-                         Types<i32V, AIntV>(-1_a, -1.0),                                      //
-                         Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32),                  //
-                         Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32),                    //
-                         Types<u32V, AIntV>(0_a, 0.0),                                        //
-                         Types<u32V, AIntV>(1_a, 1.0),                                        //
-                         Types<u32V, AIntV>(AInt(kHighestU32), kHighestU32),                  //
-                         Types<u32V, AIntV>(AInt(kLowestU32), kLowestU32),                    //
-                         Types<f32V, AFloatV>(0.0_a, 0.0),                                    //
-                         Types<f32V, AFloatV>(1.0_a, 1.0),                                    //
-                         Types<f32V, AFloatV>(-1.0_a, -1.0),                                  //
-                         Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32),              //
-                         Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32),                //
-                         Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                        //
-                         Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),          //
-                         Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),        //
-                         /* Types<f16V, AFloatV>(0.0_a, 0.0),                             */  //
-                         /* Types<f16V, AFloatV>(1.0_a, 1.0),                             */  //
-                         /* Types<f16V, AFloatV>(-1.0_a, -1.0),                           */  //
-                         /* Types<f16V, AFloatV>(AFloat(kHighestF16), kHighestF16),       */  //
-                         /* Types<f16V, AFloatV>(AFloat(kLowestF16), kLowestF16),         */  //
-                         /* Types<f16V, AFloatV>(AFloat(kPiF16), kPiF64),                 */  //
-                         /* Types<f16V, AFloatV>(AFloat(kSubnormalF16), kSubnormalF16),   */  //
-                         /* Types<f16V, AFloatV>(AFloat(-kSubnormalF16), -kSubnormalF16), */  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kVectorMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32V, AIntV>(0_a, 0.0),                                                       //
+            Types<i32V, AIntV>(1_a, 1.0),                                                       //
+            Types<i32V, AIntV>(-1_a, -1.0),                                                     //
+            Types<i32V, AIntV>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32V, AIntV>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<u32V, AIntV>(0_a, 0.0),                                                       //
+            Types<u32V, AIntV>(1_a, 1.0),                                                       //
+            Types<u32V, AIntV>(AInt(u32::Highest()), u32::Highest()),                           //
+            Types<u32V, AIntV>(AInt(u32::Lowest()), u32::Lowest()),                             //
+            Types<f32V, AFloatV>(0.0_a, 0.0),                                                   //
+            Types<f32V, AFloatV>(1.0_a, 1.0),                                                   //
+            Types<f32V, AFloatV>(-1.0_a, -1.0),                                                 //
+            Types<f32V, AFloatV>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32V, AFloatV>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+            /* Types<f16V, AFloatV>(0.0_a, 0.0),                             */                 //
+            /* Types<f16V, AFloatV>(1.0_a, 1.0),                             */                 //
+            /* Types<f16V, AFloatV>(-1.0_a, -1.0),                           */                 //
+            /* Types<f16V, AFloatV>(AFloat(kHighestF16), kHighestF16),       */                 //
+            /* Types<f16V, AFloatV>(AFloat(kLowestF16), kLowestF16),         */                 //
+            /* Types<f16V, AFloatV>(AFloat(kPiF16), kPiF64),                 */                 //
+            /* Types<f16V, AFloatV>(AFloat(kSubnormalF16), kSubnormalF16),   */                 //
+            /* Types<f16V, AFloatV>(AFloat(-kSubnormalF16), -kSubnormalF16), */                 //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeVectorRuntimeIndex,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::Values(Method::kRuntimeIndex),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32V, AIntV>(0_a, 0.0),                                  //
-                         Types<i32V, AIntV>(1_a, 1.0),                                  //
-                         Types<i32V, AIntV>(-1_a, -1.0),                                //
-                         Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32),            //
-                         Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32),              //
-                         Types<f32V, AFloatV>(0.0_a, 0.0),                              //
-                         Types<f32V, AFloatV>(1.0_a, 1.0),                              //
-                         Types<f32V, AFloatV>(-1.0_a, -1.0),                            //
-                         Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::Values(Method::kRuntimeIndex),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32V, AIntV>(0_a, 0.0),                                                       //
+            Types<i32V, AIntV>(1_a, 1.0),                                                       //
+            Types<i32V, AIntV>(-1_a, -1.0),                                                     //
+            Types<i32V, AIntV>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32V, AIntV>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<f32V, AFloatV>(0.0_a, 0.0),                                                   //
+            Types<f32V, AFloatV>(1.0_a, 1.0),                                                   //
+            Types<f32V, AFloatV>(-1.0_a, -1.0),                                                 //
+            Types<f32V, AFloatV>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32V, AFloatV>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeMatrix,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kMatrixMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<f32M, AFloatM>(0.0_a, 0.0),                                    //
-                         Types<f32M, AFloatM>(1.0_a, 1.0),                                    //
-                         Types<f32M, AFloatM>(-1.0_a, -1.0),                                  //
-                         Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32),              //
-                         Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32),                //
-                         Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                        //
-                         Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),          //
-                         Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),        //
-                         /* Types<f16M, AFloatM>(0.0_a, 0.0),                             */  //
-                         /* Types<f16M, AFloatM>(1.0_a, 1.0),                             */  //
-                         /* Types<f16M, AFloatM>(-1.0_a, -1.0),                           */  //
-                         /* Types<f16M, AFloatM>(AFloat(kHighestF16), kHighestF16),       */  //
-                         /* Types<f16M, AFloatM>(AFloat(kLowestF16), kLowestF16),         */  //
-                         /* Types<f16M, AFloatM>(AFloat(kPiF16), kPiF64),                 */  //
-                         /* Types<f16M, AFloatM>(AFloat(kSubnormalF16), kSubnormalF16),   */  //
-                         /* Types<f16M, AFloatM>(AFloat(-kSubnormalF16), -kSubnormalF16), */  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kMatrixMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<f32M, AFloatM>(0.0_a, 0.0),                                                   //
+            Types<f32M, AFloatM>(1.0_a, 1.0),                                                   //
+            Types<f32M, AFloatM>(-1.0_a, -1.0),                                                 //
+            Types<f32M, AFloatM>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32M, AFloatM>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+            /* Types<f16M, AFloatM>(0.0_a, 0.0),                             */                 //
+            /* Types<f16M, AFloatM>(1.0_a, 1.0),                             */                 //
+            /* Types<f16M, AFloatM>(-1.0_a, -1.0),                           */                 //
+            /* Types<f16M, AFloatM>(AFloat(kHighestF16), kHighestF16),       */                 //
+            /* Types<f16M, AFloatM>(AFloat(kLowestF16), kLowestF16),         */                 //
+            /* Types<f16M, AFloatM>(AFloat(kPiF16), kPiF64),                 */                 //
+            /* Types<f16M, AFloatM>(AFloat(kSubnormalF16), kSubnormalF16),   */                 //
+            /* Types<f16M, AFloatM>(AFloat(-kSubnormalF16), -kSubnormalF16), */                 //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeMatrixRuntimeIndex,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::Values(Method::kRuntimeIndex),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<f32M, AFloatM>(0.0_a, 0.0),                              //
-                         Types<f32M, AFloatM>(1.0_a, 1.0),                              //
-                         Types<f32M, AFloatM>(-1.0_a, -1.0),                            //
-                         Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::Values(Method::kRuntimeIndex),
+        testing::ValuesIn(std::vector<Data>{
+            Types<f32M, AFloatM>(0.0_a, 0.0),                                                   //
+            Types<f32M, AFloatM>(1.0_a, 1.0),                                                   //
+            Types<f32M, AFloatM>(-1.0_a, -1.0),                                                 //
+            Types<f32M, AFloatM>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32M, AFloatM>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
-INSTANTIATE_TEST_SUITE_P(MaterializeSwitch,
-                         MaterializeAbstractNumericToConcreteType,
-                         testing::Combine(testing::Values(Expectation::kMaterialize),
-                                          testing::ValuesIn(kSwitchMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, 0.0),                        //
-                                              Types<i32, AInt>(1_a, 1.0),                        //
-                                              Types<i32, AInt>(-1_a, -1.0),                      //
-                                              Types<i32, AInt>(AInt(kHighestI32), kHighestI32),  //
-                                              Types<i32, AInt>(AInt(kLowestI32), kLowestI32),    //
-                                              Types<u32, AInt>(0_a, 0.0),                        //
-                                              Types<u32, AInt>(1_a, 1.0),                        //
-                                              Types<u32, AInt>(AInt(kHighestU32), kHighestU32),  //
-                                              Types<u32, AInt>(AInt(kLowestU32), kLowestU32),    //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    MaterializeSwitch,
+    MaterializeAbstractNumericToConcreteType,
+    testing::Combine(testing::Values(Expectation::kMaterialize),
+                     testing::ValuesIn(kSwitchMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, 0.0),                              //
+                         Types<i32, AInt>(1_a, 1.0),                              //
+                         Types<i32, AInt>(-1_a, -1.0),                            //
+                         Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),  //
+                         Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),    //
+                         Types<u32, AInt>(0_a, 0.0),                              //
+                         Types<u32, AInt>(1_a, 1.0),                              //
+                         Types<u32, AInt>(AInt(u32::Highest()), u32::Highest()),  //
+                         Types<u32, AInt>(AInt(u32::Lowest()), u32::Lowest()),    //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize,
                          MaterializeAbstractNumericToConcreteType,
@@ -637,35 +635,37 @@
                                               Types<i32Varr, AFloatV>(),  //
                                           })));
 
-INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented,
-                         MaterializeAbstractNumericToConcreteType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kScalarMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),        //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),         //
-                                              Types<u32, AInt>(0_a, kHighestU32 + 1),        //
-                                              Types<u32, AInt>(0_a, kLowestU32 - 1),         //
-                                              Types<f32, AFloat>(0.0_a, kTooBigF32),         //
-                                              Types<f32, AFloat>(0.0_a, -kTooBigF32),        //
-                                              /* Types<f16, AFloat>(0.0_a, kTooBigF16),  */  //
-                                              /* Types<f16, AFloat>(0.0_a, -kTooBigF16), */  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    ScalarValueCannotBeRepresented,
+    MaterializeAbstractNumericToConcreteType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kScalarMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<u32, AInt>(0_a, static_cast<double>(u32::kHighestValue) + 1),  //
+                         Types<u32, AInt>(0_a, static_cast<double>(u32::kLowestValue) - 1),   //
+                         Types<f32, AFloat>(0.0_a, kTooBigF32),                               //
+                         Types<f32, AFloat>(0.0_a, -kTooBigF32),                              //
+                         /* Types<f16, AFloat>(0.0_a, kTooBigF16),  */                        //
+                         /* Types<f16, AFloat>(0.0_a, -kTooBigF16), */                        //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented,
-                         MaterializeAbstractNumericToConcreteType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kVectorMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32V, AIntV>(0_a, kHighestI32 + 1),        //
-                                              Types<i32V, AIntV>(0_a, kLowestI32 - 1),         //
-                                              Types<u32V, AIntV>(0_a, kHighestU32 + 1),        //
-                                              Types<u32V, AIntV>(0_a, kLowestU32 - 1),         //
-                                              Types<f32V, AFloatV>(0.0_a, kTooBigF32),         //
-                                              Types<f32V, AFloatV>(0.0_a, -kTooBigF32),        //
-                                              /* Types<f16V, AFloatV>(0.0_a, kTooBigF16),  */  //
-                                              /* Types<f16V, AFloatV>(0.0_a, -kTooBigF16), */  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    VectorValueCannotBeRepresented,
+    MaterializeAbstractNumericToConcreteType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kVectorMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<u32V, AIntV>(0_a, static_cast<double>(u32::kHighestValue) + 1),  //
+                         Types<u32V, AIntV>(0_a, static_cast<double>(u32::kLowestValue) - 1),   //
+                         Types<f32V, AFloatV>(0.0_a, kTooBigF32),                               //
+                         Types<f32V, AFloatV>(0.0_a, -kTooBigF32),                              //
+                         /* Types<f16V, AFloatV>(0.0_a, kTooBigF16),  */                        //
+                         /* Types<f16V, AFloatV>(0.0_a, -kTooBigF16), */                        //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented,
                          MaterializeAbstractNumericToConcreteType,
@@ -898,69 +898,73 @@
 INSTANTIATE_TEST_SUITE_P(
     MaterializeScalar,
     MaterializeAbstractNumericToDefaultType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kScalarMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32, AInt>(0_a, 0.0),                                  //
-                         Types<i32, AInt>(1_a, 1.0),                                  //
-                         Types<i32, AInt>(-1_a, -1.0),                                //
-                         Types<i32, AInt>(AInt(kHighestI32), kHighestI32),            //
-                         Types<i32, AInt>(AInt(kLowestI32), kLowestI32),              //
-                         Types<f32, AFloat>(0.0_a, 0.0),                              //
-                         Types<f32, AFloat>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32, AFloat>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kScalarMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32, AInt>(0_a, 0.0),                                                       //
+            Types<i32, AInt>(1_a, 1.0),                                                       //
+            Types<i32, AInt>(-1_a, -1.0),                                                     //
+            Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<f32, AFloat>(0.0_a, 0.0),                                                   //
+            Types<f32, AFloat>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32, AFloat>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeVector,
     MaterializeAbstractNumericToDefaultType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kVectorMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32V, AIntV>(0_a, 0.0),                                  //
-                         Types<i32V, AIntV>(1_a, 1.0),                                  //
-                         Types<i32V, AIntV>(-1_a, -1.0),                                //
-                         Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32),            //
-                         Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32),              //
-                         Types<f32V, AFloatV>(0.0_a, 0.0),                              //
-                         Types<f32V, AFloatV>(1.0_a, 1.0),                              //
-                         Types<f32V, AFloatV>(-1.0_a, -1.0),                            //
-                         Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kVectorMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32V, AIntV>(0_a, 0.0),                                                       //
+            Types<i32V, AIntV>(1_a, 1.0),                                                       //
+            Types<i32V, AIntV>(-1_a, -1.0),                                                     //
+            Types<i32V, AIntV>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32V, AIntV>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<f32V, AFloatV>(0.0_a, 0.0),                                                   //
+            Types<f32V, AFloatV>(1.0_a, 1.0),                                                   //
+            Types<f32V, AFloatV>(-1.0_a, -1.0),                                                 //
+            Types<f32V, AFloatV>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32V, AFloatV>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeMatrix,
     MaterializeAbstractNumericToDefaultType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kMatrixMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<f32M, AFloatM>(0.0_a, 0.0),                              //
-                         Types<f32M, AFloatM>(1.0_a, 1.0),                              //
-                         Types<f32M, AFloatM>(-1.0_a, -1.0),                            //
-                         Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kMatrixMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<f32M, AFloatM>(0.0_a, 0.0),                                                   //
+            Types<f32M, AFloatM>(1.0_a, 1.0),                                                   //
+            Types<f32M, AFloatM>(-1.0_a, -1.0),                                                 //
+            Types<f32M, AFloatM>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32M, AFloatM>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
-INSTANTIATE_TEST_SUITE_P(MaterializeAInt,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kMaterialize),
-                                          testing::ValuesIn(kAIntMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, 0.0),                        //
-                                              Types<i32, AInt>(10_a, 10.0),                      //
-                                              Types<i32, AInt>(AInt(kHighestI32), kHighestI32),  //
-                                              Types<i32, AInt>(AInt(kLowestI32), kLowestI32),    //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    MaterializeAInt,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kMaterialize),
+                     testing::ValuesIn(kAIntMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, 0.0),                              //
+                         Types<i32, AInt>(10_a, 10.0),                            //
+                         Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),  //
+                         Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),    //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeArrayLength,
@@ -971,7 +975,7 @@
                          Types<i32, AInt>(1_a, 1.0),        //
                          Types<i32, AInt>(10_a, 10.0),      //
                          Types<i32, AInt>(1000_a, 1000.0),  //
-                         // Note: kHighestI32 cannot be used due to max-byte-size validation
+                         // Note: i32::Highest() cannot be used due to max-byte-size validation
                      })));
 
 INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize,
@@ -984,28 +988,30 @@
                                               Types<i32, AInt>(65535_a, 65535.0),  //
                                           })));
 
-INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kScalarMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),   //
-                                              Types<f32, AFloat>(0.0_a, kTooBigF32),   //
-                                              Types<f32, AFloat>(0.0_a, -kTooBigF32),  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    ScalarValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kScalarMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<f32, AFloat>(0.0_a, kTooBigF32),                               //
+                         Types<f32, AFloat>(0.0_a, -kTooBigF32),                              //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kVectorMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32V, AIntV>(0_a, kHighestI32 + 1),  //
-                                              Types<i32V, AIntV>(0_a, kLowestI32 - 1),   //
-                                              Types<i32V, AIntV>(0_a, kHighestU32 + 1),  //
-                                              Types<f32V, AFloatV>(0.0_a, kTooBigF32),   //
-                                              Types<f32V, AFloatV>(0.0_a, -kTooBigF32),  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    VectorValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kVectorMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<i32V, AIntV>(0_a, static_cast<double>(u32::kHighestValue) + 1),  //
+                         Types<f32V, AFloatV>(0.0_a, kTooBigF32),                               //
+                         Types<f32V, AFloatV>(0.0_a, -kTooBigF32),                              //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented,
                          MaterializeAbstractNumericToDefaultType,
@@ -1016,31 +1022,34 @@
                                               Types<f32M, AFloatM>(0.0_a, -kTooBigF32),  //
                                           })));
 
-INSTANTIATE_TEST_SUITE_P(AIntValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kAIntMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),   //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    AIntValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kAIntMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(WorkgroupSizeValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::Values(Method::kWorkgroupSize),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),   //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    WorkgroupSizeValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::Values(Method::kWorkgroupSize),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(ArrayLengthValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::Values(Method::kArrayLength),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    ArrayLengthValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::Values(Method::kArrayLength),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                     })));
 
 }  // namespace materialize_abstract_numeric_to_default_type
 
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index d861acf..b1961c3 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -896,9 +896,8 @@
     }
 
     auto values = attr->Values();
-    std::array<const sem::Expression*, 3> args = {};
-    std::array<const sem::Type*, 3> arg_tys = {};
-    size_t arg_count = 0;
+    utils::Vector<const sem::Expression*, 3> args;
+    utils::Vector<const sem::Type*, 3> arg_tys;
 
     constexpr const char* kErrBadExpr =
         "workgroup_size argument must be either a literal, constant, or overridable of type "
@@ -921,12 +920,11 @@
             return false;
         }
 
-        args[i] = expr;
-        arg_tys[i] = ty;
-        arg_count++;
+        args.Push(expr);
+        arg_tys.Push(ty);
     }
 
-    auto* common_ty = sem::Type::Common(arg_tys.data(), arg_count);
+    auto* common_ty = sem::Type::Common(arg_tys);
     if (!common_ty) {
         AddError("workgroup_size arguments must be of the same type, either i32 or u32",
                  attr->source);
@@ -938,7 +936,7 @@
         common_ty = builder_->create<sem::I32>();
     }
 
-    for (size_t i = 0; i < arg_count; i++) {
+    for (size_t i = 0; i < args.Length(); i++) {
         auto* materialized = Materialize(args[i], common_ty);
         if (!materialized) {
             return false;
@@ -1318,46 +1316,7 @@
     return nullptr;
 }
 
-const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
-                                             const sem::Type* target_type /* = nullptr */) {
-    if (!expr) {
-        return nullptr;  // Allow for Materialize(Expression(blah))
-    }
-
-    // Helper for actually creating the the materialize node, performing the constant cast, updating
-    // the ast -> sem binding, and performing validation.
-    auto materialize = [&](const sem::Type* target_ty) -> sem::Materialize* {
-        auto* src_ty = expr->Type();
-        auto* decl = expr->Declaration();
-        if (!validator_.Materialize(target_ty, src_ty, decl->source)) {
-            return nullptr;
-        }
-        auto expr_val = expr->ConstantValue();
-        if (!expr_val) {
-            TINT_ICE(Resolver, builder_->Diagnostics())
-                << decl->source << "Materialize(" << decl->TypeInfo().name
-                << ") called on expression with no constant value";
-            return nullptr;
-        }
-        auto materialized_val = const_eval_.Convert(target_ty, expr_val, decl->source);
-        if (!materialized_val) {
-            // ConvertValue() has already failed and raised an diagnostic error.
-            return nullptr;
-        }
-        if (!materialized_val.Get()) {
-            TINT_ICE(Resolver, builder_->Diagnostics())
-                << decl->source << "ConvertValue(" << builder_->FriendlyName(expr_val->Type())
-                << " -> " << builder_->FriendlyName(target_ty) << ") returned invalid value";
-            return nullptr;
-        }
-        auto* m =
-            builder_->create<sem::Materialize>(expr, current_statement_, materialized_val.Get());
-        m->Behaviors() = expr->Behaviors();
-        builder_->Sem().Replace(decl, m);
-        return m;
-    };
-
-    // Helpers for constructing semantic types
+const sem::Type* Resolver::ConcreteType(const sem::Type* ty, const sem::Type* target_ty) {
     auto i32 = [&] { return builder_->create<sem::I32>(); };
     auto f32 = [&] { return builder_->create<sem::F32>(); };
     auto i32v = [&](uint32_t width) { return builder_->create<sem::Vector>(i32(), width); };
@@ -1366,31 +1325,69 @@
         return builder_->create<sem::Matrix>(f32v(rows), columns);
     };
 
-    // Type dispatch based on the expression type
-    return Switch<sem::Expression*>(
-        expr->Type(),  //
-        [&](const sem::AbstractInt*) { return materialize(target_type ? target_type : i32()); },
-        [&](const sem::AbstractFloat*) { return materialize(target_type ? target_type : f32()); },
+    return Switch(
+        ty,  //
+        [&](const sem::AbstractInt*) { return target_ty ? target_ty : i32(); },
+        [&](const sem::AbstractFloat*) { return target_ty ? target_ty : f32(); },
         [&](const sem::Vector* v) {
             return Switch(
                 v->type(),  //
-                [&](const sem::AbstractInt*) {
-                    return materialize(target_type ? target_type : i32v(v->Width()));
-                },
+                [&](const sem::AbstractInt*) { return target_ty ? target_ty : i32v(v->Width()); },
                 [&](const sem::AbstractFloat*) {
-                    return materialize(target_type ? target_type : f32v(v->Width()));
-                },
-                [&](Default) { return expr; });
+                    return target_ty ? target_ty : f32v(v->Width());
+                });
         },
         [&](const sem::Matrix* m) {
-            return Switch(
-                m->type(),  //
-                [&](const sem::AbstractFloat*) {
-                    return materialize(target_type ? target_type : f32m(m->columns(), m->rows()));
-                },
-                [&](Default) { return expr; });
-        },
-        [&](Default) { return expr; });
+            return Switch(m->type(),  //
+                          [&](const sem::AbstractFloat*) {
+                              return target_ty ? target_ty : f32m(m->columns(), m->rows());
+                          });
+        });
+}
+
+const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
+                                             const sem::Type* target_type /* = nullptr */) {
+    if (!expr) {
+        // Allow for Materialize(Expression(blah)), where failures pass through Materialize()
+        return nullptr;
+    }
+
+    auto* decl = expr->Declaration();
+
+    auto* concrete_ty = ConcreteType(expr->Type(), target_type);
+    if (!concrete_ty) {
+        return expr;  // Does not require materialization
+    }
+
+    auto* src_ty = expr->Type();
+    if (!validator_.Materialize(concrete_ty, src_ty, decl->source)) {
+        return nullptr;
+    }
+
+    auto expr_val = expr->ConstantValue();
+    if (!expr_val) {
+        TINT_ICE(Resolver, builder_->Diagnostics())
+            << decl->source << "Materialize(" << decl->TypeInfo().name
+            << ") called on expression with no constant value";
+        return nullptr;
+    }
+
+    auto materialized_val = const_eval_.Convert(concrete_ty, expr_val, decl->source);
+    if (!materialized_val) {
+        // ConvertValue() has already failed and raised an diagnostic error.
+        return nullptr;
+    }
+
+    if (!materialized_val.Get()) {
+        TINT_ICE(Resolver, builder_->Diagnostics())
+            << decl->source << "ConvertValue(" << builder_->FriendlyName(expr_val->Type()) << " -> "
+            << builder_->FriendlyName(concrete_ty) << ") returned invalid value";
+        return nullptr;
+    }
+    auto* m = builder_->create<sem::Materialize>(expr, current_statement_, materialized_val.Get());
+    m->Behaviors() = expr->Behaviors();
+    builder_->Sem().Replace(decl, m);
+    return m;
 }
 
 bool Resolver::MaterializeArguments(utils::VectorRef<const sem::Expression*> args,
@@ -2577,8 +2574,8 @@
 
         auto* cond_ty = cond->Type()->UnwrapRef();
 
-        utils::UniqueVector<const sem::Type*> types;
-        types.add(cond_ty);
+        utils::Vector<const sem::Type*, 8> types;
+        types.Push(cond_ty);
 
         std::vector<sem::CaseStatement*> cases;
         cases.reserve(stmt->body.size());
@@ -2589,7 +2586,7 @@
                 return false;
             }
             for (auto* expr : c->Selectors()) {
-                types.add(expr->Type()->UnwrapRef());
+                types.Push(expr->Type()->UnwrapRef());
             }
             cases.emplace_back(c);
             behaviors.Add(c->Behaviors());
@@ -2598,7 +2595,7 @@
 
         // Determine the common type across all selectors and the switch expression
         // This must materialize to an integer scalar (non-abstract).
-        auto* common_ty = sem::Type::Common(types.data(), types.size());
+        auto* common_ty = sem::Type::Common(types);
         if (!common_ty || !common_ty->is_integer_scalar()) {
             // No common type found or the common type was abstract.
             // Pick i32 and let validation deal with any mismatches.
@@ -2806,7 +2803,7 @@
         str->AddUsage(sc);
 
         for (auto* member : str->Members()) {
-            if (!ApplyStorageClassUsageToType(sc, member->Type(), usage)) {
+            if (!ApplyStorageClassUsageToType(sc, const_cast<sem::Type*>(member->Type()), usage)) {
                 std::stringstream err;
                 err << "while analysing structure member " << sem_.TypeNameOf(str) << "."
                     << builder_->Symbols().NameFor(member->Declaration()->symbol);
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index ccfaf6c..ccd3895 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -230,6 +230,13 @@
     /// `parameter_ty` should be materialized.
     bool ShouldMaterializeArgument(const sem::Type* parameter_ty) const;
 
+    /// @param ty the type that may hold abstract numeric types
+    /// @param target_ty the target type for the expression (variable type, parameter type, etc).
+    ///        May be nullptr.
+    /// @returns the concrete (materialized) type for the given type, or nullptr if the type is
+    ///          already concrete.
+    const sem::Type* ConcreteType(const sem::Type* ty, const sem::Type* target_ty);
+
     // Statement resolving methods
     // Each return true on success, false on failure.
     sem::Statement* AssignmentStatement(const ast::AssignmentStatement*);
diff --git a/src/tint/sem/struct.cc b/src/tint/sem/struct.cc
index eb0583b..0ace9db 100644
--- a/src/tint/sem/struct.cc
+++ b/src/tint/sem/struct.cc
@@ -157,7 +157,7 @@
 
 StructMember::StructMember(const ast::StructMember* declaration,
                            Symbol name,
-                           sem::Type* type,
+                           const sem::Type* type,
                            uint32_t index,
                            uint32_t offset,
                            uint32_t align,
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index 5ee93e5..62b1008 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -182,7 +182,7 @@
     /// @param size the byte size of the member
     StructMember(const ast::StructMember* declaration,
                  Symbol name,
-                 sem::Type* type,
+                 const sem::Type* type,
                  uint32_t index,
                  uint32_t offset,
                  uint32_t align,
@@ -205,7 +205,7 @@
     const sem::Struct* Struct() const { return struct_; }
 
     /// @returns the type of the member
-    sem::Type* Type() const { return type_; }
+    const sem::Type* Type() const { return type_; }
 
     /// @returns the member index
     uint32_t Index() const { return index_; }
@@ -223,7 +223,7 @@
     const ast::StructMember* const declaration_;
     const Symbol name_;
     const sem::Struct* struct_;
-    sem::Type* const type_;
+    const sem::Type* type_;
     const uint32_t index_;
     const uint32_t offset_;
     const uint32_t align_;
diff --git a/src/tint/sem/type.cc b/src/tint/sem/type.cc
index 5b2baa0..fcc1654 100644
--- a/src/tint/sem/type.cc
+++ b/src/tint/sem/type.cc
@@ -68,19 +68,15 @@
 }
 
 bool Type::is_scalar() const {
-    return IsAnyOf<F16, F32, U32, I32, Bool>();
-}
-
-bool Type::is_abstract_or_scalar() const {
-    return IsAnyOf<F16, F32, U32, I32, Bool, AbstractNumeric>();
+    return IsAnyOf<F16, F32, U32, I32, AbstractNumeric, Bool>();
 }
 
 bool Type::is_numeric_scalar() const {
-    return IsAnyOf<F16, F32, U32, I32>();
+    return IsAnyOf<F16, F32, U32, I32, AbstractNumeric>();
 }
 
 bool Type::is_float_scalar() const {
-    return IsAnyOf<F16, F32>();
+    return IsAnyOf<F16, F32, AbstractNumeric>();
 }
 
 bool Type::is_float_matrix() const {
@@ -117,7 +113,7 @@
 }
 
 bool Type::is_signed_integer_vector() const {
-    return Is([](const Vector* v) { return v->type()->Is<I32>(); });
+    return Is([](const Vector* v) { return v->type()->IsAnyOf<I32>(); });
 }
 
 bool Type::is_unsigned_integer_vector() const {
@@ -136,10 +132,6 @@
     return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector();
 }
 
-bool Type::is_abstract_scalar_vector() const {
-    return Is([](const Vector* v) { return v->type()->Is<sem::AbstractNumeric>(); });
-}
-
 bool Type::is_abstract_integer_vector() const {
     return Is([](const Vector* v) { return v->type()->Is<sem::AbstractInt>(); });
 }
@@ -148,10 +140,6 @@
     return Is([](const Vector* v) { return v->type()->Is<sem::AbstractFloat>(); });
 }
 
-bool Type::is_abstract_scalar_or_vector() const {
-    return Is<sem::AbstractNumeric>() || is_abstract_scalar_vector();
-}
-
 bool Type::is_abstract_integer_scalar_or_vector() const {
     return Is<sem::AbstractInt>() || is_abstract_integer_vector();
 }
@@ -224,11 +212,19 @@
             }
             return kNoConversion;
         },
+        [&](const Array* from_arr) {
+            if (auto* to_arr = to->As<Array>()) {
+                if (from_arr->Count() == to_arr->Count()) {
+                    return ConversionRank(from_arr->ElemType(), to_arr->ElemType());
+                }
+            }
+            return kNoConversion;
+        },
         [&](Default) { return kNoConversion; });
 }
 
 const Type* Type::ElementOf(const Type* ty, uint32_t* count /* = nullptr */) {
-    if (ty->is_abstract_or_scalar()) {
+    if (ty->is_scalar()) {
         if (count) {
             *count = 1;
         }
@@ -276,7 +272,8 @@
     return el_ty;
 }
 
-const sem::Type* Type::Common(Type const* const* types, size_t count) {
+const sem::Type* Type::Common(utils::ConstVectorRef<const Type*> types) {
+    const auto count = types.Length();
     if (count == 0) {
         return nullptr;
     }
diff --git a/src/tint/sem/type.h b/src/tint/sem/type.h
index 3866e8d..c2b83e5 100644
--- a/src/tint/sem/type.h
+++ b/src/tint/sem/type.h
@@ -19,6 +19,7 @@
 #include <string>
 
 #include "src/tint/sem/node.h"
+#include "src/tint/utils/vector.h"
 
 // Forward declarations
 namespace tint {
@@ -71,8 +72,6 @@
 
     /// @returns true if this type is a scalar
     bool is_scalar() const;
-    /// @returns true if this type is a scalar or an abstract numeric
-    bool is_abstract_or_scalar() const;
     /// @returns true if this type is a numeric scalar
     bool is_numeric_scalar() const;
     /// @returns true if this type is a float scalar
@@ -103,14 +102,10 @@
     bool is_signed_scalar_or_vector() const;
     /// @returns true if this type is an integer scalar or vector
     bool is_integer_scalar_or_vector() const;
-    /// @returns true if this type is an abstract scalar vector
-    bool is_abstract_scalar_vector() const;
     /// @returns true if this type is an abstract integer vector
     bool is_abstract_integer_vector() const;
     /// @returns true if this type is an abstract float vector
     bool is_abstract_float_vector() const;
-    /// @returns true if this type is an abstract scalar or vector
-    bool is_abstract_scalar_or_vector() const;
     /// @returns true if this type is an abstract integer scalar or vector
     bool is_abstract_integer_scalar_or_vector() const;
     /// @returns true if this type is an abstract float scalar or vector
@@ -162,20 +157,11 @@
     ///   * `nullptr` if `ty` is none of the above
     static const Type* DeepestElementOf(const Type* ty, uint32_t* count = nullptr);
 
-    /// @param types a pointer to a list of `const Type*`.
-    /// @param count the number of types in `types`.
+    /// @param types the list of types
     /// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
-    /// or nullptr if there is no consistent common type across all types in `types`.
+    ///          or nullptr if there is no consistent common type across all types in `types`.
     /// @see https://www.w3.org/TR/WGSL/#conversion-rank
-    static const sem::Type* Common(Type const* const* types, size_t count);
-
-    /// @param types an initializer_list of `const Type*`.
-    /// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
-    /// or nullptr if there is no consistent common type across all types in `types`.
-    /// @see https://www.w3.org/TR/WGSL/#conversion-rank
-    static const sem::Type* Common(std::initializer_list<const Type*> types) {
-        return Common(types.begin(), types.size());
-    }
+    static const sem::Type* Common(utils::ConstVectorRef<const Type*> types);
 
   protected:
     Type();
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index 8458880..837579e 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -14,34 +14,110 @@
 
 #include "src/tint/sem/abstract_float.h"
 #include "src/tint/sem/abstract_int.h"
+#include "src/tint/sem/f16.h"
 #include "src/tint/sem/reference.h"
 #include "src/tint/sem/test_helper.h"
 
 namespace tint::sem {
 namespace {
 
-using TypeTest = TestHelper;
+struct TypeTest : public TestHelper {
+    const sem::AbstractFloat* af = create<AbstractFloat>();
+    const sem::AbstractInt* ai = create<AbstractInt>();
+    const sem::F32* f32 = create<F32>();
+    const sem::F16* f16 = create<F16>();
+    const sem::I32* i32 = create<I32>();
+    const sem::U32* u32 = create<U32>();
+    const sem::Vector* vec2_f32 = create<Vector>(f32, 2u);
+    const sem::Vector* vec3_f32 = create<Vector>(f32, 3u);
+    const sem::Vector* vec3_f16 = create<Vector>(f16, 3u);
+    const sem::Vector* vec4_f32 = create<Vector>(f32, 4u);
+    const sem::Vector* vec3_u32 = create<Vector>(u32, 3u);
+    const sem::Vector* vec3_i32 = create<Vector>(i32, 3u);
+    const sem::Vector* vec3_af = create<Vector>(af, 3u);
+    const sem::Vector* vec3_ai = create<Vector>(ai, 3u);
+    const sem::Matrix* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
+    const sem::Matrix* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
+    const sem::Matrix* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
+    const sem::Matrix* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
+    const sem::Matrix* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+    const sem::Matrix* mat4x3_af = create<Matrix>(vec3_af, 4u);
+    const sem::Reference* ref_u32 =
+        create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
+    const sem::Struct* str = create<Struct>(nullptr,
+                                            Sym("s"),
+                                            StructMemberList{
+                                                create<StructMember>(
+                                                    /* declaration */ nullptr,
+                                                    /* name */ Sym("x"),
+                                                    /* type */ f16,
+                                                    /* index */ 0u,
+                                                    /* offset */ 0u,
+                                                    /* align */ 4u,
+                                                    /* size */ 4u),
+                                            },
+                                            /* align*/ 4u,
+                                            /* size*/ 4u,
+                                            /* size_no_padding*/ 4u);
+    const sem::Array* arr_i32 = create<Array>(
+        /* element */ i32,
+        /* count */ 5u,
+        /* align */ 4u,
+        /* size */ 5u * 4u,
+        /* stride */ 5u * 4u,
+        /* implicit_stride */ 5u * 4u);
+    const sem::Array* arr_ai = create<Array>(
+        /* element */ ai,
+        /* count */ 5u,
+        /* align */ 4u,
+        /* size */ 5u * 4u,
+        /* stride */ 5u * 4u,
+        /* implicit_stride */ 5u * 4u);
+    const sem::Array* arr_vec3_i32 = create<Array>(
+        /* element */ vec3_i32,
+        /* count */ 5u,
+        /* align */ 16u,
+        /* size */ 5u * 16u,
+        /* stride */ 5u * 16u,
+        /* implicit_stride */ 5u * 16u);
+    const sem::Array* arr_vec3_ai = create<Array>(
+        /* element */ vec3_ai,
+        /* count */ 5u,
+        /* align */ 16u,
+        /* size */ 5u * 16u,
+        /* stride */ 5u * 16u,
+        /* implicit_stride */ 5u * 16u);
+    const sem::Array* arr_mat4x3_f16 = create<Array>(
+        /* element */ mat4x3_f16,
+        /* count */ 5u,
+        /* align */ 32u,
+        /* size */ 5u * 32u,
+        /* stride */ 5u * 32u,
+        /* implicit_stride */ 5u * 32u);
+    const sem::Array* arr_mat4x3_f32 = create<Array>(
+        /* element */ mat4x3_f32,
+        /* count */ 5u,
+        /* align */ 64u,
+        /* size */ 5u * 64u,
+        /* stride */ 5u * 64u,
+        /* implicit_stride */ 5u * 64u);
+    const sem::Array* arr_mat4x3_af = create<Array>(
+        /* element */ mat4x3_af,
+        /* count */ 5u,
+        /* align */ 64u,
+        /* size */ 5u * 64u,
+        /* stride */ 5u * 64u,
+        /* implicit_stride */ 5u * 64u);
+    const sem::Array* arr_str = create<Array>(
+        /* element */ str,
+        /* count */ 5u,
+        /* align */ 4u,
+        /* size */ 5u * 4u,
+        /* stride */ 5u * 4u,
+        /* implicit_stride */ 5u * 4u);
+};
 
 TEST_F(TypeTest, ConversionRank) {
-    auto* af = create<AbstractFloat>();
-    auto* ai = create<AbstractInt>();
-    auto* f32 = create<F32>();
-    auto* f16 = create<F16>();
-    auto* i32 = create<I32>();
-    auto* u32 = create<U32>();
-    auto* vec3_f32 = create<Vector>(f32, 3u);
-    auto* vec3_f16 = create<Vector>(f16, 3u);
-    auto* vec4_f32 = create<Vector>(f32, 4u);
-    auto* vec3_u32 = create<Vector>(u32, 3u);
-    auto* vec3_i32 = create<Vector>(i32, 3u);
-    auto* vec3_af = create<Vector>(af, 3u);
-    auto* vec3_ai = create<Vector>(ai, 3u);
-    auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
-    auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
-    auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
-    auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
-    auto* ref_u32 = create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-
     EXPECT_EQ(Type::ConversionRank(i32, i32), 0u);
     EXPECT_EQ(Type::ConversionRank(f32, f32), 0u);
     EXPECT_EQ(Type::ConversionRank(u32, u32), 0u);
@@ -55,17 +131,24 @@
     EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat3x4_f32), 0u);
     EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_f32), 0u);
     EXPECT_EQ(Type::ConversionRank(mat4x3_f16, mat4x3_f16), 0u);
+    EXPECT_EQ(Type::ConversionRank(arr_vec3_ai, arr_vec3_ai), 0u);
+    EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f16, arr_mat4x3_f16), 0u);
     EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_af), 0u);
+    EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_af), 0u);
     EXPECT_EQ(Type::ConversionRank(ref_u32, u32), 0u);
 
     EXPECT_EQ(Type::ConversionRank(af, f32), 1u);
     EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f32), 1u);
     EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f32), 1u);
+    EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_f32), 1u);
     EXPECT_EQ(Type::ConversionRank(af, f16), 2u);
     EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f16), 2u);
     EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f16), 2u);
+    EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_f16), 2u);
     EXPECT_EQ(Type::ConversionRank(ai, i32), 3u);
     EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_i32), 3u);
+    EXPECT_EQ(Type::ConversionRank(arr_ai, arr_i32), 3u);
+    EXPECT_EQ(Type::ConversionRank(arr_vec3_ai, arr_vec3_i32), 3u);
     EXPECT_EQ(Type::ConversionRank(ai, u32), 4u);
     EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_u32), 4u);
     EXPECT_EQ(Type::ConversionRank(ai, af), 5u);
@@ -80,6 +163,9 @@
     EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat4x3_f32), Type::kNoConversion);
     EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat3x4_f32), Type::kNoConversion);
     EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_af), Type::kNoConversion);
+    EXPECT_EQ(Type::ConversionRank(arr_vec3_i32, arr_vec3_ai), Type::kNoConversion);
+    EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f32, arr_mat4x3_af), Type::kNoConversion);
+    EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f16, arr_mat4x3_f32), Type::kNoConversion);
     EXPECT_EQ(Type::ConversionRank(f32, af), Type::kNoConversion);
     EXPECT_EQ(Type::ConversionRank(f16, af), Type::kNoConversion);
     EXPECT_EQ(Type::ConversionRank(vec3_f16, vec3_af), Type::kNoConversion);
@@ -92,61 +178,6 @@
 }
 
 TEST_F(TypeTest, ElementOf) {
-    auto* f32 = create<F32>();
-    auto* f16 = create<F16>();
-    auto* i32 = create<I32>();
-    auto* u32 = create<U32>();
-    auto* vec2_f32 = create<Vector>(f32, 2u);
-    auto* vec3_f16 = create<Vector>(f16, 3u);
-    auto* vec4_f32 = create<Vector>(f32, 4u);
-    auto* vec3_u32 = create<Vector>(u32, 3u);
-    auto* vec3_i32 = create<Vector>(i32, 3u);
-    auto* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
-    auto* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
-    auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
-    auto* str = create<Struct>(nullptr, Sym("s"),
-                               StructMemberList{
-                                   create<StructMember>(
-                                       /* declaration */ nullptr,
-                                       /* name */ Sym("x"),
-                                       /* type */ f16,
-                                       /* index */ 0u,
-                                       /* offset */ 0u,
-                                       /* align */ 4u,
-                                       /* size */ 4u),
-                               },
-                               /* align*/ 4u,
-                               /* size*/ 4u,
-                               /* size_no_padding*/ 4u);
-    auto* arr_i32 = create<Array>(
-        /* element */ i32,
-        /* count */ 5u,
-        /* align */ 4u,
-        /* size */ 5u * 4u,
-        /* stride */ 5u * 4u,
-        /* implicit_stride */ 5u * 4u);
-    auto* arr_vec3_i32 = create<Array>(
-        /* element */ vec3_i32,
-        /* count */ 5u,
-        /* align */ 16u,
-        /* size */ 5u * 16u,
-        /* stride */ 5u * 16u,
-        /* implicit_stride */ 5u * 16u);
-    auto* arr_mat4x3_f16 = create<Array>(
-        /* element */ mat4x3_f16,
-        /* count */ 5u,
-        /* align */ 64u,
-        /* size */ 5u * 64u,
-        /* stride */ 5u * 64u,
-        /* implicit_stride */ 5u * 64u);
-    auto* arr_str = create<Array>(
-        /* element */ str,
-        /* count */ 5u,
-        /* align */ 4u,
-        /* size */ 5u * 4u,
-        /* stride */ 5u * 4u,
-        /* implicit_stride */ 5u * 4u);
-
     // No count
     EXPECT_TYPE(Type::ElementOf(f32), f32);
     EXPECT_TYPE(Type::ElementOf(f16), f16);
@@ -164,6 +195,7 @@
     EXPECT_TYPE(Type::ElementOf(arr_i32), i32);
     EXPECT_TYPE(Type::ElementOf(arr_vec3_i32), vec3_i32);
     EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16), mat4x3_f16);
+    EXPECT_TYPE(Type::ElementOf(arr_mat4x3_af), mat4x3_af);
     EXPECT_TYPE(Type::ElementOf(arr_str), str);
 
     // With count
@@ -216,66 +248,14 @@
     EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16, &count), mat4x3_f16);
     EXPECT_EQ(count, 5u);
     count = 42;
+    EXPECT_TYPE(Type::ElementOf(arr_mat4x3_af, &count), mat4x3_af);
+    EXPECT_EQ(count, 5u);
+    count = 42;
     EXPECT_TYPE(Type::ElementOf(arr_str, &count), str);
     EXPECT_EQ(count, 5u);
 }
 
 TEST_F(TypeTest, DeepestElementOf) {
-    auto* f32 = create<F32>();
-    auto* f16 = create<F16>();
-    auto* i32 = create<I32>();
-    auto* u32 = create<U32>();
-    auto* vec2_f32 = create<Vector>(f32, 2u);
-    auto* vec3_f16 = create<Vector>(f16, 3u);
-    auto* vec4_f32 = create<Vector>(f32, 4u);
-    auto* vec3_u32 = create<Vector>(u32, 3u);
-    auto* vec3_i32 = create<Vector>(i32, 3u);
-    auto* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
-    auto* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
-    auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
-    auto* str = create<Struct>(nullptr, Sym("s"),
-                               StructMemberList{
-                                   create<StructMember>(
-                                       /* declaration */ nullptr,
-                                       /* name */ Sym("x"),
-                                       /* type */ f16,
-                                       /* index */ 0u,
-                                       /* offset */ 0u,
-                                       /* align */ 4u,
-                                       /* size */ 4u),
-                               },
-                               /* align*/ 4u,
-                               /* size*/ 4u,
-                               /* size_no_padding*/ 4u);
-    auto* arr_i32 = create<Array>(
-        /* element */ i32,
-        /* count */ 5u,
-        /* align */ 4u,
-        /* size */ 5u * 4u,
-        /* stride */ 5u * 4u,
-        /* implicit_stride */ 5u * 4u);
-    auto* arr_vec3_i32 = create<Array>(
-        /* element */ vec3_i32,
-        /* count */ 5u,
-        /* align */ 16u,
-        /* size */ 5u * 16u,
-        /* stride */ 5u * 16u,
-        /* implicit_stride */ 5u * 16u);
-    auto* arr_mat4x3_f16 = create<Array>(
-        /* element */ mat4x3_f16,
-        /* count */ 5u,
-        /* align */ 64u,
-        /* size */ 5u * 64u,
-        /* stride */ 5u * 64u,
-        /* implicit_stride */ 5u * 64u);
-    auto* arr_str = create<Array>(
-        /* element */ str,
-        /* count */ 5u,
-        /* align */ 4u,
-        /* size */ 5u * 4u,
-        /* stride */ 5u * 4u,
-        /* implicit_stride */ 5u * 4u);
-
     // No count
     EXPECT_TYPE(Type::DeepestElementOf(f32), f32);
     EXPECT_TYPE(Type::DeepestElementOf(f16), f16);
@@ -293,6 +273,7 @@
     EXPECT_TYPE(Type::DeepestElementOf(arr_i32), i32);
     EXPECT_TYPE(Type::DeepestElementOf(arr_vec3_i32), i32);
     EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16), f16);
+    EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_af), af);
     EXPECT_TYPE(Type::DeepestElementOf(arr_str), nullptr);
 
     // With count
@@ -345,228 +326,202 @@
     EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16, &count), f16);
     EXPECT_EQ(count, 60u);
     count = 42;
+    EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_af, &count), af);
+    EXPECT_EQ(count, 60u);
+    count = 42;
     EXPECT_TYPE(Type::DeepestElementOf(arr_str, &count), nullptr);
     EXPECT_EQ(count, 0u);
 }
 
 TEST_F(TypeTest, Common2) {
-    auto* ai = create<AbstractInt>();
-    auto* af = create<AbstractFloat>();
-    auto* f32 = create<F32>();
-    auto* f16 = create<F16>();
-    auto* i32 = create<I32>();
-    auto* u32 = create<U32>();
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, ai}), ai);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, af}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, i32}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, u32}), u32);
 
-    EXPECT_TYPE(Type::Common({ai, ai}), ai);
-    EXPECT_TYPE(Type::Common({af, af}), af);
-    EXPECT_TYPE(Type::Common({f32, f32}), f32);
-    EXPECT_TYPE(Type::Common({f16, f16}), f16);
-    EXPECT_TYPE(Type::Common({i32, i32}), i32);
-    EXPECT_TYPE(Type::Common({u32, u32}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, f16}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, i32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({i32, u32}), nullptr);
-    EXPECT_TYPE(Type::Common({u32, f32}), nullptr);
-    EXPECT_TYPE(Type::Common({f32, f16}), nullptr);
-    EXPECT_TYPE(Type::Common({f16, i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, i32}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, u32}), u32);
 
-    EXPECT_TYPE(Type::Common({ai, af}), af);
-    EXPECT_TYPE(Type::Common({ai, f32}), f32);
-    EXPECT_TYPE(Type::Common({ai, f16}), f16);
-    EXPECT_TYPE(Type::Common({ai, i32}), i32);
-    EXPECT_TYPE(Type::Common({ai, u32}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, ai}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, ai}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, ai}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, ai}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, ai}), u32);
 
-    EXPECT_TYPE(Type::Common({af, ai}), af);
-    EXPECT_TYPE(Type::Common({f32, ai}), f32);
-    EXPECT_TYPE(Type::Common({f16, ai}), f16);
-    EXPECT_TYPE(Type::Common({i32, ai}), i32);
-    EXPECT_TYPE(Type::Common({u32, ai}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, af}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, af}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, af}), nullptr);
 
-    EXPECT_TYPE(Type::Common({ai, af}), af);
-    EXPECT_TYPE(Type::Common({f32, af}), f32);
-    EXPECT_TYPE(Type::Common({f16, af}), f16);
-    EXPECT_TYPE(Type::Common({i32, af}), nullptr);
-    EXPECT_TYPE(Type::Common({u32, af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, ai}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, u32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({af, ai}), af);
-    EXPECT_TYPE(Type::Common({af, f32}), f32);
-    EXPECT_TYPE(Type::Common({af, f16}), f16);
-    EXPECT_TYPE(Type::Common({af, i32}), nullptr);
-    EXPECT_TYPE(Type::Common({af, u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai}), vec3_ai);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af}), vec3_af);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec4_f32}), vec4_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_u32}), vec3_u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_i32}), vec3_i32);
 
-    auto* vec3_ai = create<Vector>(ai, 3u);
-    auto* vec3_af = create<Vector>(af, 3u);
-    auto* vec3_f32 = create<Vector>(f32, 3u);
-    auto* vec3_f16 = create<Vector>(f16, 3u);
-    auto* vec4_f32 = create<Vector>(f32, 4u);
-    auto* vec3_u32 = create<Vector>(u32, 3u);
-    auto* vec3_i32 = create<Vector>(i32, 3u);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_u32}), vec3_u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_i32}), vec3_i32);
 
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_ai}), vec3_ai);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_af}), vec3_af);
-    EXPECT_TYPE(Type::Common({vec3_f32, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_f16, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec4_f32, vec4_f32}), vec4_f32);
-    EXPECT_TYPE(Type::Common({vec3_u32, vec3_u32}), vec3_u32);
-    EXPECT_TYPE(Type::Common({vec3_i32, vec3_i32}), vec3_i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_ai}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_ai}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_ai}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_ai}), vec3_u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_ai}), vec3_i32);
 
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_u32}), vec3_u32);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_i32}), vec3_i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_i32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({vec3_f32, vec3_ai}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_f16, vec3_ai}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec4_f32, vec3_ai}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_u32, vec3_ai}), vec3_u32);
-    EXPECT_TYPE(Type::Common({vec3_i32, vec3_ai}), vec3_i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_af}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_af}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af}), nullptr);
 
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec3_af, vec4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_u32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af}), mat4x3_af);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32}), mat3x4_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32}), mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_f16}), mat4x3_f16);
 
-    EXPECT_TYPE(Type::Common({vec3_f32, vec3_af}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_f16, vec3_af}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec4_f32, vec3_af}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_u32, vec3_af}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_i32, vec3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32}), mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16}), mat4x3_f16);
 
-    auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
-    auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
-    auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
-    auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af}), mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af}), mat4x3_f16);
 
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_af}), mat4x3_af);
-    EXPECT_TYPE(Type::Common({mat3x4_f32, mat3x4_f32}), mat3x4_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_f32}), mat4x3_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_f16}), mat4x3_f16);
-
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat3x4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f32}), mat4x3_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f16}), mat4x3_f16);
-
-    EXPECT_TYPE(Type::Common({mat3x4_f32, mat4x3_af}), nullptr);
-    EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_af}), mat4x3_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_af}), mat4x3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f32, arr_mat4x3_f16}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f32, arr_mat4x3_af}), arr_mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f16, arr_mat4x3_af}), arr_mat4x3_f16);
 }
 
 TEST_F(TypeTest, Common3) {
-    auto* ai = create<AbstractInt>();
-    auto* af = create<AbstractFloat>();
-    auto* f32 = create<F32>();
-    auto* f16 = create<F16>();
-    auto* i32 = create<I32>();
-    auto* u32 = create<U32>();
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, ai, ai}), ai);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, af, af}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, f32, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, f16, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, i32, i32}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, u32, u32}), u32);
 
-    EXPECT_TYPE(Type::Common({ai, ai, ai}), ai);
-    EXPECT_TYPE(Type::Common({af, af, af}), af);
-    EXPECT_TYPE(Type::Common({f32, f32, f32}), f32);
-    EXPECT_TYPE(Type::Common({f16, f16, f16}), f16);
-    EXPECT_TYPE(Type::Common({i32, i32, i32}), i32);
-    EXPECT_TYPE(Type::Common({u32, u32, u32}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af, ai}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, f32, ai}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, f16, ai}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, i32, ai}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, u32, ai}), u32);
 
-    EXPECT_TYPE(Type::Common({ai, af, ai}), af);
-    EXPECT_TYPE(Type::Common({ai, f32, ai}), f32);
-    EXPECT_TYPE(Type::Common({ai, f16, ai}), f16);
-    EXPECT_TYPE(Type::Common({ai, i32, ai}), i32);
-    EXPECT_TYPE(Type::Common({ai, u32, ai}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, ai, af}), af);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, ai, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, ai, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, ai, i32}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, ai, u32}), u32);
 
-    EXPECT_TYPE(Type::Common({af, ai, af}), af);
-    EXPECT_TYPE(Type::Common({f32, ai, f32}), f32);
-    EXPECT_TYPE(Type::Common({f16, ai, f16}), f16);
-    EXPECT_TYPE(Type::Common({i32, ai, i32}), i32);
-    EXPECT_TYPE(Type::Common({u32, ai, u32}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, f32, ai}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, f16, ai}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, i32, ai}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, u32, ai}), u32);
 
-    EXPECT_TYPE(Type::Common({ai, f32, ai}), f32);
-    EXPECT_TYPE(Type::Common({ai, f16, ai}), f16);
-    EXPECT_TYPE(Type::Common({ai, i32, ai}), i32);
-    EXPECT_TYPE(Type::Common({ai, u32, ai}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, ai, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, ai, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, ai, i32}), i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, ai, u32}), u32);
 
-    EXPECT_TYPE(Type::Common({f32, ai, f32}), f32);
-    EXPECT_TYPE(Type::Common({f16, ai, f16}), f16);
-    EXPECT_TYPE(Type::Common({i32, ai, i32}), i32);
-    EXPECT_TYPE(Type::Common({u32, ai, u32}), u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, f32, af}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, f16, af}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, i32, af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{af, u32, af}), nullptr);
 
-    EXPECT_TYPE(Type::Common({af, f32, af}), f32);
-    EXPECT_TYPE(Type::Common({af, f16, af}), f16);
-    EXPECT_TYPE(Type::Common({af, i32, af}), nullptr);
-    EXPECT_TYPE(Type::Common({af, u32, af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{f32, af, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{f16, af, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{i32, af, i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{u32, af, u32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({f32, af, f32}), f32);
-    EXPECT_TYPE(Type::Common({f16, af, f16}), f16);
-    EXPECT_TYPE(Type::Common({i32, af, i32}), nullptr);
-    EXPECT_TYPE(Type::Common({u32, af, u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af, f32}), f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af, f16}), f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af, i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{ai, af, u32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({ai, af, f32}), f32);
-    EXPECT_TYPE(Type::Common({ai, af, f16}), f16);
-    EXPECT_TYPE(Type::Common({ai, af, i32}), nullptr);
-    EXPECT_TYPE(Type::Common({ai, af, u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af, vec3_af}), vec3_af);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_f16, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec4_f32, vec4_f32}), vec4_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_u32, vec3_u32}), vec3_u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_i32, vec3_i32}), vec3_i32);
 
-    auto* vec3_ai = create<Vector>(ai, 3u);
-    auto* vec3_af = create<Vector>(af, 3u);
-    auto* vec3_f32 = create<Vector>(f32, 3u);
-    auto* vec3_f16 = create<Vector>(f16, 3u);
-    auto* vec4_f32 = create<Vector>(f32, 4u);
-    auto* vec3_u32 = create<Vector>(u32, 3u);
-    auto* vec3_i32 = create<Vector>(i32, 3u);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_ai, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_ai, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_ai, vec4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_ai, vec3_u32}), vec3_u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_ai, vec3_i32}), vec3_i32);
 
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_af, vec3_af}), vec3_af);
-    EXPECT_TYPE(Type::Common({vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_f16, vec3_f16, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec4_f32, vec4_f32, vec4_f32}), vec4_f32);
-    EXPECT_TYPE(Type::Common({vec3_u32, vec3_u32, vec3_u32}), vec3_u32);
-    EXPECT_TYPE(Type::Common({vec3_i32, vec3_i32, vec3_i32}), vec3_i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f32, vec3_ai}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f16, vec3_ai}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec4_f32, vec3_ai}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_u32, vec3_ai}), vec3_u32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_i32, vec3_ai}), vec3_i32);
 
-    EXPECT_TYPE(Type::Common({vec3_f32, vec3_ai, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_f16, vec3_ai, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec4_f32, vec3_ai, vec4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_u32, vec3_ai, vec3_u32}), vec3_u32);
-    EXPECT_TYPE(Type::Common({vec3_i32, vec3_ai, vec3_i32}), vec3_i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_af, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_af, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_af, vec4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af, vec3_u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af, vec3_i32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_f32, vec3_ai}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_f16, vec3_ai}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec4_f32, vec3_ai}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_u32, vec3_ai}), vec3_u32);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_i32, vec3_ai}), vec3_i32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f32, vec3_af}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f16, vec3_af}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec4_f32, vec3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_u32, vec3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_i32, vec3_af}), nullptr);
 
-    EXPECT_TYPE(Type::Common({vec3_f32, vec3_af, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_f16, vec3_af, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec4_f32, vec3_af, vec4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_u32, vec3_af, vec3_u32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_i32, vec3_af, vec3_i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_f32}), vec3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_f16}), vec3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_u32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_i32}), nullptr);
 
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_f32, vec3_af}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_f16, vec3_af}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec3_af, vec4_f32, vec3_af}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_u32, vec3_af}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_af, vec3_i32, vec3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_f16, mat4x3_f16}), mat4x3_f16);
 
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_f32}), vec3_f32);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_f16}), vec3_f16);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_u32}), nullptr);
-    EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_i32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af, mat3x4_f32}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af, mat4x3_f32}), mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af, mat4x3_f16}), mat4x3_f16);
 
-    auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
-    auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
-    auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
-    auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
 
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
-    EXPECT_TYPE(Type::Common({mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_f16, mat4x3_f16}), mat4x3_f16);
-
-    EXPECT_TYPE(Type::Common({mat3x4_f32, mat4x3_af, mat3x4_f32}), nullptr);
-    EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_af, mat4x3_f32}), mat4x3_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_af, mat4x3_f16}), mat4x3_f16);
-
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
-    EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
+    EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f16, arr_mat4x3_f32, arr_mat4x3_f16}),
+                nullptr);
+    EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_af, arr_mat4x3_f32, arr_mat4x3_af}),
+                arr_mat4x3_f32);
+    EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_af, arr_mat4x3_f16, arr_mat4x3_af}),
+                arr_mat4x3_f16);
 }
 
 }  // namespace
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 4f9d6c8..3d474ed 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -105,10 +105,11 @@
 
 bool DecomposeStridedMatrix::ShouldRun(const Program* program, const DataMap&) const {
     bool should_run = false;
-    GatherCustomStrideMatrixMembers(program, [&](const sem::StructMember*, sem::Matrix*, uint32_t) {
-        should_run = true;
-        return GatherResult::kStop;
-    });
+    GatherCustomStrideMatrixMembers(program,
+                                    [&](const sem::StructMember*, const sem::Matrix*, uint32_t) {
+                                        should_run = true;
+                                        return GatherResult::kStop;
+                                    });
     return should_run;
 }
 
@@ -118,7 +119,7 @@
     // and populate the `decomposed` map with the members that have been replaced.
     std::unordered_map<const ast::StructMember*, MatrixInfo> decomposed;
     GatherCustomStrideMatrixMembers(
-        ctx.src, [&](const sem::StructMember* member, sem::Matrix* matrix, uint32_t stride) {
+        ctx.src, [&](const sem::StructMember* member, const sem::Matrix* matrix, uint32_t stride) {
             // We've got ourselves a struct member of a matrix type with a custom
             // stride. Replace this with an array of column vectors.
             MatrixInfo info{stride, matrix};
diff --git a/src/tint/transform/vectorize_scalar_matrix_constructors.cc b/src/tint/transform/vectorize_scalar_matrix_constructors.cc
index 3bba57c..f48ac8e 100644
--- a/src/tint/transform/vectorize_scalar_matrix_constructors.cc
+++ b/src/tint/transform/vectorize_scalar_matrix_constructors.cc
@@ -18,6 +18,7 @@
 #include <utility>
 
 #include "src/tint/program_builder.h"
+#include "src/tint/sem/abstract_numeric.h"
 #include "src/tint/sem/call.h"
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/type_constructor.h"
@@ -54,7 +55,6 @@
         if (!ty_ctor) {
             return nullptr;
         }
-        // Check if this is a matrix constructor with scalar arguments.
         auto* mat_type = call->Type()->As<sem::Matrix>();
         if (!mat_type) {
             return nullptr;
@@ -64,7 +64,15 @@
         if (args.IsEmpty()) {
             return nullptr;
         }
-        if (!args[0]->Type()->UnwrapRef()->is_scalar()) {
+
+        // If the argument type is a matrix, then this is an identity / conversion constructor.
+        // If the argument type is a vector, then we're already column vectors.
+        // If the argument type is abstract, then we're const-expression and there's no need to
+        // adjust this, as it'll be constant folded by the backend.
+        if (args[0]
+                ->Type()
+                ->UnwrapRef()
+                ->IsAnyOf<sem::Matrix, sem::Vector, sem::AbstractNumeric>()) {
             return nullptr;
         }
 
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 5cd0999..4c513be 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -1302,10 +1302,12 @@
 bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
                                     const ast::CallExpression* expr,
                                     const sem::Builtin* builtin) {
+    auto* return_elem_type = sem::Type::DeepestElementOf(builtin->ReturnType());
+    const std::string suffix = Is<sem::F16>(return_elem_type) ? "hf" : "f";
     return CallBuiltinHelper(out, expr, builtin,
                              [&](TextBuffer* b, const std::vector<std::string>& params) {
                                  line(b) << "return " << params[0] << " * " << std::setprecision(20)
-                                         << sem::kRadToDeg << ";";
+                                         << sem::kRadToDeg << suffix << ";";
                                  return true;
                              });
 }
@@ -1313,10 +1315,12 @@
 bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
                                     const ast::CallExpression* expr,
                                     const sem::Builtin* builtin) {
+    auto* return_elem_type = sem::Type::DeepestElementOf(builtin->ReturnType());
+    const std::string suffix = Is<sem::F16>(return_elem_type) ? "hf" : "f";
     return CallBuiltinHelper(out, expr, builtin,
                              [&](TextBuffer* b, const std::vector<std::string>& params) {
                                  line(b) << "return " << params[0] << " * " << std::setprecision(20)
-                                         << sem::kDegToRad << ";";
+                                         << sem::kDegToRad << suffix << ";";
                                  return true;
                              });
 }
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index c753293..ad75046 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -29,36 +29,40 @@
 
 using GlslGeneratorImplTest_Builtin = TestHelper;
 
-enum class ParamType {
+enum class CallParamType {
     kF32,
     kU32,
     kBool,
+    kF16,
 };
 
 struct BuiltinData {
     BuiltinType builtin;
-    ParamType type;
+    CallParamType type;
     const char* glsl_name;
 };
 inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
-    out << data.glsl_name;
+    out << data.glsl_name << "<";
     switch (data.type) {
-        case ParamType::kF32:
+        case CallParamType::kF32:
             out << "f32";
             break;
-        case ParamType::kU32:
+        case CallParamType::kU32:
             out << "u32";
             break;
-        case ParamType::kBool:
+        case CallParamType::kBool:
             out << "bool";
             break;
+        case CallParamType::kF16:
+            out << "f16";
+            break;
     }
     out << ">";
     return out;
 }
 
 const ast::CallExpression* GenerateCall(BuiltinType builtin,
-                                        ParamType type,
+                                        CallParamType type,
                                         ProgramBuilder* builder) {
     std::string name;
     std::ostringstream str(name);
@@ -96,29 +100,51 @@
         case BuiltinType::kTanh:
         case BuiltinType::kTrunc:
         case BuiltinType::kSign:
-            return builder->Call(str.str(), "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2");
+            } else {
+                return builder->Call(str.str(), "f2");
+            }
         case BuiltinType::kLdexp:
-            return builder->Call(str.str(), "f2", "i2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "i2");
+            } else {
+                return builder->Call(str.str(), "f2", "i2");
+            }
         case BuiltinType::kAtan2:
         case BuiltinType::kDot:
         case BuiltinType::kDistance:
         case BuiltinType::kPow:
         case BuiltinType::kReflect:
         case BuiltinType::kStep:
-            return builder->Call(str.str(), "f2", "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2");
+            }
         case BuiltinType::kCross:
-            return builder->Call(str.str(), "f3", "f3");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h3", "h3");
+            } else {
+                return builder->Call(str.str(), "f3", "f3");
+            }
         case BuiltinType::kFma:
         case BuiltinType::kMix:
         case BuiltinType::kFaceForward:
         case BuiltinType::kSmoothstep:
-            return builder->Call(str.str(), "f2", "f2", "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "h2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2", "f2");
+            }
         case BuiltinType::kAll:
         case BuiltinType::kAny:
             return builder->Call(str.str(), "b2");
         case BuiltinType::kAbs:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2");
             } else {
                 return builder->Call(str.str(), "u2");
             }
@@ -127,23 +153,39 @@
             return builder->Call(str.str(), "u2");
         case BuiltinType::kMax:
         case BuiltinType::kMin:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2", "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2");
             } else {
                 return builder->Call(str.str(), "u2", "u2");
             }
         case BuiltinType::kClamp:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2", "f2", "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "h2");
             } else {
                 return builder->Call(str.str(), "u2", "u2", "u2");
             }
         case BuiltinType::kSelect:
-            return builder->Call(str.str(), "f2", "f2", "b2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "b2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2", "b2");
+            }
         case BuiltinType::kDeterminant:
-            return builder->Call(str.str(), "m2x2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "hm2x2");
+            } else {
+                return builder->Call(str.str(), "m2x2");
+            }
         case BuiltinType::kTranspose:
-            return builder->Call(str.str(), "m3x2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "hm3x2");
+            } else {
+                return builder->Call(str.str(), "m3x2");
+            }
         default:
             break;
     }
@@ -153,6 +195,15 @@
 TEST_P(GlslBuiltinTest, Emit) {
     auto param = GetParam();
 
+    if (param.type == CallParamType::kF16) {
+        Enable(ast::Extension::kF16);
+
+        GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
+    }
+
     GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
     GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
     GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
@@ -180,64 +231,110 @@
 INSTANTIATE_TEST_SUITE_P(
     GlslGeneratorImplTest_Builtin,
     GlslBuiltinTest,
-    testing::Values(BuiltinData{BuiltinType::kAbs, ParamType::kF32, "abs"},
-                    BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
-                    BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
-                    BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
-                    BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
-                    BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
-                    BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
-                    BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan"},
-                    BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
-                    BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
-                    BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
-                    BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
-                    BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
-                    BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "bitCount"},
-                    BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
-                    BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
-                    BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
-                    BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
-                    BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "dFdx"},
-                    BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "dFdx"},
-                    BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "dFdx"},
-                    BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "dFdy"},
-                    BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "dFdy"},
-                    BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "dFdy"},
-                    BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
-                    BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
-                    BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
-                    BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
-                    BuiltinData{BuiltinType::kFma, ParamType::kF32, "fma"},
-                    BuiltinData{BuiltinType::kFract, ParamType::kF32, "fract"},
-                    BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
-                    BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
-                    BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
-                    BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "inversesqrt"},
-                    BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
-                    BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
-                    BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
-                    BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
-                    BuiltinData{BuiltinType::kMax, ParamType::kF32, "max"},
-                    BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
-                    BuiltinData{BuiltinType::kMin, ParamType::kF32, "min"},
-                    BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
-                    BuiltinData{BuiltinType::kMix, ParamType::kF32, "mix"},
-                    BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
-                    BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
-                    BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
-                    BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "bitfieldReverse"},
-                    BuiltinData{BuiltinType::kRound, ParamType::kU32, "round"},
-                    BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
-                    BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
-                    BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
-                    BuiltinData{BuiltinType::kSmoothstep, ParamType::kF32, "smoothstep"},
-                    BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
-                    BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
-                    BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
-                    BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
-                    BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
-                    BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"}));
+    testing::Values(/* Logical built-in */
+                    BuiltinData{BuiltinType::kAll, CallParamType::kBool, "all"},
+                    BuiltinData{BuiltinType::kAny, CallParamType::kBool, "any"},
+                    /* Float built-in */
+                    BuiltinData{BuiltinType::kAbs, CallParamType::kF32, "abs"},
+                    BuiltinData{BuiltinType::kAbs, CallParamType::kF16, "abs"},
+                    BuiltinData{BuiltinType::kAcos, CallParamType::kF32, "acos"},
+                    BuiltinData{BuiltinType::kAcos, CallParamType::kF16, "acos"},
+                    BuiltinData{BuiltinType::kAsin, CallParamType::kF32, "asin"},
+                    BuiltinData{BuiltinType::kAsin, CallParamType::kF16, "asin"},
+                    BuiltinData{BuiltinType::kAtan, CallParamType::kF32, "atan"},
+                    BuiltinData{BuiltinType::kAtan, CallParamType::kF16, "atan"},
+                    BuiltinData{BuiltinType::kAtan2, CallParamType::kF32, "atan"},
+                    BuiltinData{BuiltinType::kAtan2, CallParamType::kF16, "atan"},
+                    BuiltinData{BuiltinType::kCeil, CallParamType::kF32, "ceil"},
+                    BuiltinData{BuiltinType::kCeil, CallParamType::kF16, "ceil"},
+                    BuiltinData{BuiltinType::kClamp, CallParamType::kF32, "clamp"},
+                    BuiltinData{BuiltinType::kClamp, CallParamType::kF16, "clamp"},
+                    BuiltinData{BuiltinType::kCos, CallParamType::kF32, "cos"},
+                    BuiltinData{BuiltinType::kCos, CallParamType::kF16, "cos"},
+                    BuiltinData{BuiltinType::kCosh, CallParamType::kF32, "cosh"},
+                    BuiltinData{BuiltinType::kCosh, CallParamType::kF16, "cosh"},
+                    BuiltinData{BuiltinType::kCross, CallParamType::kF32, "cross"},
+                    BuiltinData{BuiltinType::kCross, CallParamType::kF16, "cross"},
+                    BuiltinData{BuiltinType::kDistance, CallParamType::kF32, "distance"},
+                    BuiltinData{BuiltinType::kDistance, CallParamType::kF16, "distance"},
+                    BuiltinData{BuiltinType::kExp, CallParamType::kF32, "exp"},
+                    BuiltinData{BuiltinType::kExp, CallParamType::kF16, "exp"},
+                    BuiltinData{BuiltinType::kExp2, CallParamType::kF32, "exp2"},
+                    BuiltinData{BuiltinType::kExp2, CallParamType::kF16, "exp2"},
+                    BuiltinData{BuiltinType::kFaceForward, CallParamType::kF32, "faceforward"},
+                    BuiltinData{BuiltinType::kFaceForward, CallParamType::kF16, "faceforward"},
+                    BuiltinData{BuiltinType::kFloor, CallParamType::kF32, "floor"},
+                    BuiltinData{BuiltinType::kFloor, CallParamType::kF16, "floor"},
+                    BuiltinData{BuiltinType::kFma, CallParamType::kF32, "fma"},
+                    BuiltinData{BuiltinType::kFma, CallParamType::kF16, "fma"},
+                    BuiltinData{BuiltinType::kFract, CallParamType::kF32, "fract"},
+                    BuiltinData{BuiltinType::kFract, CallParamType::kF16, "fract"},
+                    BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF32, "inversesqrt"},
+                    BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF16, "inversesqrt"},
+                    BuiltinData{BuiltinType::kLdexp, CallParamType::kF32, "ldexp"},
+                    BuiltinData{BuiltinType::kLdexp, CallParamType::kF16, "ldexp"},
+                    BuiltinData{BuiltinType::kLength, CallParamType::kF32, "length"},
+                    BuiltinData{BuiltinType::kLength, CallParamType::kF16, "length"},
+                    BuiltinData{BuiltinType::kLog, CallParamType::kF32, "log"},
+                    BuiltinData{BuiltinType::kLog, CallParamType::kF16, "log"},
+                    BuiltinData{BuiltinType::kLog2, CallParamType::kF32, "log2"},
+                    BuiltinData{BuiltinType::kLog2, CallParamType::kF16, "log2"},
+                    BuiltinData{BuiltinType::kMax, CallParamType::kF32, "max"},
+                    BuiltinData{BuiltinType::kMax, CallParamType::kF16, "max"},
+                    BuiltinData{BuiltinType::kMin, CallParamType::kF32, "min"},
+                    BuiltinData{BuiltinType::kMin, CallParamType::kF16, "min"},
+                    BuiltinData{BuiltinType::kMix, CallParamType::kF32, "mix"},
+                    BuiltinData{BuiltinType::kMix, CallParamType::kF16, "mix"},
+                    BuiltinData{BuiltinType::kNormalize, CallParamType::kF32, "normalize"},
+                    BuiltinData{BuiltinType::kNormalize, CallParamType::kF16, "normalize"},
+                    BuiltinData{BuiltinType::kPow, CallParamType::kF32, "pow"},
+                    BuiltinData{BuiltinType::kPow, CallParamType::kF16, "pow"},
+                    BuiltinData{BuiltinType::kReflect, CallParamType::kF32, "reflect"},
+                    BuiltinData{BuiltinType::kReflect, CallParamType::kF16, "reflect"},
+                    BuiltinData{BuiltinType::kSign, CallParamType::kF32, "sign"},
+                    BuiltinData{BuiltinType::kSign, CallParamType::kF16, "sign"},
+                    BuiltinData{BuiltinType::kSin, CallParamType::kF32, "sin"},
+                    BuiltinData{BuiltinType::kSin, CallParamType::kF16, "sin"},
+                    BuiltinData{BuiltinType::kSinh, CallParamType::kF32, "sinh"},
+                    BuiltinData{BuiltinType::kSinh, CallParamType::kF16, "sinh"},
+                    BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF32, "smoothstep"},
+                    BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF16, "smoothstep"},
+                    BuiltinData{BuiltinType::kSqrt, CallParamType::kF32, "sqrt"},
+                    BuiltinData{BuiltinType::kSqrt, CallParamType::kF16, "sqrt"},
+                    BuiltinData{BuiltinType::kStep, CallParamType::kF32, "step"},
+                    BuiltinData{BuiltinType::kStep, CallParamType::kF16, "step"},
+                    BuiltinData{BuiltinType::kTan, CallParamType::kF32, "tan"},
+                    BuiltinData{BuiltinType::kTan, CallParamType::kF16, "tan"},
+                    BuiltinData{BuiltinType::kTanh, CallParamType::kF32, "tanh"},
+                    BuiltinData{BuiltinType::kTanh, CallParamType::kF16, "tanh"},
+                    BuiltinData{BuiltinType::kTrunc, CallParamType::kF32, "trunc"},
+                    BuiltinData{BuiltinType::kTrunc, CallParamType::kF16, "trunc"},
+                    /* Integer built-in */
+                    BuiltinData{BuiltinType::kAbs, CallParamType::kU32, "abs"},
+                    BuiltinData{BuiltinType::kClamp, CallParamType::kU32, "clamp"},
+                    BuiltinData{BuiltinType::kCountOneBits, CallParamType::kU32, "bitCount"},
+                    BuiltinData{BuiltinType::kMax, CallParamType::kU32, "max"},
+                    BuiltinData{BuiltinType::kMin, CallParamType::kU32, "min"},
+                    BuiltinData{BuiltinType::kReverseBits, CallParamType::kU32, "bitfieldReverse"},
+                    BuiltinData{BuiltinType::kRound, CallParamType::kU32, "round"},
+                    /* Matrix built-in */
+                    BuiltinData{BuiltinType::kDeterminant, CallParamType::kF32, "determinant"},
+                    BuiltinData{BuiltinType::kDeterminant, CallParamType::kF16, "determinant"},
+                    BuiltinData{BuiltinType::kTranspose, CallParamType::kF32, "transpose"},
+                    BuiltinData{BuiltinType::kTranspose, CallParamType::kF16, "transpose"},
+                    /* Vector built-in */
+                    BuiltinData{BuiltinType::kDot, CallParamType::kF32, "dot"},
+                    BuiltinData{BuiltinType::kDot, CallParamType::kF16, "dot"},
+                    /* Derivate built-in */
+                    BuiltinData{BuiltinType::kDpdx, CallParamType::kF32, "dFdx"},
+                    BuiltinData{BuiltinType::kDpdxCoarse, CallParamType::kF32, "dFdx"},
+                    BuiltinData{BuiltinType::kDpdxFine, CallParamType::kF32, "dFdx"},
+                    BuiltinData{BuiltinType::kDpdy, CallParamType::kF32, "dFdy"},
+                    BuiltinData{BuiltinType::kDpdyCoarse, CallParamType::kF32, "dFdy"},
+                    BuiltinData{BuiltinType::kDpdyFine, CallParamType::kF32, "dFdy"},
+                    BuiltinData{BuiltinType::kFwidth, CallParamType::kF32, "fwidth"},
+                    BuiltinData{BuiltinType::kFwidthCoarse, CallParamType::kF32, "fwidth"},
+                    BuiltinData{BuiltinType::kFwidthFine, CallParamType::kF32, "fwidth"}));
 
 TEST_F(GlslGeneratorImplTest_Builtin, Builtin_Call) {
     auto* call = Call("dot", "param1", "param2");
@@ -277,6 +374,41 @@
     EXPECT_EQ(out.str(), "mix(ivec2(1, 2), ivec2(3, 4), bvec2(true, false))");
 }
 
+TEST_F(GlslGeneratorImplTest_Builtin, FMA_f32) {
+    auto* call = Call("fma", "a", "b", "c");
+
+    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+
+    WrapInFunction(CallStmt(call));
+
+    GeneratorImpl& gen = Build();
+
+    gen.increment_indent();
+    std::stringstream out;
+    ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
+    EXPECT_EQ(out.str(), "((a) * (b) + (c))");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, FMA_f16) {
+    Enable(ast::Extension::kF16);
+
+    GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("c", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+
+    auto* call = Call("fma", "a", "b", "c");
+    WrapInFunction(CallStmt(call));
+
+    GeneratorImpl& gen = Build();
+
+    gen.increment_indent();
+    std::stringstream out;
+    ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
+    EXPECT_EQ(out.str(), "((a) * (b) + (c))");
+}
+
 TEST_F(GlslGeneratorImplTest_Builtin, Modf_Scalar) {
     auto* call = Call("modf", 1_f);
     WrapInFunction(CallStmt(call));
@@ -402,7 +534,7 @@
 )"));
 }
 
-TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar) {
+TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar_f32) {
     auto* val = Var("val", ty.f32());
     auto* call = Call("degrees", val);
     WrapInFunction(val, call);
@@ -413,7 +545,7 @@
     EXPECT_EQ(gen.result(), R"(#version 310 es
 
 float tint_degrees(float param_0) {
-  return param_0 * 57.295779513082322865;
+  return param_0 * 57.295779513082322865f;
 }
 
 
@@ -430,7 +562,7 @@
 )");
 }
 
-TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector) {
+TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector_f32) {
     auto* val = Var("val", ty.vec3<f32>());
     auto* call = Call("degrees", val);
     WrapInFunction(val, call);
@@ -441,7 +573,7 @@
     EXPECT_EQ(gen.result(), R"(#version 310 es
 
 vec3 tint_degrees(vec3 param_0) {
-  return param_0 * 57.295779513082322865;
+  return param_0 * 57.295779513082322865f;
 }
 
 
@@ -458,7 +590,69 @@
 )");
 }
 
-TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar) {
+TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("degrees", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+float16_t tint_degrees(float16_t param_0) {
+  return param_0 * 57.295779513082322865hf;
+}
+
+
+void test_function() {
+  float16_t val = 0.0hf;
+  float16_t tint_symbol = tint_degrees(val);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  test_function();
+  return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("degrees", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+f16vec3 tint_degrees(f16vec3 param_0) {
+  return param_0 * 57.295779513082322865hf;
+}
+
+
+void test_function() {
+  f16vec3 val = f16vec3(0.0hf, 0.0hf, 0.0hf);
+  f16vec3 tint_symbol = tint_degrees(val);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  test_function();
+  return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar_f32) {
     auto* val = Var("val", ty.f32());
     auto* call = Call("radians", val);
     WrapInFunction(val, call);
@@ -469,7 +663,7 @@
     EXPECT_EQ(gen.result(), R"(#version 310 es
 
 float tint_radians(float param_0) {
-  return param_0 * 0.017453292519943295474;
+  return param_0 * 0.017453292519943295474f;
 }
 
 
@@ -486,7 +680,7 @@
 )");
 }
 
-TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector) {
+TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector_f32) {
     auto* val = Var("val", ty.vec3<f32>());
     auto* call = Call("radians", val);
     WrapInFunction(val, call);
@@ -497,7 +691,7 @@
     EXPECT_EQ(gen.result(), R"(#version 310 es
 
 vec3 tint_radians(vec3 param_0) {
-  return param_0 * 0.017453292519943295474;
+  return param_0 * 0.017453292519943295474f;
 }
 
 
@@ -514,6 +708,68 @@
 )");
 }
 
+TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("radians", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+float16_t tint_radians(float16_t param_0) {
+  return param_0 * 0.017453292519943295474hf;
+}
+
+
+void test_function() {
+  float16_t val = 0.0hf;
+  float16_t tint_symbol = tint_radians(val);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  test_function();
+  return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("radians", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+
+f16vec3 tint_radians(f16vec3 param_0) {
+  return param_0 * 0.017453292519943295474hf;
+}
+
+
+void test_function() {
+  f16vec3 val = f16vec3(0.0hf, 0.0hf, 0.0hf);
+  f16vec3 tint_symbol = tint_radians(val);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  test_function();
+  return;
+}
+)");
+}
+
 TEST_F(GlslGeneratorImplTest_Builtin, ExtractBits) {
     auto* v = Var("v", ty.vec3<u32>());
     auto* offset = Var("offset", ty.u32());
@@ -828,23 +1084,6 @@
 )");
 }
 
-TEST_F(GlslGeneratorImplTest_Builtin, FMA) {
-    auto* call = Call("fma", "a", "b", "c");
-
-    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-
-    WrapInFunction(CallStmt(call));
-
-    GeneratorImpl& gen = Build();
-
-    gen.increment_indent();
-    std::stringstream out;
-    ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
-    EXPECT_EQ(out.str(), "((a) * (b) + (c))");
-}
-
 TEST_F(GlslGeneratorImplTest_Builtin, DotU32) {
     GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index 008ea6c..c87d60d 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -28,36 +28,40 @@
 using BuiltinType = sem::BuiltinType;
 using HlslGeneratorImplTest_Builtin = TestHelper;
 
-enum class ParamType {
+enum class CallParamType {
     kF32,
     kU32,
     kBool,
+    kF16,
 };
 
 struct BuiltinData {
     BuiltinType builtin;
-    ParamType type;
+    CallParamType type;
     const char* hlsl_name;
 };
 inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
-    out << data.hlsl_name;
+    out << data.hlsl_name << "<";
     switch (data.type) {
-        case ParamType::kF32:
+        case CallParamType::kF32:
             out << "f32";
             break;
-        case ParamType::kU32:
+        case CallParamType::kU32:
             out << "u32";
             break;
-        case ParamType::kBool:
+        case CallParamType::kBool:
             out << "bool";
             break;
+        case CallParamType::kF16:
+            out << "f16";
+            break;
     }
     out << ">";
     return out;
 }
 
 const ast::CallExpression* GenerateCall(BuiltinType builtin,
-                                        ParamType type,
+                                        CallParamType type,
                                         ProgramBuilder* builder) {
     std::string name;
     std::ostringstream str(name);
@@ -95,29 +99,51 @@
         case BuiltinType::kTanh:
         case BuiltinType::kTrunc:
         case BuiltinType::kSign:
-            return builder->Call(str.str(), "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2");
+            } else {
+                return builder->Call(str.str(), "f2");
+            }
         case BuiltinType::kLdexp:
-            return builder->Call(str.str(), "f2", "i2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "i2");
+            } else {
+                return builder->Call(str.str(), "f2", "i2");
+            }
         case BuiltinType::kAtan2:
         case BuiltinType::kDot:
         case BuiltinType::kDistance:
         case BuiltinType::kPow:
         case BuiltinType::kReflect:
         case BuiltinType::kStep:
-            return builder->Call(str.str(), "f2", "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2");
+            }
         case BuiltinType::kCross:
-            return builder->Call(str.str(), "f3", "f3");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h3", "h3");
+            } else {
+                return builder->Call(str.str(), "f3", "f3");
+            }
         case BuiltinType::kFma:
         case BuiltinType::kMix:
         case BuiltinType::kFaceForward:
         case BuiltinType::kSmoothstep:
-            return builder->Call(str.str(), "f2", "f2", "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "h2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2", "f2");
+            }
         case BuiltinType::kAll:
         case BuiltinType::kAny:
             return builder->Call(str.str(), "b2");
         case BuiltinType::kAbs:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2");
             } else {
                 return builder->Call(str.str(), "u2");
             }
@@ -126,32 +152,58 @@
             return builder->Call(str.str(), "u2");
         case BuiltinType::kMax:
         case BuiltinType::kMin:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2", "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2");
             } else {
                 return builder->Call(str.str(), "u2", "u2");
             }
         case BuiltinType::kClamp:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2", "f2", "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "h2");
             } else {
                 return builder->Call(str.str(), "u2", "u2", "u2");
             }
         case BuiltinType::kSelect:
-            return builder->Call(str.str(), "f2", "f2", "b2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "b2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2", "b2");
+            }
         case BuiltinType::kDeterminant:
-            return builder->Call(str.str(), "m2x2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "hm2x2");
+            } else {
+                return builder->Call(str.str(), "m2x2");
+            }
         case BuiltinType::kTranspose:
-            return builder->Call(str.str(), "m3x2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "hm3x2");
+            } else {
+                return builder->Call(str.str(), "m3x2");
+            }
         default:
             break;
     }
     return nullptr;
 }
+
 using HlslBuiltinTest = TestParamHelper<BuiltinData>;
 TEST_P(HlslBuiltinTest, Emit) {
     auto param = GetParam();
 
+    if (param.type == CallParamType::kF16) {
+        Enable(ast::Extension::kF16);
+
+        GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
+    }
+
     GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
     GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
     GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
@@ -179,64 +231,110 @@
 INSTANTIATE_TEST_SUITE_P(
     HlslGeneratorImplTest_Builtin,
     HlslBuiltinTest,
-    testing::Values(BuiltinData{BuiltinType::kAbs, ParamType::kF32, "abs"},
-                    BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
-                    BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
-                    BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
-                    BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
-                    BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
-                    BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
-                    BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan2"},
-                    BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
-                    BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
-                    BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
-                    BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
-                    BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
-                    BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "countbits"},
-                    BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
-                    BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
-                    BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
-                    BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
-                    BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "ddx"},
-                    BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "ddx_coarse"},
-                    BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "ddx_fine"},
-                    BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "ddy"},
-                    BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "ddy_coarse"},
-                    BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "ddy_fine"},
-                    BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
-                    BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
-                    BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
-                    BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
-                    BuiltinData{BuiltinType::kFma, ParamType::kF32, "mad"},
-                    BuiltinData{BuiltinType::kFract, ParamType::kF32, "frac"},
-                    BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
-                    BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
-                    BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
-                    BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
-                    BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
-                    BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
-                    BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
-                    BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
-                    BuiltinData{BuiltinType::kMax, ParamType::kF32, "max"},
-                    BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
-                    BuiltinData{BuiltinType::kMin, ParamType::kF32, "min"},
-                    BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
-                    BuiltinData{BuiltinType::kMix, ParamType::kF32, "lerp"},
-                    BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
-                    BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
-                    BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
-                    BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reversebits"},
-                    BuiltinData{BuiltinType::kRound, ParamType::kU32, "round"},
-                    BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
-                    BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
-                    BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
-                    BuiltinData{BuiltinType::kSmoothstep, ParamType::kF32, "smoothstep"},
-                    BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
-                    BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
-                    BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
-                    BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
-                    BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
-                    BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"}));
+    testing::Values(/* Logical built-in */
+                    BuiltinData{BuiltinType::kAll, CallParamType::kBool, "all"},
+                    BuiltinData{BuiltinType::kAny, CallParamType::kBool, "any"},
+                    /* Float built-in */
+                    BuiltinData{BuiltinType::kAbs, CallParamType::kF32, "abs"},
+                    BuiltinData{BuiltinType::kAbs, CallParamType::kF16, "abs"},
+                    BuiltinData{BuiltinType::kAcos, CallParamType::kF32, "acos"},
+                    BuiltinData{BuiltinType::kAcos, CallParamType::kF16, "acos"},
+                    BuiltinData{BuiltinType::kAsin, CallParamType::kF32, "asin"},
+                    BuiltinData{BuiltinType::kAsin, CallParamType::kF16, "asin"},
+                    BuiltinData{BuiltinType::kAtan, CallParamType::kF32, "atan"},
+                    BuiltinData{BuiltinType::kAtan, CallParamType::kF16, "atan"},
+                    BuiltinData{BuiltinType::kAtan2, CallParamType::kF32, "atan2"},
+                    BuiltinData{BuiltinType::kAtan2, CallParamType::kF16, "atan2"},
+                    BuiltinData{BuiltinType::kCeil, CallParamType::kF32, "ceil"},
+                    BuiltinData{BuiltinType::kCeil, CallParamType::kF16, "ceil"},
+                    BuiltinData{BuiltinType::kClamp, CallParamType::kF32, "clamp"},
+                    BuiltinData{BuiltinType::kClamp, CallParamType::kF16, "clamp"},
+                    BuiltinData{BuiltinType::kCos, CallParamType::kF32, "cos"},
+                    BuiltinData{BuiltinType::kCos, CallParamType::kF16, "cos"},
+                    BuiltinData{BuiltinType::kCosh, CallParamType::kF32, "cosh"},
+                    BuiltinData{BuiltinType::kCosh, CallParamType::kF16, "cosh"},
+                    BuiltinData{BuiltinType::kCross, CallParamType::kF32, "cross"},
+                    BuiltinData{BuiltinType::kCross, CallParamType::kF16, "cross"},
+                    BuiltinData{BuiltinType::kDistance, CallParamType::kF32, "distance"},
+                    BuiltinData{BuiltinType::kDistance, CallParamType::kF16, "distance"},
+                    BuiltinData{BuiltinType::kExp, CallParamType::kF32, "exp"},
+                    BuiltinData{BuiltinType::kExp, CallParamType::kF16, "exp"},
+                    BuiltinData{BuiltinType::kExp2, CallParamType::kF32, "exp2"},
+                    BuiltinData{BuiltinType::kExp2, CallParamType::kF16, "exp2"},
+                    BuiltinData{BuiltinType::kFaceForward, CallParamType::kF32, "faceforward"},
+                    BuiltinData{BuiltinType::kFaceForward, CallParamType::kF16, "faceforward"},
+                    BuiltinData{BuiltinType::kFloor, CallParamType::kF32, "floor"},
+                    BuiltinData{BuiltinType::kFloor, CallParamType::kF16, "floor"},
+                    BuiltinData{BuiltinType::kFma, CallParamType::kF32, "mad"},
+                    BuiltinData{BuiltinType::kFma, CallParamType::kF16, "mad"},
+                    BuiltinData{BuiltinType::kFract, CallParamType::kF32, "frac"},
+                    BuiltinData{BuiltinType::kFract, CallParamType::kF16, "frac"},
+                    BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF32, "rsqrt"},
+                    BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF16, "rsqrt"},
+                    BuiltinData{BuiltinType::kLdexp, CallParamType::kF32, "ldexp"},
+                    BuiltinData{BuiltinType::kLdexp, CallParamType::kF16, "ldexp"},
+                    BuiltinData{BuiltinType::kLength, CallParamType::kF32, "length"},
+                    BuiltinData{BuiltinType::kLength, CallParamType::kF16, "length"},
+                    BuiltinData{BuiltinType::kLog, CallParamType::kF32, "log"},
+                    BuiltinData{BuiltinType::kLog, CallParamType::kF16, "log"},
+                    BuiltinData{BuiltinType::kLog2, CallParamType::kF32, "log2"},
+                    BuiltinData{BuiltinType::kLog2, CallParamType::kF16, "log2"},
+                    BuiltinData{BuiltinType::kMax, CallParamType::kF32, "max"},
+                    BuiltinData{BuiltinType::kMax, CallParamType::kF16, "max"},
+                    BuiltinData{BuiltinType::kMin, CallParamType::kF32, "min"},
+                    BuiltinData{BuiltinType::kMin, CallParamType::kF16, "min"},
+                    BuiltinData{BuiltinType::kMix, CallParamType::kF32, "lerp"},
+                    BuiltinData{BuiltinType::kMix, CallParamType::kF16, "lerp"},
+                    BuiltinData{BuiltinType::kNormalize, CallParamType::kF32, "normalize"},
+                    BuiltinData{BuiltinType::kNormalize, CallParamType::kF16, "normalize"},
+                    BuiltinData{BuiltinType::kPow, CallParamType::kF32, "pow"},
+                    BuiltinData{BuiltinType::kPow, CallParamType::kF16, "pow"},
+                    BuiltinData{BuiltinType::kReflect, CallParamType::kF32, "reflect"},
+                    BuiltinData{BuiltinType::kReflect, CallParamType::kF16, "reflect"},
+                    BuiltinData{BuiltinType::kSign, CallParamType::kF32, "sign"},
+                    BuiltinData{BuiltinType::kSign, CallParamType::kF16, "sign"},
+                    BuiltinData{BuiltinType::kSin, CallParamType::kF32, "sin"},
+                    BuiltinData{BuiltinType::kSin, CallParamType::kF16, "sin"},
+                    BuiltinData{BuiltinType::kSinh, CallParamType::kF32, "sinh"},
+                    BuiltinData{BuiltinType::kSinh, CallParamType::kF16, "sinh"},
+                    BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF32, "smoothstep"},
+                    BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF16, "smoothstep"},
+                    BuiltinData{BuiltinType::kSqrt, CallParamType::kF32, "sqrt"},
+                    BuiltinData{BuiltinType::kSqrt, CallParamType::kF16, "sqrt"},
+                    BuiltinData{BuiltinType::kStep, CallParamType::kF32, "step"},
+                    BuiltinData{BuiltinType::kStep, CallParamType::kF16, "step"},
+                    BuiltinData{BuiltinType::kTan, CallParamType::kF32, "tan"},
+                    BuiltinData{BuiltinType::kTan, CallParamType::kF16, "tan"},
+                    BuiltinData{BuiltinType::kTanh, CallParamType::kF32, "tanh"},
+                    BuiltinData{BuiltinType::kTanh, CallParamType::kF16, "tanh"},
+                    BuiltinData{BuiltinType::kTrunc, CallParamType::kF32, "trunc"},
+                    BuiltinData{BuiltinType::kTrunc, CallParamType::kF16, "trunc"},
+                    /* Integer built-in */
+                    BuiltinData{BuiltinType::kAbs, CallParamType::kU32, "abs"},
+                    BuiltinData{BuiltinType::kClamp, CallParamType::kU32, "clamp"},
+                    BuiltinData{BuiltinType::kCountOneBits, CallParamType::kU32, "countbits"},
+                    BuiltinData{BuiltinType::kMax, CallParamType::kU32, "max"},
+                    BuiltinData{BuiltinType::kMin, CallParamType::kU32, "min"},
+                    BuiltinData{BuiltinType::kReverseBits, CallParamType::kU32, "reversebits"},
+                    BuiltinData{BuiltinType::kRound, CallParamType::kU32, "round"},
+                    /* Matrix built-in */
+                    BuiltinData{BuiltinType::kDeterminant, CallParamType::kF32, "determinant"},
+                    BuiltinData{BuiltinType::kDeterminant, CallParamType::kF16, "determinant"},
+                    BuiltinData{BuiltinType::kTranspose, CallParamType::kF32, "transpose"},
+                    BuiltinData{BuiltinType::kTranspose, CallParamType::kF16, "transpose"},
+                    /* Vector built-in */
+                    BuiltinData{BuiltinType::kDot, CallParamType::kF32, "dot"},
+                    BuiltinData{BuiltinType::kDot, CallParamType::kF16, "dot"},
+                    /* Derivate built-in */
+                    BuiltinData{BuiltinType::kDpdx, CallParamType::kF32, "ddx"},
+                    BuiltinData{BuiltinType::kDpdxCoarse, CallParamType::kF32, "ddx_coarse"},
+                    BuiltinData{BuiltinType::kDpdxFine, CallParamType::kF32, "ddx_fine"},
+                    BuiltinData{BuiltinType::kDpdy, CallParamType::kF32, "ddy"},
+                    BuiltinData{BuiltinType::kDpdyCoarse, CallParamType::kF32, "ddy_coarse"},
+                    BuiltinData{BuiltinType::kDpdyFine, CallParamType::kF32, "ddy_fine"},
+                    BuiltinData{BuiltinType::kFwidth, CallParamType::kF32, "fwidth"},
+                    BuiltinData{BuiltinType::kFwidthCoarse, CallParamType::kF32, "fwidth"},
+                    BuiltinData{BuiltinType::kFwidthFine, CallParamType::kF32, "fwidth"}));
 
 TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
     auto* call = Call("dot", "param1", "param2");
@@ -380,7 +478,7 @@
 )");
 }
 
-TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar) {
+TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar_f32) {
     auto* val = Var("val", ty.f32());
     auto* call = Call("degrees", val);
     WrapInFunction(val, call);
@@ -401,7 +499,7 @@
 )");
 }
 
-TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector) {
+TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector_f32) {
     auto* val = Var("val", ty.vec3<f32>());
     auto* call = Call("degrees", val);
     WrapInFunction(val, call);
@@ -422,7 +520,53 @@
 )");
 }
 
-TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar) {
+TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("degrees", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(float16_t tint_degrees(float16_t param_0) {
+  return param_0 * 57.295779513082322865;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  float16_t val = float16_t(0.0h);
+  const float16_t tint_symbol = tint_degrees(val);
+  return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("degrees", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(vector<float16_t, 3> tint_degrees(vector<float16_t, 3> param_0) {
+  return param_0 * 57.295779513082322865;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  vector<float16_t, 3> val = vector<float16_t, 3>(float16_t(0.0h), float16_t(0.0h), float16_t(0.0h));
+  const vector<float16_t, 3> tint_symbol = tint_degrees(val);
+  return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar_f32) {
     auto* val = Var("val", ty.f32());
     auto* call = Call("radians", val);
     WrapInFunction(val, call);
@@ -443,7 +587,7 @@
 )");
 }
 
-TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector) {
+TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector_f32) {
     auto* val = Var("val", ty.vec3<f32>());
     auto* call = Call("radians", val);
     WrapInFunction(val, call);
@@ -464,6 +608,52 @@
 )");
 }
 
+TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("radians", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(float16_t tint_radians(float16_t param_0) {
+  return param_0 * 0.017453292519943295474;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  float16_t val = float16_t(0.0h);
+  const float16_t tint_symbol = tint_radians(val);
+  return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("radians", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(vector<float16_t, 3> tint_radians(vector<float16_t, 3> param_0) {
+  return param_0 * 0.017453292519943295474;
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  vector<float16_t, 3> val = vector<float16_t, 3>(float16_t(0.0h), float16_t(0.0h), float16_t(0.0h));
+  const vector<float16_t, 3> tint_symbol = tint_radians(val);
+  return;
+}
+)");
+}
+
 TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
     auto* call = Call("pack4x8snorm", "p1");
     GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index 9f00be7..c8fab4b 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -25,36 +25,40 @@
 
 using MslGeneratorImplTest = TestHelper;
 
-enum class ParamType {
+enum class CallParamType {
     kF32,
     kU32,
     kBool,
+    kF16,
 };
 
 struct BuiltinData {
     BuiltinType builtin;
-    ParamType type;
+    CallParamType type;
     const char* msl_name;
 };
 inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
     out << data.msl_name << "<";
     switch (data.type) {
-        case ParamType::kF32:
+        case CallParamType::kF32:
             out << "f32";
             break;
-        case ParamType::kU32:
+        case CallParamType::kU32:
             out << "u32";
             break;
-        case ParamType::kBool:
+        case CallParamType::kBool:
             out << "bool";
             break;
+        case CallParamType::kF16:
+            out << "f16";
+            break;
     }
     out << ">";
     return out;
 }
 
 const ast::CallExpression* GenerateCall(BuiltinType builtin,
-                                        ParamType type,
+                                        CallParamType type,
                                         ProgramBuilder* builder) {
     std::string name;
     std::ostringstream str(name);
@@ -92,31 +96,53 @@
         case BuiltinType::kTanh:
         case BuiltinType::kTrunc:
         case BuiltinType::kSign:
-            return builder->Call(str.str(), "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2");
+            } else {
+                return builder->Call(str.str(), "f2");
+            }
         case BuiltinType::kLdexp:
-            return builder->Call(str.str(), "f2", "i2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "i2");
+            } else {
+                return builder->Call(str.str(), "f2", "i2");
+            }
         case BuiltinType::kAtan2:
         case BuiltinType::kDot:
         case BuiltinType::kDistance:
         case BuiltinType::kPow:
         case BuiltinType::kReflect:
         case BuiltinType::kStep:
-            return builder->Call(str.str(), "f2", "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2");
+            }
         case BuiltinType::kStorageBarrier:
             return builder->Call(str.str());
         case BuiltinType::kCross:
-            return builder->Call(str.str(), "f3", "f3");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h3", "h3");
+            } else {
+                return builder->Call(str.str(), "f3", "f3");
+            }
         case BuiltinType::kFma:
         case BuiltinType::kMix:
         case BuiltinType::kFaceForward:
         case BuiltinType::kSmoothstep:
-            return builder->Call(str.str(), "f2", "f2", "f2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "h2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2", "f2");
+            }
         case BuiltinType::kAll:
         case BuiltinType::kAny:
             return builder->Call(str.str(), "b2");
         case BuiltinType::kAbs:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2");
             } else {
                 return builder->Call(str.str(), "u2");
             }
@@ -131,21 +157,33 @@
             return builder->Call(str.str(), "u2", "u2", "u1", "u1");
         case BuiltinType::kMax:
         case BuiltinType::kMin:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2", "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2");
             } else {
                 return builder->Call(str.str(), "u2", "u2");
             }
         case BuiltinType::kClamp:
-            if (type == ParamType::kF32) {
+            if (type == CallParamType::kF32) {
                 return builder->Call(str.str(), "f2", "f2", "f2");
+            } else if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "h2");
             } else {
                 return builder->Call(str.str(), "u2", "u2", "u2");
             }
         case BuiltinType::kSelect:
-            return builder->Call(str.str(), "f2", "f2", "b2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "h2", "h2", "b2");
+            } else {
+                return builder->Call(str.str(), "f2", "f2", "b2");
+            }
         case BuiltinType::kDeterminant:
-            return builder->Call(str.str(), "m2x2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "hm2x2");
+            } else {
+                return builder->Call(str.str(), "m2x2");
+            }
         case BuiltinType::kPack2x16snorm:
         case BuiltinType::kPack2x16unorm:
             return builder->Call(str.str(), "f2");
@@ -160,7 +198,11 @@
         case BuiltinType::kWorkgroupBarrier:
             return builder->Call(str.str());
         case BuiltinType::kTranspose:
-            return builder->Call(str.str(), "m3x2");
+            if (type == CallParamType::kF16) {
+                return builder->Call(str.str(), "hm3x2");
+            } else {
+                return builder->Call(str.str(), "m3x2");
+            }
         default:
             break;
     }
@@ -171,6 +213,15 @@
 TEST_P(MslBuiltinTest, Emit) {
     auto param = GetParam();
 
+    if (param.type == CallParamType::kF16) {
+        Enable(ast::Extension::kF16);
+
+        GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
+    }
+
     GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
     GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
     GlobalVar("f4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
@@ -201,76 +252,122 @@
     MslGeneratorImplTest,
     MslBuiltinTest,
     testing::Values(
-        BuiltinData{BuiltinType::kAbs, ParamType::kF32, "fabs"},
-        BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
-        BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
-        BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
-        BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
-        BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
-        BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
-        BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan2"},
-        BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
-        BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
-        BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
-        BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
-        BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
-        BuiltinData{BuiltinType::kCountLeadingZeros, ParamType::kU32, "clz"},
-        BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "popcount"},
-        BuiltinData{BuiltinType::kCountTrailingZeros, ParamType::kU32, "ctz"},
-        BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
-        BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
-        BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
-        BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
-        BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "dfdx"},
-        BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "dfdx"},
-        BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "dfdx"},
-        BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "dfdy"},
-        BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "dfdy"},
-        BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "dfdy"},
-        BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
-        BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
-        BuiltinData{BuiltinType::kExtractBits, ParamType::kU32, "extract_bits"},
-        BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
-        BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
-        BuiltinData{BuiltinType::kFma, ParamType::kF32, "fma"},
-        BuiltinData{BuiltinType::kFract, ParamType::kF32, "fract"},
-        BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
-        BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
-        BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
-        BuiltinData{BuiltinType::kInsertBits, ParamType::kU32, "insert_bits"},
-        BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
-        BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
-        BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
-        BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
-        BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
-        BuiltinData{BuiltinType::kMax, ParamType::kF32, "fmax"},
-        BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
-        BuiltinData{BuiltinType::kMin, ParamType::kF32, "fmin"},
-        BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
-        BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
-        BuiltinData{BuiltinType::kPack4x8snorm, ParamType::kF32, "pack_float_to_snorm4x8"},
-        BuiltinData{BuiltinType::kPack4x8unorm, ParamType::kF32, "pack_float_to_unorm4x8"},
-        BuiltinData{BuiltinType::kPack2x16snorm, ParamType::kF32, "pack_float_to_snorm2x16"},
-        BuiltinData{BuiltinType::kPack2x16unorm, ParamType::kF32, "pack_float_to_unorm2x16"},
-        BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
-        BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
-        BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reverse_bits"},
-        BuiltinData{BuiltinType::kRound, ParamType::kU32, "rint"},
-        BuiltinData{BuiltinType::kSelect, ParamType::kF32, "select"},
-        BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
-        BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
-        BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
-        BuiltinData{BuiltinType::kSmoothstep, ParamType::kF32, "smoothstep"},
-        BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
-        BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
-        BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
-        BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
-        BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
-        BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"},
-        BuiltinData{BuiltinType::kUnpack4x8snorm, ParamType::kU32, "unpack_snorm4x8_to_float"},
-        BuiltinData{BuiltinType::kUnpack4x8unorm, ParamType::kU32, "unpack_unorm4x8_to_float"},
-        BuiltinData{BuiltinType::kUnpack2x16snorm, ParamType::kU32, "unpack_snorm2x16_to_float"},
-        BuiltinData{BuiltinType::kUnpack2x16unorm, ParamType::kU32, "unpack_unorm2x16_to_float"}));
+        /* Logical built-in */
+        BuiltinData{BuiltinType::kAll, CallParamType::kBool, "all"},
+        BuiltinData{BuiltinType::kAny, CallParamType::kBool, "any"},
+        BuiltinData{BuiltinType::kSelect, CallParamType::kF32, "select"},
+        /* Float built-in */
+        BuiltinData{BuiltinType::kAbs, CallParamType::kF32, "fabs"},
+        BuiltinData{BuiltinType::kAbs, CallParamType::kF16, "fabs"},
+        BuiltinData{BuiltinType::kAcos, CallParamType::kF32, "acos"},
+        BuiltinData{BuiltinType::kAcos, CallParamType::kF16, "acos"},
+        BuiltinData{BuiltinType::kAsin, CallParamType::kF32, "asin"},
+        BuiltinData{BuiltinType::kAsin, CallParamType::kF16, "asin"},
+        BuiltinData{BuiltinType::kAtan, CallParamType::kF32, "atan"},
+        BuiltinData{BuiltinType::kAtan, CallParamType::kF16, "atan"},
+        BuiltinData{BuiltinType::kAtan2, CallParamType::kF32, "atan2"},
+        BuiltinData{BuiltinType::kAtan2, CallParamType::kF16, "atan2"},
+        BuiltinData{BuiltinType::kCeil, CallParamType::kF32, "ceil"},
+        BuiltinData{BuiltinType::kCeil, CallParamType::kF16, "ceil"},
+        BuiltinData{BuiltinType::kClamp, CallParamType::kF32, "clamp"},
+        BuiltinData{BuiltinType::kClamp, CallParamType::kF16, "clamp"},
+        BuiltinData{BuiltinType::kCos, CallParamType::kF32, "cos"},
+        BuiltinData{BuiltinType::kCos, CallParamType::kF16, "cos"},
+        BuiltinData{BuiltinType::kCosh, CallParamType::kF32, "cosh"},
+        BuiltinData{BuiltinType::kCosh, CallParamType::kF16, "cosh"},
+        BuiltinData{BuiltinType::kCross, CallParamType::kF32, "cross"},
+        BuiltinData{BuiltinType::kCross, CallParamType::kF16, "cross"},
+        BuiltinData{BuiltinType::kDistance, CallParamType::kF32, "distance"},
+        BuiltinData{BuiltinType::kDistance, CallParamType::kF16, "distance"},
+        BuiltinData{BuiltinType::kExp, CallParamType::kF32, "exp"},
+        BuiltinData{BuiltinType::kExp, CallParamType::kF16, "exp"},
+        BuiltinData{BuiltinType::kExp2, CallParamType::kF32, "exp2"},
+        BuiltinData{BuiltinType::kExp2, CallParamType::kF16, "exp2"},
+        BuiltinData{BuiltinType::kFaceForward, CallParamType::kF32, "faceforward"},
+        BuiltinData{BuiltinType::kFaceForward, CallParamType::kF16, "faceforward"},
+        BuiltinData{BuiltinType::kFloor, CallParamType::kF32, "floor"},
+        BuiltinData{BuiltinType::kFloor, CallParamType::kF16, "floor"},
+        BuiltinData{BuiltinType::kFma, CallParamType::kF32, "fma"},
+        BuiltinData{BuiltinType::kFma, CallParamType::kF16, "fma"},
+        BuiltinData{BuiltinType::kFract, CallParamType::kF32, "fract"},
+        BuiltinData{BuiltinType::kFract, CallParamType::kF16, "fract"},
+        BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF32, "rsqrt"},
+        BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF16, "rsqrt"},
+        BuiltinData{BuiltinType::kLdexp, CallParamType::kF32, "ldexp"},
+        BuiltinData{BuiltinType::kLdexp, CallParamType::kF16, "ldexp"},
+        BuiltinData{BuiltinType::kLength, CallParamType::kF32, "length"},
+        BuiltinData{BuiltinType::kLength, CallParamType::kF16, "length"},
+        BuiltinData{BuiltinType::kLog, CallParamType::kF32, "log"},
+        BuiltinData{BuiltinType::kLog, CallParamType::kF16, "log"},
+        BuiltinData{BuiltinType::kLog2, CallParamType::kF32, "log2"},
+        BuiltinData{BuiltinType::kLog2, CallParamType::kF16, "log2"},
+        BuiltinData{BuiltinType::kMax, CallParamType::kF32, "fmax"},
+        BuiltinData{BuiltinType::kMax, CallParamType::kF16, "fmax"},
+        BuiltinData{BuiltinType::kMin, CallParamType::kF32, "fmin"},
+        BuiltinData{BuiltinType::kMin, CallParamType::kF16, "fmin"},
+        BuiltinData{BuiltinType::kNormalize, CallParamType::kF32, "normalize"},
+        BuiltinData{BuiltinType::kNormalize, CallParamType::kF16, "normalize"},
+        BuiltinData{BuiltinType::kPow, CallParamType::kF32, "pow"},
+        BuiltinData{BuiltinType::kPow, CallParamType::kF16, "pow"},
+        BuiltinData{BuiltinType::kReflect, CallParamType::kF32, "reflect"},
+        BuiltinData{BuiltinType::kReflect, CallParamType::kF16, "reflect"},
+        BuiltinData{BuiltinType::kSign, CallParamType::kF32, "sign"},
+        BuiltinData{BuiltinType::kSign, CallParamType::kF16, "sign"},
+        BuiltinData{BuiltinType::kSin, CallParamType::kF32, "sin"},
+        BuiltinData{BuiltinType::kSin, CallParamType::kF16, "sin"},
+        BuiltinData{BuiltinType::kSinh, CallParamType::kF32, "sinh"},
+        BuiltinData{BuiltinType::kSinh, CallParamType::kF16, "sinh"},
+        BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF32, "smoothstep"},
+        BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF16, "smoothstep"},
+        BuiltinData{BuiltinType::kSqrt, CallParamType::kF32, "sqrt"},
+        BuiltinData{BuiltinType::kSqrt, CallParamType::kF16, "sqrt"},
+        BuiltinData{BuiltinType::kStep, CallParamType::kF32, "step"},
+        BuiltinData{BuiltinType::kStep, CallParamType::kF16, "step"},
+        BuiltinData{BuiltinType::kTan, CallParamType::kF32, "tan"},
+        BuiltinData{BuiltinType::kTan, CallParamType::kF16, "tan"},
+        BuiltinData{BuiltinType::kTanh, CallParamType::kF32, "tanh"},
+        BuiltinData{BuiltinType::kTanh, CallParamType::kF16, "tanh"},
+        BuiltinData{BuiltinType::kTrunc, CallParamType::kF32, "trunc"},
+        BuiltinData{BuiltinType::kTrunc, CallParamType::kF16, "trunc"},
+        /* Integer built-in */
+        BuiltinData{BuiltinType::kAbs, CallParamType::kU32, "abs"},
+        BuiltinData{BuiltinType::kClamp, CallParamType::kU32, "clamp"},
+        BuiltinData{BuiltinType::kCountLeadingZeros, CallParamType::kU32, "clz"},
+        BuiltinData{BuiltinType::kCountOneBits, CallParamType::kU32, "popcount"},
+        BuiltinData{BuiltinType::kCountTrailingZeros, CallParamType::kU32, "ctz"},
+        BuiltinData{BuiltinType::kExtractBits, CallParamType::kU32, "extract_bits"},
+        BuiltinData{BuiltinType::kInsertBits, CallParamType::kU32, "insert_bits"},
+        BuiltinData{BuiltinType::kMax, CallParamType::kU32, "max"},
+        BuiltinData{BuiltinType::kMin, CallParamType::kU32, "min"},
+        BuiltinData{BuiltinType::kReverseBits, CallParamType::kU32, "reverse_bits"},
+        BuiltinData{BuiltinType::kRound, CallParamType::kU32, "rint"},
+        /* Matrix built-in */
+        BuiltinData{BuiltinType::kDeterminant, CallParamType::kF32, "determinant"},
+        BuiltinData{BuiltinType::kTranspose, CallParamType::kF32, "transpose"},
+        /* Vector built-in */
+        BuiltinData{BuiltinType::kDot, CallParamType::kF32, "dot"},
+        /* Derivate built-in */
+        BuiltinData{BuiltinType::kDpdx, CallParamType::kF32, "dfdx"},
+        BuiltinData{BuiltinType::kDpdxCoarse, CallParamType::kF32, "dfdx"},
+        BuiltinData{BuiltinType::kDpdxFine, CallParamType::kF32, "dfdx"},
+        BuiltinData{BuiltinType::kDpdy, CallParamType::kF32, "dfdy"},
+        BuiltinData{BuiltinType::kDpdyCoarse, CallParamType::kF32, "dfdy"},
+        BuiltinData{BuiltinType::kDpdyFine, CallParamType::kF32, "dfdy"},
+        BuiltinData{BuiltinType::kFwidth, CallParamType::kF32, "fwidth"},
+        BuiltinData{BuiltinType::kFwidthCoarse, CallParamType::kF32, "fwidth"},
+        BuiltinData{BuiltinType::kFwidthFine, CallParamType::kF32, "fwidth"},
+        /* Data packing builtin */
+        BuiltinData{BuiltinType::kPack4x8snorm, CallParamType::kF32, "pack_float_to_snorm4x8"},
+        BuiltinData{BuiltinType::kPack4x8unorm, CallParamType::kF32, "pack_float_to_unorm4x8"},
+        BuiltinData{BuiltinType::kPack2x16snorm, CallParamType::kF32, "pack_float_to_snorm2x16"},
+        BuiltinData{BuiltinType::kPack2x16unorm, CallParamType::kF32, "pack_float_to_unorm2x16"},
+        /* Data unpacking builtin */
+        BuiltinData{BuiltinType::kUnpack4x8snorm, CallParamType::kU32, "unpack_snorm4x8_to_float"},
+        BuiltinData{BuiltinType::kUnpack4x8unorm, CallParamType::kU32, "unpack_unorm4x8_to_float"},
+        BuiltinData{BuiltinType::kUnpack2x16snorm, CallParamType::kU32,
+                    "unpack_snorm2x16_to_float"},
+        BuiltinData{BuiltinType::kUnpack2x16unorm, CallParamType::kU32,
+                    "unpack_unorm2x16_to_float"}));
 
 TEST_F(MslGeneratorImplTest, Builtin_Call) {
     GlobalVar("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
@@ -308,12 +405,12 @@
     EXPECT_EQ(out.str(), "threadgroup_barrier(mem_flags::mem_threadgroup)");
 }
 
-TEST_F(MslGeneratorImplTest, Degrees_Scalar) {
+TEST_F(MslGeneratorImplTest, Degrees_Scalar_f32) {
     auto* val = Var("val", ty.f32());
     auto* call = Call("degrees", val);
     WrapInFunction(val, call);
 
-    GeneratorImpl& gen = Build();
+    GeneratorImpl& gen = SanitizeAndBuild();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
     EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
@@ -333,12 +430,12 @@
 )");
 }
 
-TEST_F(MslGeneratorImplTest, Degrees_Vector) {
+TEST_F(MslGeneratorImplTest, Degrees_Vector_f32) {
     auto* val = Var("val", ty.vec3<f32>());
     auto* call = Call("degrees", val);
     WrapInFunction(val, call);
 
-    GeneratorImpl& gen = Build();
+    GeneratorImpl& gen = SanitizeAndBuild();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
     EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
@@ -358,12 +455,66 @@
 )");
 }
 
-TEST_F(MslGeneratorImplTest, Radians_Scalar) {
+TEST_F(MslGeneratorImplTest, Degrees_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("degrees", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+half tint_degrees(half param_0) {
+  return param_0 * 57.295779513082322865;
+}
+
+kernel void test_function() {
+  half val = 0.0h;
+  half const tint_symbol = tint_degrees(val);
+  return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Degrees_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("degrees", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+half3 tint_degrees(half3 param_0) {
+  return param_0 * 57.295779513082322865;
+}
+
+kernel void test_function() {
+  half3 val = 0.0h;
+  half3 const tint_symbol = tint_degrees(val);
+  return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Radians_Scalar_f32) {
     auto* val = Var("val", ty.f32());
     auto* call = Call("radians", val);
     WrapInFunction(val, call);
 
-    GeneratorImpl& gen = Build();
+    GeneratorImpl& gen = SanitizeAndBuild();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
     EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
@@ -383,12 +534,12 @@
 )");
 }
 
-TEST_F(MslGeneratorImplTest, Radians_Vector) {
+TEST_F(MslGeneratorImplTest, Radians_Vector_f32) {
     auto* val = Var("val", ty.vec3<f32>());
     auto* call = Call("radians", val);
     WrapInFunction(val, call);
 
-    GeneratorImpl& gen = Build();
+    GeneratorImpl& gen = SanitizeAndBuild();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
     EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
@@ -408,6 +559,60 @@
 )");
 }
 
+TEST_F(MslGeneratorImplTest, Radians_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("radians", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+half tint_radians(half param_0) {
+  return param_0 * 0.017453292519943295474;
+}
+
+kernel void test_function() {
+  half val = 0.0h;
+  half const tint_symbol = tint_radians(val);
+  return;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Radians_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("radians", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+half3 tint_radians(half3 param_0) {
+  return param_0 * 0.017453292519943295474;
+}
+
+kernel void test_function() {
+  half3 val = 0.0h;
+  half3 const tint_symbol = tint_radians(val);
+  return;
+}
+
+)");
+}
+
 TEST_F(MslGeneratorImplTest, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
     GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 4ed4826..cb93784 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -38,6 +38,138 @@
     return out;
 }
 
+// This tests that we do not push OpTypeSampledImage and float_0 type twice.
+TEST_F(BuiltinBuilderTest, Call_TextureSampleCompare_Twice) {
+    auto* s = ty.sampler(ast::SamplerKind::kComparisonSampler);
+    auto* t = ty.depth_texture(ast::TextureDimension::k2d);
+
+    auto* tex = GlobalVar("texture", t,
+                          ast::AttributeList{
+                              create<ast::BindingAttribute>(0u),
+                              create<ast::GroupAttribute>(0u),
+                          });
+
+    auto* sampler = GlobalVar("sampler", s,
+                              ast::AttributeList{
+                                  create<ast::BindingAttribute>(1u),
+                                  create<ast::GroupAttribute>(0u),
+                              });
+
+    auto* expr1 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
+    auto* expr2 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
+
+    Func("f1", {}, ty.void_(), {CallStmt(expr1)}, {});
+    Func("f2", {}, ty.void_(), {CallStmt(expr2)}, {});
+
+    spirv::Builder& b = Build();
+
+    b.push_function(Function{});
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
+    ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
+
+    EXPECT_EQ(b.GenerateExpression(expr1), 8u) << b.error();
+    EXPECT_EQ(b.GenerateExpression(expr2), 17u) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 0 0 0 1 Unknown
+%2 = OpTypePointer UniformConstant %3
+%1 = OpVariable %2 UniformConstant
+%7 = OpTypeSampler
+%6 = OpTypePointer UniformConstant %7
+%5 = OpVariable %6 UniformConstant
+%11 = OpTypeSampledImage %3
+%13 = OpTypeVector %4 2
+%14 = OpConstant %4 1
+%15 = OpConstant %4 2
+%16 = OpConstantComposite %13 %14 %15
+)");
+
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+              R"(%9 = OpLoad %7 %5
+%10 = OpLoad %3 %1
+%12 = OpSampledImage %11 %10 %9
+%8 = OpImageSampleDrefImplicitLod %4 %12 %16 %15
+%18 = OpLoad %7 %5
+%19 = OpLoad %3 %1
+%20 = OpSampledImage %11 %19 %18
+%17 = OpImageSampleDrefImplicitLod %4 %20 %16 %15
+)");
+}
+
+TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f32) {
+    auto* var = GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
+    auto* expr = Call("round", "ident");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect =
+        R"(%10 = OpExtInstImport "GLSL.std.450"
+OpName %1 "ident"
+OpName %7 "a_func"
+%3 = OpTypeFloat 32
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+%7 = OpFunction %6 None %5
+%8 = OpLabel
+%11 = OpLoad %3 %1
+%9 = OpExtInst %3 %10 RoundEven %11
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* var = GlobalVar("ident", ty.f16(), ast::StorageClass::kPrivate);
+    auto* expr = Call("round", "ident");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect =
+        R"(%10 = OpExtInstImport "GLSL.std.450"
+OpName %1 "ident"
+OpName %7 "a_func"
+%3 = OpTypeFloat 16
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+%7 = OpFunction %6 None %5
+%8 = OpLabel
+%11 = OpLoad %3 %1
+%9 = OpExtInst %3 %10 RoundEven %11
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+// Tests for Logical builtins
+namespace logical_builtin_tests {
+
 using BuiltinBoolTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinBoolTest, Call_Bool_Scalar) {
     auto param = GetParam();
@@ -99,315 +231,6 @@
                          BuiltinBoolTest,
                          testing::Values(BuiltinData{"any", "OpAny"}, BuiltinData{"all", "OpAll"}));
 
-using BuiltinIntTest = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(BuiltinIntTest, Call_SInt_Scalar) {
-    auto param = GetParam();
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* expr = Call(param.name, "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
-%2 = OpTypePointer Private %3
-%4 = OpConstantNull %3
-%1 = OpVariable %2 Private %4
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-)");
-
-    auto expected = utils::ReplaceAll(R"(%10 = OpLoad %3 %1
-%9 = ${op} %3 %10
-OpReturn
-)",
-                                      "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
-}
-
-TEST_P(BuiltinIntTest, Call_SInt_Vector) {
-    auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call(param.name, "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Private %3
-%5 = OpConstantNull %3
-%1 = OpVariable %2 Private %5
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-)");
-
-    auto expected = utils::ReplaceAll(R"(%11 = OpLoad %3 %1
-%10 = ${op} %3 %11
-OpReturn
-)",
-                                      "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
-}
-
-TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
-    auto param = GetParam();
-    auto* var = GlobalVar("v", ty.u32(), ast::StorageClass::kPrivate);
-    auto* expr = Call(param.name, "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 0
-%2 = OpTypePointer Private %3
-%4 = OpConstantNull %3
-%1 = OpVariable %2 Private %4
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-)");
-
-    auto expected = utils::ReplaceAll(R"(%10 = OpLoad %3 %1
-%9 = ${op} %3 %10
-OpReturn
-)",
-                                      "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
-}
-
-TEST_P(BuiltinIntTest, Call_UInt_Vector) {
-    auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call(param.name, "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Private %3
-%5 = OpConstantNull %3
-%1 = OpVariable %2 Private %5
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-)");
-
-    auto expected = utils::ReplaceAll(R"(%11 = OpLoad %3 %1
-%10 = ${op} %3 %11
-OpReturn
-)",
-                                      "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         BuiltinIntTest,
-                         testing::Values(BuiltinData{"countOneBits", "OpBitCount"},
-                                         BuiltinData{"reverseBits", "OpBitReverse"}));
-
-TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
-    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call("dot", "v", "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Private %3
-%5 = OpConstantNull %3
-%1 = OpVariable %2 Private %5
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-)");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
-              R"(%11 = OpLoad %3 %1
-%12 = OpLoad %3 %1
-%10 = OpDot %4 %11 %12
-OpReturn
-)");
-}
-
-TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
-    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call("dot", "v", "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Private %3
-%5 = OpConstantNull %3
-%1 = OpVariable %2 Private %5
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-)");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
-              R"(%11 = OpLoad %3 %1
-%12 = OpLoad %3 %1
-%13 = OpCompositeExtract %4 %11 0
-%14 = OpCompositeExtract %4 %12 0
-%15 = OpIMul %4 %13 %14
-%16 = OpCompositeExtract %4 %11 1
-%17 = OpCompositeExtract %4 %12 1
-%18 = OpIMul %4 %16 %17
-%19 = OpIAdd %4 %15 %18
-%20 = OpCompositeExtract %4 %11 2
-%21 = OpCompositeExtract %4 %12 2
-%22 = OpIMul %4 %20 %21
-%10 = OpIAdd %4 %19 %22
-OpReturn
-)");
-}
-
-TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
-    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call("dot", "v", "v");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Private %3
-%5 = OpConstantNull %3
-%1 = OpVariable %2 Private %5
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-)");
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
-              R"(%11 = OpLoad %3 %1
-%12 = OpLoad %3 %1
-%13 = OpCompositeExtract %4 %11 0
-%14 = OpCompositeExtract %4 %12 0
-%15 = OpIMul %4 %13 %14
-%16 = OpCompositeExtract %4 %11 1
-%17 = OpCompositeExtract %4 %12 1
-%18 = OpIMul %4 %16 %17
-%19 = OpIAdd %4 %15 %18
-%20 = OpCompositeExtract %4 %11 2
-%21 = OpCompositeExtract %4 %12 2
-%22 = OpIMul %4 %20 %21
-%10 = OpIAdd %4 %19 %22
-OpReturn
-)");
-}
-
-using BuiltinDeriveTest = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(BuiltinDeriveTest, Call_Derivative_Scalar) {
-    auto param = GetParam();
-    auto* var = GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate);
-    auto* expr = Call(param.name, "v");
-    auto* func =
-        Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
-%2 = OpTypePointer Private %3
-%4 = OpConstantNull %3
-%1 = OpVariable %2 Private %4
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-)");
-
-    auto expected = utils::ReplaceAll(R"(%10 = OpLoad %3 %1
-%9 = ${op} %3 %10
-OpReturn
-)",
-                                      "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
-}
-
-TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
-    auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call(param.name, "v");
-    auto* func =
-        Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    if (param.name != "dpdx" && param.name != "dpdy" && param.name != "fwidth") {
-        EXPECT_EQ(DumpInstructions(b.capabilities()),
-                  R"(OpCapability DerivativeControl
-)");
-    }
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Private %3
-%5 = OpConstantNull %3
-%1 = OpVariable %2 Private %5
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-)");
-
-    auto expected = utils::ReplaceAll(R"(%11 = OpLoad %3 %1
-%10 = ${op} %3 %11
-OpReturn
-)",
-                                      "${op}", param.op);
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         BuiltinDeriveTest,
-                         testing::Values(BuiltinData{"dpdx", "OpDPdx"},
-                                         BuiltinData{"dpdxFine", "OpDPdxFine"},
-                                         BuiltinData{"dpdxCoarse", "OpDPdxCoarse"},
-                                         BuiltinData{"dpdy", "OpDPdy"},
-                                         BuiltinData{"dpdyFine", "OpDPdyFine"},
-                                         BuiltinData{"dpdyCoarse", "OpDPdyCoarse"},
-                                         BuiltinData{"fwidth", "OpFwidth"},
-                                         BuiltinData{"fwidthFine", "OpFwidthFine"},
-                                         BuiltinData{"fwidthCoarse", "OpFwidthCoarse"}));
-
 TEST_F(BuiltinBuilderTest, Call_Select) {
     auto* v3 = GlobalVar("v3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
 
@@ -446,1190 +269,10 @@
 )");
 }
 
-// This tests that we do not push OpTypeSampledImage and float_0 type twice.
-TEST_F(BuiltinBuilderTest, Call_TextureSampleCompare_Twice) {
-    auto* s = ty.sampler(ast::SamplerKind::kComparisonSampler);
-    auto* t = ty.depth_texture(ast::TextureDimension::k2d);
+}  // namespace logical_builtin_tests
 
-    auto* tex = GlobalVar("texture", t,
-                          ast::AttributeList{
-                              create<ast::BindingAttribute>(0u),
-                              create<ast::GroupAttribute>(0u),
-                          });
-
-    auto* sampler = GlobalVar("sampler", s,
-                              ast::AttributeList{
-                                  create<ast::BindingAttribute>(1u),
-                                  create<ast::GroupAttribute>(0u),
-                              });
-
-    auto* expr1 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
-    auto* expr2 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
-
-    Func("f1", {}, ty.void_(), {CallStmt(expr1)}, {});
-    Func("f2", {}, ty.void_(), {CallStmt(expr2)}, {});
-
-    spirv::Builder& b = Build();
-
-    b.push_function(Function{});
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
-    ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
-
-    EXPECT_EQ(b.GenerateExpression(expr1), 8u) << b.error();
-    EXPECT_EQ(b.GenerateExpression(expr2), 17u) << b.error();
-
-    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeImage %4 2D 0 0 0 1 Unknown
-%2 = OpTypePointer UniformConstant %3
-%1 = OpVariable %2 UniformConstant
-%7 = OpTypeSampler
-%6 = OpTypePointer UniformConstant %7
-%5 = OpVariable %6 UniformConstant
-%11 = OpTypeSampledImage %3
-%13 = OpTypeVector %4 2
-%14 = OpConstant %4 1
-%15 = OpConstant %4 2
-%16 = OpConstantComposite %13 %14 %15
-)");
-
-    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
-              R"(%9 = OpLoad %7 %5
-%10 = OpLoad %3 %1
-%12 = OpSampledImage %11 %10 %9
-%8 = OpImageSampleDrefImplicitLod %4 %12 %16 %15
-%18 = OpLoad %7 %5
-%19 = OpLoad %3 %1
-%20 = OpSampledImage %11 %19 %18
-%17 = OpImageSampleDrefImplicitLod %4 %20 %16 %15
-)");
-}
-
-TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad) {
-    auto* var = GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
-    auto* expr = Call("round", "ident");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect =
-        R"(%10 = OpExtInstImport "GLSL.std.450"
-OpName %1 "ident"
-OpName %7 "a_func"
-%3 = OpTypeFloat 32
-%2 = OpTypePointer Private %3
-%4 = OpConstantNull %3
-%1 = OpVariable %2 Private %4
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-%7 = OpFunction %6 None %5
-%8 = OpLabel
-%11 = OpLoad %3 %1
-%9 = OpExtInst %3 %10 RoundEven %11
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-using Builtin_Builtin_SingleParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_SingleParam_Float_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* expr = Call(param.name, 1_f);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%8 = OpConstant %6 1
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 )" +
-                  param.op +
-                  R"( %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_SingleParam_Float_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* expr = Call(param.name, vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%9 = OpConstant %7 1
-%10 = OpConstantComposite %6 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %8 )" +
-                  param.op +
-                  R"( %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_SingleParam_Float_Test,
-                         testing::Values(BuiltinData{"abs", "FAbs"},
-                                         BuiltinData{"acos", "Acos"},
-                                         BuiltinData{"asin", "Asin"},
-                                         BuiltinData{"atan", "Atan"},
-                                         BuiltinData{"ceil", "Ceil"},
-                                         BuiltinData{"cos", "Cos"},
-                                         BuiltinData{"cosh", "Cosh"},
-                                         BuiltinData{"degrees", "Degrees"},
-                                         BuiltinData{"exp", "Exp"},
-                                         BuiltinData{"exp2", "Exp2"},
-                                         BuiltinData{"floor", "Floor"},
-                                         BuiltinData{"fract", "Fract"},
-                                         BuiltinData{"inverseSqrt", "InverseSqrt"},
-                                         BuiltinData{"log", "Log"},
-                                         BuiltinData{"log2", "Log2"},
-                                         BuiltinData{"radians", "Radians"},
-                                         BuiltinData{"round", "RoundEven"},
-                                         BuiltinData{"sign", "FSign"},
-                                         BuiltinData{"sin", "Sin"},
-                                         BuiltinData{"sinh", "Sinh"},
-                                         BuiltinData{"sqrt", "Sqrt"},
-                                         BuiltinData{"tan", "Tan"},
-                                         BuiltinData{"tanh", "Tanh"},
-                                         BuiltinData{"trunc", "Trunc"}));
-
-TEST_F(BuiltinBuilderTest, Call_Length_Scalar) {
-    auto* expr = Call("length", 1_f);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%8 = OpConstant %6 1
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 Length %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Length_Vector) {
-    auto* expr = Call("length", vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%8 = OpTypeVector %6 2
-%9 = OpConstant %6 1
-%10 = OpConstantComposite %8 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 Length %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Normalize) {
-    auto* expr = Call("normalize", vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%9 = OpConstant %7 1
-%10 = OpConstantComposite %6 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %8 Normalize %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-using Builtin_Builtin_DualParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_DualParam_Float_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* scalar = Var("scalar", nullptr, Expr(1_f));
-    auto* expr = Call(param.name, scalar, scalar);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Decl(scalar),
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %7 "scalar"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = OpTypeFloat 32
-%6 = OpConstant %5 1
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%7 = OpVariable %8 Function %9
-OpStore %7 %6
-%12 = OpLoad %5 %7
-%13 = OpLoad %5 %7
-%10 = OpExtInst %5 %11 )" +
-                  param.op +
-                  R"( %12 %13
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_DualParam_Float_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
-    auto* expr = Call(param.name, vec, vec);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Decl(vec),
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %9 "vec"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%5 = OpTypeVector %6 2
-%7 = OpConstant %6 1
-%8 = OpConstantComposite %5 %7 %7
-%10 = OpTypePointer Function %5
-%11 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVariable %10 Function %11
-OpStore %9 %8
-%14 = OpLoad %5 %9
-%15 = OpLoad %5 %9
-%12 = OpExtInst %5 %13 )" +
-                  param.op +
-                  R"( %14 %15
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_DualParam_Float_Test,
-                         testing::Values(BuiltinData{"atan2", "Atan2"},
-                                         BuiltinData{"max", "NMax"},
-                                         BuiltinData{"min", "NMin"},
-                                         BuiltinData{"pow", "Pow"},
-                                         BuiltinData{"step", "Step"}));
-
-TEST_F(BuiltinBuilderTest, Call_Reflect_Vector) {
-    auto* expr = Call("reflect", vec2<f32>(1_f, 1_f), vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%9 = OpConstant %7 1
-%10 = OpConstantComposite %6 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %8 Reflect %10 %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Distance_Scalar) {
-    auto* expr = Call("distance", 1_f, 1_f);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%8 = OpConstant %6 1
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 Distance %8 %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Distance_Vector) {
-    auto* expr = Call("distance", vec2<f32>(1_f, 1_f), vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%8 = OpTypeVector %6 2
-%9 = OpConstant %6 1
-%10 = OpConstantComposite %8 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 Distance %10 %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Cross) {
-    auto* expr = Call("cross", vec3<f32>(1_f, 1_f, 1_f), vec3<f32>(1_f, 1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 3
-%9 = OpConstant %7 1
-%10 = OpConstantComposite %6 %9 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %8 Cross %10 %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-using Builtin_Builtin_ThreeParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_ThreeParam_Float_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* decl = Decl(Var("a", nullptr, Expr(1_f)));
-    auto* expr = Call(param.name, Expr("a"), 1_f, 1_f);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          decl,
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %7 "a"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = OpTypeFloat 32
-%6 = OpConstant %5 1
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%7 = OpVariable %8 Function %9
-OpStore %7 %6
-%12 = OpLoad %5 %7
-%10 = OpExtInst %5 %11 )" +
-                  param.op +
-                  R"( %12 %6 %6
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_ThreeParam_Float_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* decl = Decl(Var("a", nullptr, vec2<f32>(1_f, 1_f)));
-    auto* expr = Call(param.name, Expr("a"), vec2<f32>(1_f, 1_f), vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          decl,
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %9 "a"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%5 = OpTypeVector %6 2
-%7 = OpConstant %6 1
-%8 = OpConstantComposite %5 %7 %7
-%10 = OpTypePointer Function %5
-%11 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVariable %10 Function %11
-OpStore %9 %8
-%14 = OpLoad %5 %9
-%12 = OpExtInst %5 %13 )" +
-                  param.op +
-                  R"( %14 %8 %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_ThreeParam_Float_Test,
-                         testing::Values(BuiltinData{"clamp", "NClamp"},
-                                         BuiltinData{"fma", "Fma"},
-                                         BuiltinData{"mix", "FMix"},
-
-                                         BuiltinData{"smoothstep", "SmoothStep"}));
-
-TEST_F(BuiltinBuilderTest, Call_FaceForward_Vector) {
-    auto* expr = Call("faceForward", vec2<f32>(1_f, 1_f), vec2<f32>(1_f, 1_f), vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%9 = OpConstant %7 1
-%10 = OpConstantComposite %6 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %8 FaceForward %10 %10 %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-using Builtin_Builtin_SingleParam_Sint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_SingleParam_Sint_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* expr = Call(param.name, 1_i);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 1
-%8 = OpConstant %6 1
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 )" +
-                  param.op +
-                  R"( %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_SingleParam_Sint_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* expr = Call(param.name, vec2<i32>(1_i, 1_i));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeInt 32 1
-%6 = OpTypeVector %7 2
-%9 = OpConstant %7 1
-%10 = OpConstantComposite %6 %9 %9
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %8 )" +
-                  param.op +
-                  R"( %10
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_SingleParam_Sint_Test,
-                         testing::Values(BuiltinData{"abs", "SAbs"}));
-
-// Calling abs() on an unsigned integer scalar / vector is a no-op.
-using Builtin_Builtin_Abs_Uint_Test = BuiltinBuilderTest;
-TEST_F(Builtin_Builtin_Abs_Uint_Test, Call_Scalar) {
-    auto* expr = Call("abs", Expr(1_u));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 1
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(Builtin_Builtin_Abs_Uint_Test, Call_Vector) {
-    auto* expr = Call("abs", vec2<u32>(1_u, 1_u));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeInt 32 0
-%6 = OpTypeVector %7 2
-%8 = OpConstant %7 1
-%9 = OpConstantComposite %6 %8 %8
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-using Builtin_Builtin_DualParam_SInt_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_DualParam_SInt_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* scalar = Var("scalar", nullptr, Expr(1_i));
-    auto* expr = Call(param.name, scalar, scalar);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Decl(scalar),
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %7 "scalar"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = OpTypeInt 32 1
-%6 = OpConstant %5 1
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%7 = OpVariable %8 Function %9
-OpStore %7 %6
-%12 = OpLoad %5 %7
-%13 = OpLoad %5 %7
-%10 = OpExtInst %5 %11 )" +
-                  param.op +
-                  R"( %12 %13
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_DualParam_SInt_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
-    auto* expr = Call(param.name, vec, vec);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Decl(vec),
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %9 "vec"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 1
-%5 = OpTypeVector %6 2
-%7 = OpConstant %6 1
-%8 = OpConstantComposite %5 %7 %7
-%10 = OpTypePointer Function %5
-%11 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVariable %10 Function %11
-OpStore %9 %8
-%14 = OpLoad %5 %9
-%15 = OpLoad %5 %9
-%12 = OpExtInst %5 %13 )" +
-                  param.op +
-                  R"( %14 %15
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_DualParam_SInt_Test,
-                         testing::Values(BuiltinData{"max", "SMax"}, BuiltinData{"min", "SMin"}));
-
-using Builtin_Builtin_DualParam_UInt_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_DualParam_UInt_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* scalar = Var("scalar", nullptr, Expr(1_u));
-    auto* expr = Call(param.name, scalar, scalar);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Decl(scalar),
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %7 "scalar"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = OpTypeInt 32 0
-%6 = OpConstant %5 1
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%7 = OpVariable %8 Function %9
-OpStore %7 %6
-%12 = OpLoad %5 %7
-%13 = OpLoad %5 %7
-%10 = OpExtInst %5 %11 )" +
-                  param.op +
-                  R"( %12 %13
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_DualParam_UInt_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* vec = Var("vec", nullptr, vec2<u32>(1_u, 1_u));
-    auto* expr = Call(param.name, vec, vec);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Decl(vec),
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %9 "vec"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%5 = OpTypeVector %6 2
-%7 = OpConstant %6 1
-%8 = OpConstantComposite %5 %7 %7
-%10 = OpTypePointer Function %5
-%11 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVariable %10 Function %11
-OpStore %9 %8
-%14 = OpLoad %5 %9
-%15 = OpLoad %5 %9
-%12 = OpExtInst %5 %13 )" +
-                  param.op +
-                  R"( %14 %15
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_DualParam_UInt_Test,
-                         testing::Values(BuiltinData{"max", "UMax"}, BuiltinData{"min", "UMin"}));
-
-using Builtin_Builtin_ThreeParam_Sint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_ThreeParam_Sint_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* decl = Decl(Var("a", nullptr, Expr(1_i)));
-    auto* expr = Call(param.name, Expr("a"), 1_i, 1_i);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          decl,
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %7 "a"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = OpTypeInt 32 1
-%6 = OpConstant %5 1
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%7 = OpVariable %8 Function %9
-OpStore %7 %6
-%12 = OpLoad %5 %7
-%10 = OpExtInst %5 %11 )" +
-                  param.op +
-                  R"( %12 %6 %6
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_ThreeParam_Sint_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* decl = Decl(Var("a", nullptr, vec2<i32>(1_i, 1_i)));
-    auto* expr = Call(param.name, Expr("a"), vec2<i32>(1_i, 1_i), vec2<i32>(1_i, 1_i));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          decl,
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %9 "a"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 1
-%5 = OpTypeVector %6 2
-%7 = OpConstant %6 1
-%8 = OpConstantComposite %5 %7 %7
-%10 = OpTypePointer Function %5
-%11 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVariable %10 Function %11
-OpStore %9 %8
-%14 = OpLoad %5 %9
-%12 = OpExtInst %5 %13 )" +
-                  param.op +
-                  R"( %14 %8 %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_ThreeParam_Sint_Test,
-                         testing::Values(BuiltinData{"clamp", "SClamp"}));
-
-using Builtin_Builtin_ThreeParam_Uint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_ThreeParam_Uint_Test, Call_Scalar) {
-    auto param = GetParam();
-    auto* decl = Decl(Var("a", nullptr, Expr(1_u)));
-    auto* expr = Call(param.name, Expr("a"), 1_u, 1_u);
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          decl,
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %7 "a"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%5 = OpTypeInt 32 0
-%6 = OpConstant %5 1
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%7 = OpVariable %8 Function %9
-OpStore %7 %6
-%12 = OpLoad %5 %7
-%10 = OpExtInst %5 %11 )" +
-                  param.op +
-                  R"( %12 %6 %6
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_P(Builtin_Builtin_ThreeParam_Uint_Test, Call_Vector) {
-    auto param = GetParam();
-    auto* decl = Decl(Var("a", nullptr, vec2<u32>(1_u, 1_u)));
-    auto* expr = Call(param.name, Expr("a"), vec2<u32>(1_u, 1_u), vec2<u32>(1_u, 1_u));
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          decl,
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-OpName %9 "a"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%5 = OpTypeVector %6 2
-%7 = OpConstant %6 1
-%8 = OpConstantComposite %5 %7 %7
-%10 = OpTypePointer Function %5
-%11 = OpConstantNull %5
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%9 = OpVariable %10 Function %11
-OpStore %9 %8
-%14 = OpLoad %5 %9
-%12 = OpExtInst %5 %13 )" +
-                  param.op +
-                  R"( %14 %8 %8
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_ThreeParam_Uint_Test,
-                         testing::Values(BuiltinData{"clamp", "UClamp"}));
-
-TEST_F(BuiltinBuilderTest, Call_Modf) {
-    auto* expr = Call("modf", vec2<f32>(1_f, 2_f));
-    Func("a_func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-    auto got = DumpBuilder(b);
-    auto* expect = R"(OpCapability Shader
-%9 = OpExtInstImport "GLSL.std.450"
-OpMemoryModel Logical GLSL450
-OpEntryPoint Fragment %3 "a_func"
-OpExecutionMode %3 OriginUpperLeft
-OpName %3 "a_func"
-OpName %6 "__modf_result_vec2"
-OpMemberName %6 0 "fract"
-OpMemberName %6 1 "whole"
-OpMemberDecorate %6 0 Offset 0
-OpMemberDecorate %6 1 Offset 8
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%8 = OpTypeFloat 32
-%7 = OpTypeVector %8 2
-%6 = OpTypeStruct %7 %7
-%10 = OpConstant %8 1
-%11 = OpConstant %8 2
-%12 = OpConstantComposite %7 %10 %11
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %9 ModfStruct %12
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(expect, got);
-
-    Validate(b);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Frexp) {
-    auto* expr = Call("frexp", vec2<f32>(1_f, 2_f));
-    Func("a_func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-    auto got = DumpBuilder(b);
-    auto* expect = R"(OpCapability Shader
-%11 = OpExtInstImport "GLSL.std.450"
-OpMemoryModel Logical GLSL450
-OpEntryPoint Fragment %3 "a_func"
-OpExecutionMode %3 OriginUpperLeft
-OpName %3 "a_func"
-OpName %6 "__frexp_result_vec2"
-OpMemberName %6 0 "sig"
-OpMemberName %6 1 "exp"
-OpMemberDecorate %6 0 Offset 0
-OpMemberDecorate %6 1 Offset 8
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%8 = OpTypeFloat 32
-%7 = OpTypeVector %8 2
-%10 = OpTypeInt 32 1
-%9 = OpTypeVector %10 2
-%6 = OpTypeStruct %7 %9
-%12 = OpConstant %8 1
-%13 = OpConstant %8 2
-%14 = OpConstantComposite %7 %12 %13
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %11 FrexpStruct %14
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(expect, got);
-
-    Validate(b);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Determinant) {
-    auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call("determinant", "var");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(%12 = OpExtInstImport "GLSL.std.450"
-OpName %1 "var"
-OpName %9 "a_func"
-%5 = OpTypeFloat 32
-%4 = OpTypeVector %5 3
-%3 = OpTypeMatrix %4 3
-%2 = OpTypePointer Private %3
-%6 = OpConstantNull %3
-%1 = OpVariable %2 Private %6
-%8 = OpTypeVoid
-%7 = OpTypeFunction %8
-%9 = OpFunction %8 None %7
-%10 = OpLabel
-%13 = OpLoad %3 %1
-%11 = OpExtInst %5 %12 Determinant %13
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
-
-TEST_F(BuiltinBuilderTest, Call_Transpose) {
-    auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
-    auto* expr = Call("transpose", "var");
-    auto* func = Func("a_func", {}, ty.void_(),
-                      {
-                          Assign(Phony(), expr),
-                      });
-
-    spirv::Builder& b = Build();
-
-    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
-    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
-
-    auto got = DumpBuilder(b);
-    auto expect = R"(OpName %1 "var"
-OpName %9 "a_func"
-%5 = OpTypeFloat 32
-%4 = OpTypeVector %5 3
-%3 = OpTypeMatrix %4 2
-%2 = OpTypePointer Private %3
-%6 = OpConstantNull %3
-%1 = OpVariable %2 Private %6
-%8 = OpTypeVoid
-%7 = OpTypeFunction %8
-%13 = OpTypeVector %5 2
-%12 = OpTypeMatrix %13 3
-%9 = OpFunction %8 None %7
-%10 = OpLabel
-%14 = OpLoad %3 %1
-%11 = OpTranspose %12 %14
-OpReturn
-OpFunctionEnd
-)";
-    EXPECT_EQ(got, expect);
-}
+// Tests for Array builtins
+namespace array_builtin_tests {
 
 TEST_F(BuiltinBuilderTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
@@ -1833,635 +476,1885 @@
     Validate(b);
 }
 
-TEST_F(BuiltinBuilderTest, Call_AtomicLoad) {
-    // struct S {
-    //   u : atomic<u32>;
-    //   i : atomic<i32>;
-    // }
-    //
-    // @binding(1) @group(2) var<storage, read_write> b : S;
-    //
-    // fn a_func() {
-    //   let u : u32 = atomicLoad(&b.u);
-    //   let i : i32 = atomicLoad(&b.i);
-    // }
-    auto* s = Structure("S", {
-                                 Member("u", ty.atomic<u32>()),
-                                 Member("i", ty.atomic<i32>()),
-                             });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
-              ast::AttributeList{
-                  create<ast::BindingAttribute>(1u),
-                  create<ast::GroupAttribute>(2u),
-              });
+}  // namespace array_builtin_tests
 
-    Func("a_func", {}, ty.void_(),
-         ast::StatementList{
-             Decl(Let("u", ty.u32(), Call("atomicLoad", AddressOf(MemberAccessor("b", "u"))))),
-             Decl(Let("i", ty.i32(), Call("atomicLoad", AddressOf(MemberAccessor("b", "i"))))),
-         },
-         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+// Tests for Numeric builtins with float parameter
+namespace float_builtin_tests {
 
-    spirv::Builder& b = SanitizeAndBuild();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
-%2 = OpTypePointer StorageBuffer %3
-%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%11 = OpConstant %4 1
-%12 = OpConstant %4 0
-%14 = OpTypePointer StorageBuffer %4
-%18 = OpTypePointer StorageBuffer %5
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    auto* expected_instructions = R"(%15 = OpAccessChain %14 %1 %12
-%10 = OpAtomicLoad %4 %15 %11 %12
-%19 = OpAccessChain %18 %1 %11
-%16 = OpAtomicLoad %5 %19 %11 %12
-OpReturn
-)";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
-
-    Validate(b);
-}
-
-TEST_F(BuiltinBuilderTest, Call_AtomicStore) {
-    // struct S {
-    //   u : atomic<u32>;
-    //   i : atomic<i32>;
-    // }
-    //
-    // @binding(1) @group(2) var<storage, read_write> b : S;
-    //
-    // fn a_func() {
-    //   var u = 1_u;
-    //   var i = 2;
-    //   atomicStore(&b.u, u);
-    //   atomicStore(&b.i, i);
-    // }
-    auto* s = Structure("S", {
-                                 Member("u", ty.atomic<u32>()),
-                                 Member("i", ty.atomic<i32>()),
-                             });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
-              ast::AttributeList{
-                  create<ast::BindingAttribute>(1u),
-                  create<ast::GroupAttribute>(2u),
-              });
-
-    Func("a_func", {}, ty.void_(),
-         ast::StatementList{
-             Decl(Var("u", nullptr, Expr(1_u))),
-             Decl(Var("i", nullptr, Expr(2_i))),
-             CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "u")), "u")),
-             CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "i")), "i")),
-         },
-         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = SanitizeAndBuild();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
-%2 = OpTypePointer StorageBuffer %3
-%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%10 = OpConstant %4 1
-%12 = OpTypePointer Function %4
-%13 = OpConstantNull %4
-%14 = OpConstant %5 2
-%16 = OpTypePointer Function %5
-%17 = OpConstantNull %5
-%19 = OpConstant %4 0
-%21 = OpTypePointer StorageBuffer %4
-%26 = OpTypePointer StorageBuffer %5
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    auto* expected_instructions = R"(OpStore %11 %10
-OpStore %15 %14
-%22 = OpAccessChain %21 %1 %19
-%23 = OpLoad %4 %11
-OpAtomicStore %22 %10 %19 %23
-%27 = OpAccessChain %26 %1 %10
-%28 = OpLoad %5 %15
-OpAtomicStore %27 %10 %19 %28
-OpReturn
-)";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
-
-    Validate(b);
-}
-
-using Builtin_Builtin_AtomicRMW_i32 = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_AtomicRMW_i32, Test) {
-    // struct S {
-    //   v : atomic<i32>;
-    // }
-    //
-    // @binding(1) @group(2) var<storage, read_write> b : S;
-    //
-    // fn a_func() {
-    //   var v = 10;
-    //   let x : i32 = atomicOP(&b.v, v);
-    // }
-    auto* s = Structure("S", {
-                                 Member("v", ty.atomic<i32>()),
-                             });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
-              ast::AttributeList{
-                  create<ast::BindingAttribute>(1u),
-                  create<ast::GroupAttribute>(2u),
-              });
-
-    Func("a_func", {}, ty.void_(),
-         ast::StatementList{
-             Decl(Var("v", nullptr, Expr(10_i))),
-             Decl(Let("x", ty.i32(),
-                      Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
-         },
-         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = SanitizeAndBuild();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    std::string expected_types = R"(%4 = OpTypeInt 32 1
-%3 = OpTypeStruct %4
-%2 = OpTypePointer StorageBuffer %3
-%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-%9 = OpConstant %4 10
-%11 = OpTypePointer Function %4
-%12 = OpConstantNull %4
-%14 = OpTypeInt 32 0
-%15 = OpConstant %14 1
-%16 = OpConstant %14 0
-%18 = OpTypePointer StorageBuffer %4
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    std::string expected_instructions = R"(OpStore %10 %9
-%19 = OpAccessChain %18 %1 %16
-%20 = OpLoad %4 %10
-)";
-    expected_instructions += "%13 = " + GetParam().op + " %4 %19 %15 %16 %20\n";
-    expected_instructions += "OpReturn\n";
-
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
-
-    Validate(b);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_AtomicRMW_i32,
-                         testing::Values(BuiltinData{"atomicAdd", "OpAtomicIAdd"},
-                                         BuiltinData{"atomicMax", "OpAtomicSMax"},
-                                         BuiltinData{"atomicMin", "OpAtomicSMin"},
-                                         BuiltinData{"atomicAnd", "OpAtomicAnd"},
-                                         BuiltinData{"atomicOr", "OpAtomicOr"},
-                                         BuiltinData{"atomicXor", "OpAtomicXor"}));
-
-using Builtin_Builtin_AtomicRMW_u32 = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_AtomicRMW_u32, Test) {
-    // struct S {
-    //   v : atomic<u32>;
-    // }
-    //
-    // @binding(1) @group(2) var<storage, read_write> b : S;
-    //
-    // fn a_func() {
-    //   var v = 10u;
-    //   let x : u32 = atomicOP(&b.v, v);
-    // }
-    auto* s = Structure("S", {
-                                 Member("v", ty.atomic<u32>()),
-                             });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
-              ast::AttributeList{
-                  create<ast::BindingAttribute>(1u),
-                  create<ast::GroupAttribute>(2u),
-              });
-
-    Func("a_func", {}, ty.void_(),
-         ast::StatementList{
-             Decl(Var("v", nullptr, Expr(10_u))),
-             Decl(Let("x", ty.u32(),
-                      Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
-         },
-         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = SanitizeAndBuild();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    std::string expected_types = R"(%4 = OpTypeInt 32 0
-%3 = OpTypeStruct %4
-%2 = OpTypePointer StorageBuffer %3
-%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-%9 = OpConstant %4 10
-%11 = OpTypePointer Function %4
-%12 = OpConstantNull %4
-%14 = OpConstant %4 1
-%15 = OpConstant %4 0
-%17 = OpTypePointer StorageBuffer %4
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    std::string expected_instructions = R"(OpStore %10 %9
-%18 = OpAccessChain %17 %1 %15
-%19 = OpLoad %4 %10
-)";
-    expected_instructions += "%13 = " + GetParam().op + " %4 %18 %14 %15 %19\n";
-    expected_instructions += "OpReturn\n";
-
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
-
-    Validate(b);
-}
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_AtomicRMW_u32,
-                         testing::Values(BuiltinData{"atomicAdd", "OpAtomicIAdd"},
-                                         BuiltinData{"atomicMax", "OpAtomicUMax"},
-                                         BuiltinData{"atomicMin", "OpAtomicUMin"},
-                                         BuiltinData{"atomicAnd", "OpAtomicAnd"},
-                                         BuiltinData{"atomicOr", "OpAtomicOr"},
-                                         BuiltinData{"atomicXor", "OpAtomicXor"}));
-
-TEST_F(BuiltinBuilderTest, Call_AtomicExchange) {
-    // struct S {
-    //   u : atomic<u32>;
-    //   i : atomic<i32>;
-    // }
-    //
-    // @binding(1) @group(2) var<storage, read_write> b : S;
-    //
-    // fn a_func() {
-    //   var u = 10u;
-    //   var i = 10i;
-    //   let r : u32 = atomicExchange(&b.u, u);
-    //   let s : i32 = atomicExchange(&b.i, i);
-    // }
-    auto* s = Structure("S", {
-                                 Member("u", ty.atomic<u32>()),
-                                 Member("i", ty.atomic<i32>()),
-                             });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
-              ast::AttributeList{
-                  create<ast::BindingAttribute>(1u),
-                  create<ast::GroupAttribute>(2u),
-              });
-
-    Func("a_func", {}, ty.void_(),
-         ast::StatementList{
-             Decl(Var("u", nullptr, Expr(10_u))),
-             Decl(Var("i", nullptr, Expr(10_i))),
-             Decl(Let("r", ty.u32(),
-                      Call("atomicExchange", AddressOf(MemberAccessor("b", "u")), "u"))),
-             Decl(Let("s", ty.i32(),
-                      Call("atomicExchange", AddressOf(MemberAccessor("b", "i")), "i"))),
-         },
-         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = SanitizeAndBuild();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
-%2 = OpTypePointer StorageBuffer %3
-%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%10 = OpConstant %4 10
-%12 = OpTypePointer Function %4
-%13 = OpConstantNull %4
-%14 = OpConstant %5 10
-%16 = OpTypePointer Function %5
-%17 = OpConstantNull %5
-%19 = OpConstant %4 1
-%20 = OpConstant %4 0
-%22 = OpTypePointer StorageBuffer %4
-%27 = OpTypePointer StorageBuffer %5
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    auto* expected_instructions = R"(OpStore %11 %10
-OpStore %15 %14
-%23 = OpAccessChain %22 %1 %20
-%24 = OpLoad %4 %11
-%18 = OpAtomicExchange %4 %23 %19 %20 %24
-%28 = OpAccessChain %27 %1 %19
-%29 = OpLoad %5 %15
-%25 = OpAtomicExchange %5 %28 %19 %20 %29
-OpReturn
-)";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
-
-    Validate(b);
-}
-
-TEST_F(BuiltinBuilderTest, Call_AtomicCompareExchangeWeak) {
-    // struct S {
-    //   u : atomic<u32>,
-    //   i : atomic<i32>,
-    // }
-    //
-    // @binding(1) @group(2) var<storage, read_write> b : S;
-    //
-    // fn a_func() {
-    //   let u = atomicCompareExchangeWeak(&b.u, 10u, 20u);
-    //   let i = atomicCompareExchangeWeak(&b.i, 10, 10);
-    // }
-    auto* s = Structure("S", {
-                                 Member("u", ty.atomic<u32>()),
-                                 Member("i", ty.atomic<i32>()),
-                             });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
-              ast::AttributeList{
-                  create<ast::BindingAttribute>(1u),
-                  create<ast::GroupAttribute>(2u),
-              });
-
-    Func("a_func", {}, ty.void_(),
-         ast::StatementList{
-             Decl(Let("u", nullptr,
-                      Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "u")), 10_u,
-                           20_u))),
-             Decl(Let("i", nullptr,
-                      Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "i")), 10_i,
-                           20_i))),
-         },
-         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
-
-    spirv::Builder& b = SanitizeAndBuild();
-
-    ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
-%2 = OpTypePointer StorageBuffer %3
-%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%12 = OpTypeBool
-%11 = OpTypeStruct %4 %12
-%13 = OpConstant %4 1
-%14 = OpConstant %4 0
-%16 = OpTypePointer StorageBuffer %4
-%18 = OpConstant %4 20
-%19 = OpConstant %4 10
-%23 = OpTypeStruct %5 %12
-%25 = OpTypePointer StorageBuffer %5
-%27 = OpConstant %5 20
-%28 = OpConstant %5 10
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    auto* expected_instructions = R"(%17 = OpAccessChain %16 %1 %14
-%20 = OpAtomicCompareExchange %4 %17 %13 %14 %14 %18 %19
-%21 = OpIEqual %12 %20 %18
-%10 = OpCompositeConstruct %11 %20 %21
-%26 = OpAccessChain %25 %1 %13
-%29 = OpAtomicCompareExchange %5 %26 %13 %14 %14 %27 %28
-%30 = OpIEqual %12 %29 %27
-%22 = OpCompositeConstruct %23 %29 %30
-OpReturn
-)";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
-
-    Validate(b);
-}
-
-using Builtin_Builtin_DataPacking_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_DataPacking_Test, Binary) {
+using Builtin_Builder_SingleParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Scalar_f32) {
     auto param = GetParam();
-
-    bool pack4 = param.name == "pack4x8snorm" || param.name == "pack4x8unorm";
-    auto* call = pack4 ? Call(param.name, vec4<f32>(1_f, 1_f, 1_f, 1_f))
-                       : Call(param.name, vec2<f32>(1_f, 1_f));
-    auto* func = Func("a_func", {}, ty.void_(), {CallStmt(call)});
+    // Use a variable to prevent the function being evaluated as constant.
+    auto* scalar = Var("a", nullptr, Expr(1_f));
+    auto* expr = Call(param.name, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
 
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    if (pack4) {
-        auto got = DumpBuilder(b);
-        auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
 OpName %3 "a_func"
+OpName %7 "a"
 %2 = OpTypeVoid
 %1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%9 = OpTypeFloat 32
-%8 = OpTypeVector %9 4
-%10 = OpConstant %9 1
-%11 = OpConstantComposite %8 %10 %10 %10 %10
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
 %3 = OpFunction %2 None %1
 %4 = OpLabel
-%5 = OpExtInst %6 %7 )" +
-                      param.op +
-                      R"( %11
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12
 OpReturn
 OpFunctionEnd
 )";
-        EXPECT_EQ(got, expect);
-    } else {
-        auto got = DumpBuilder(b);
-        auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
-OpName %3 "a_func"
-%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%9 = OpTypeFloat 32
-%8 = OpTypeVector %9 2
-%10 = OpConstant %9 1
-%11 = OpConstantComposite %8 %10 %10
-%3 = OpFunction %2 None %1
-%4 = OpLabel
-%5 = OpExtInst %6 %7 )" +
-                      param.op +
-                      R"( %11
-OpReturn
-OpFunctionEnd
-)";
-        EXPECT_EQ(got, expect);
-    }
+    EXPECT_EQ(got, expect);
 }
 
-INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_DataPacking_Test,
-                         testing::Values(BuiltinData{"pack4x8snorm", "PackSnorm4x8"},
-                                         BuiltinData{"pack4x8unorm", "PackUnorm4x8"},
-                                         BuiltinData{"pack2x16snorm", "PackSnorm2x16"},
-                                         BuiltinData{"pack2x16unorm", "PackUnorm2x16"},
-                                         BuiltinData{"pack2x16float", "PackHalf2x16"}));
+TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Scalar_f16) {
+    Enable(ast::Extension::kF16);
 
-using Builtin_Builtin_DataUnpacking_Test = BuiltinBuilderTestWithParam<BuiltinData>;
-TEST_P(Builtin_Builtin_DataUnpacking_Test, Binary) {
     auto param = GetParam();
-
-    bool pack4 = param.name == "unpack4x8snorm" || param.name == "unpack4x8unorm";
-    auto* func = Func("a_func", {}, ty.void_(), {CallStmt(Call(param.name, 1_u))});
+    // Use a variable to prevent the function being evaluated as constant.
+    auto* scalar = Var("a", nullptr, Expr(1_h));
+    auto* expr = Call(param.name, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
 
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
 
-    if (pack4) {
-        auto got = DumpBuilder(b);
-        auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
 OpName %3 "a_func"
+OpName %7 "a"
 %2 = OpTypeVoid
 %1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 4
-%9 = OpTypeInt 32 0
-%10 = OpConstant %9 1
+%5 = OpTypeFloat 16
+%6 = OpConstant %5 0x1p+0
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
 %3 = OpFunction %2 None %1
 %4 = OpLabel
-%5 = OpExtInst %6 %8 )" +
-                      param.op +
-                      R"( %10
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12
 OpReturn
 OpFunctionEnd
 )";
-        EXPECT_EQ(got, expect);
-    } else {
-        auto got = DumpBuilder(b);
-        auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Vector_f32) {
+    auto param = GetParam();
+
+    // Use a variable to prevent the function being evaluated as constant.
+    auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call(param.name, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
 OpName %3 "a_func"
+OpName %9 "a"
 %2 = OpTypeVoid
 %1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%9 = OpTypeInt 32 0
-%10 = OpConstant %9 1
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
 %3 = OpFunction %2 None %1
 %4 = OpLabel
-%5 = OpExtInst %6 %8 )" +
-                      param.op +
-                      R"( %10
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14
 OpReturn
 OpFunctionEnd
 )";
-        EXPECT_EQ(got, expect);
-    }
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto param = GetParam();
+
+    // Use a variable to prevent the function being evaluated as constant.
+    auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call(param.name, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
 }
 
 INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
-                         Builtin_Builtin_DataUnpacking_Test,
-                         testing::Values(BuiltinData{"unpack4x8snorm", "UnpackSnorm4x8"},
-                                         BuiltinData{"unpack4x8unorm", "UnpackUnorm4x8"},
-                                         BuiltinData{"unpack2x16snorm", "UnpackSnorm2x16"},
-                                         BuiltinData{"unpack2x16unorm", "UnpackUnorm2x16"},
-                                         BuiltinData{"unpack2x16float", "UnpackHalf2x16"}));
+                         Builtin_Builder_SingleParam_Float_Test,
+                         testing::Values(BuiltinData{"abs", "FAbs"},
+                                         BuiltinData{"acos", "Acos"},
+                                         BuiltinData{"asin", "Asin"},
+                                         BuiltinData{"atan", "Atan"},
+                                         BuiltinData{"ceil", "Ceil"},
+                                         BuiltinData{"cos", "Cos"},
+                                         BuiltinData{"cosh", "Cosh"},
+                                         BuiltinData{"degrees", "Degrees"},
+                                         BuiltinData{"exp", "Exp"},
+                                         BuiltinData{"exp2", "Exp2"},
+                                         BuiltinData{"floor", "Floor"},
+                                         BuiltinData{"fract", "Fract"},
+                                         BuiltinData{"inverseSqrt", "InverseSqrt"},
+                                         BuiltinData{"log", "Log"},
+                                         BuiltinData{"log2", "Log2"},
+                                         BuiltinData{"radians", "Radians"},
+                                         BuiltinData{"round", "RoundEven"},
+                                         BuiltinData{"sign", "FSign"},
+                                         BuiltinData{"sin", "Sin"},
+                                         BuiltinData{"sinh", "Sinh"},
+                                         BuiltinData{"sqrt", "Sqrt"},
+                                         BuiltinData{"tan", "Tan"},
+                                         BuiltinData{"tanh", "Tanh"},
+                                         BuiltinData{"trunc", "Trunc"}));
 
-TEST_F(BuiltinBuilderTest, Call_WorkgroupBarrier) {
-    Func("f", {}, ty.void_(),
-         ast::StatementList{
-             CallStmt(Call("workgroupBarrier")),
-         },
-         ast::AttributeList{
-             Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1_i),
-         });
+TEST_F(BuiltinBuilderTest, Call_Length_Scalar_f32) {
+    auto* scalar = Var("a", nullptr, Expr(1_f));
+    auto* expr = Call("length", scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 Length %12
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Length_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* scalar = Var("a", nullptr, Expr(1_h));
+    auto* expr = Call("length", scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 16
+%6 = OpConstant %5 0x1p+0
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 Length %12
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Length_Vector_f32) {
+    auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call("length", vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %6 %13 Length %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Length_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call("length", vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %6 %13 Length %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Normalize_f32) {
+    auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call("normalize", vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 Normalize %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Normalize_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call("normalize", vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "a"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 Normalize %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+using Builtin_Builder_DualParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Scalar_f32) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_f));
+    auto* expr = Call(param.name, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_h));
+    auto* expr = Call(param.name, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 16
+%6 = OpConstant %5 0x1p+0
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Vector_f32) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call(param.name, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call(param.name, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_DualParam_Float_Test,
+                         testing::Values(BuiltinData{"atan2", "Atan2"},
+                                         BuiltinData{"max", "NMax"},
+                                         BuiltinData{"min", "NMin"},
+                                         BuiltinData{"pow", "Pow"},
+                                         BuiltinData{"step", "Step"}));
+
+TEST_F(BuiltinBuilderTest, Call_Reflect_Vector_f32) {
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call("reflect", vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 Reflect %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Reflect_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call("reflect", vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 Reflect %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Distance_Scalar_f32) {
+    auto* scalar = Var("scalar", nullptr, Expr(1_f));
+    auto* expr = Call("distance", scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 Distance %12 %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Distance_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* scalar = Var("scalar", nullptr, Expr(1_h));
+    auto* expr = Call("distance", scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 16
+%6 = OpConstant %5 0x1p+0
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 Distance %12 %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Distance_Vector_f32) {
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call("distance", vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %6 %13 Distance %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Distance_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call("distance", vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %6 %13 Distance %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Cross_f32) {
+    auto* vec = Var("vec", nullptr, vec3<f32>(1_f, 1_f, 1_f));
+    auto* expr = Call("cross", vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 Cross %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Cross_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* vec = Var("vec", nullptr, vec3<f16>(1_h, 1_h, 1_h));
+    auto* expr = Call("cross", vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 Cross %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+using Builtin_Builder_ThreeParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Scalar_f32) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_f));
+    auto* expr = Call(param.name, scalar, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%14 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13 %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Scalar_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_h));
+    auto* expr = Call(param.name, scalar, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 16
+%6 = OpConstant %5 0x1p+0
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%14 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13 %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Vector_f32) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call(param.name, vec, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%16 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15 %16
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call(param.name, vec, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%16 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15 %16
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_ThreeParam_Float_Test,
+                         testing::Values(BuiltinData{"clamp", "NClamp"},
+                                         BuiltinData{"fma", "Fma"},
+                                         BuiltinData{"mix", "FMix"},
+
+                                         BuiltinData{"smoothstep", "SmoothStep"}));
+
+TEST_F(BuiltinBuilderTest, Call_FaceForward_Vector_f32) {
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
+    auto* expr = Call("faceForward", vec, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%16 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 FaceForward %14 %15 %16
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_FaceForward_Vector_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
+    auto* expr = Call("faceForward", vec, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 16
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 0x1p+0
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%16 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 FaceForward %14 %15 %16
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Modf) {
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 2_f));
+    auto* expr = Call("modf", vec);
+    Func("a_func", {}, ty.void_(), {Decl(vec), CallStmt(expr)},
+         {Stage(ast::PipelineStage::kFragment)});
 
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    auto* expected_types = R"(%2 = OpTypeVoid
+    auto got = DumpBuilder(b);
+    auto* expect = R"(OpCapability Shader
+%15 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %3 "a_func"
+OpExecutionMode %3 OriginUpperLeft
+OpName %3 "a_func"
+OpName %10 "vec"
+OpName %14 "__modf_result_vec2"
+OpMemberName %14 0 "fract"
+OpMemberName %14 1 "whole"
+OpMemberDecorate %14 0 Offset 0
+OpMemberDecorate %14 1 Offset 8
+%2 = OpTypeVoid
 %1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 2
-%8 = OpConstant %6 264
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstant %6 2
+%9 = OpConstantComposite %5 %7 %8
+%11 = OpTypePointer Function %5
+%12 = OpConstantNull %5
+%14 = OpTypeStruct %5 %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%10 = OpVariable %11 Function %12
+OpStore %10 %9
+%16 = OpLoad %5 %10
+%13 = OpExtInst %14 %15 ModfStruct %16
 OpReturn
+OpFunctionEnd
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
+    EXPECT_EQ(expect, got);
 
     Validate(b);
 }
 
-TEST_F(BuiltinBuilderTest, Call_StorageBarrier) {
-    Func("f", {}, ty.void_(),
-         ast::StatementList{
-             CallStmt(Call("storageBarrier")),
-         },
-         ast::AttributeList{
-             Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1_i),
-         });
+TEST_F(BuiltinBuilderTest, Call_Frexp) {
+    auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 2_f));
+    auto* expr = Call("frexp", vec);
+    Func("a_func", {}, ty.void_(), {Decl(vec), CallStmt(expr)},
+         {Stage(ast::PipelineStage::kFragment)});
 
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.Build()) << b.error();
-
-    ASSERT_EQ(b.functions().size(), 1_u);
-
-    auto* expected_types = R"(%2 = OpTypeVoid
+    auto got = DumpBuilder(b);
+    auto* expect = R"(OpCapability Shader
+%17 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %3 "a_func"
+OpExecutionMode %3 OriginUpperLeft
+OpName %3 "a_func"
+OpName %10 "vec"
+OpName %14 "__frexp_result_vec2"
+OpMemberName %14 0 "sig"
+OpMemberName %14 1 "exp"
+OpMemberDecorate %14 0 Offset 0
+OpMemberDecorate %14 1 Offset 8
+%2 = OpTypeVoid
 %1 = OpTypeFunction %2
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 2
-%8 = OpConstant %6 72
-)";
-    auto got_types = DumpInstructions(b.types());
-    EXPECT_EQ(expected_types, got_types);
-
-    auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstant %6 2
+%9 = OpConstantComposite %5 %7 %8
+%11 = OpTypePointer Function %5
+%12 = OpConstantNull %5
+%16 = OpTypeInt 32 1
+%15 = OpTypeVector %16 2
+%14 = OpTypeStruct %5 %15
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%10 = OpVariable %11 Function %12
+OpStore %10 %9
+%18 = OpLoad %5 %10
+%13 = OpExtInst %14 %17 FrexpStruct %18
 OpReturn
+OpFunctionEnd
 )";
-    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
-    EXPECT_EQ(expected_instructions, got_instructions);
+    EXPECT_EQ(expect, got);
 
     Validate(b);
 }
 
+}  // namespace float_builtin_tests
+
+// Tests for Numeric builtins with all integer parameter
+namespace integer_builtin_tests {
+
+using BuiltinIntTest = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(BuiltinIntTest, Call_SInt_Scalar) {
+    auto param = GetParam();
+    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* expr = Call(param.name, "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+)");
+
+    auto expected = utils::ReplaceAll(R"(%10 = OpLoad %3 %1
+%9 = ${op} %3 %10
+OpReturn
+)",
+                                      "${op}", param.op);
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+}
+
+TEST_P(BuiltinIntTest, Call_SInt_Vector) {
+    auto param = GetParam();
+    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call(param.name, "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+
+    auto expected = utils::ReplaceAll(R"(%11 = OpLoad %3 %1
+%10 = ${op} %3 %11
+OpReturn
+)",
+                                      "${op}", param.op);
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+}
+
+TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
+    auto param = GetParam();
+    auto* var = GlobalVar("v", ty.u32(), ast::StorageClass::kPrivate);
+    auto* expr = Call(param.name, "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 0
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+)");
+
+    auto expected = utils::ReplaceAll(R"(%10 = OpLoad %3 %1
+%9 = ${op} %3 %10
+OpReturn
+)",
+                                      "${op}", param.op);
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+}
+
+TEST_P(BuiltinIntTest, Call_UInt_Vector) {
+    auto param = GetParam();
+    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call(param.name, "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+
+    auto expected = utils::ReplaceAll(R"(%11 = OpLoad %3 %1
+%10 = ${op} %3 %11
+OpReturn
+)",
+                                      "${op}", param.op);
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         BuiltinIntTest,
+                         testing::Values(BuiltinData{"countOneBits", "OpBitCount"},
+                                         BuiltinData{"reverseBits", "OpBitReverse"}));
+
+using Builtin_Builder_SingleParam_Sint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_SingleParam_Sint_Test, Call_Scalar) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_i));
+    auto* expr = Call(param.name, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 1
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_SingleParam_Sint_Test, Call_Vector) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
+    auto* expr = Call(param.name, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 1
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_SingleParam_Sint_Test,
+                         testing::Values(BuiltinData{"abs", "SAbs"}));
+
+// Calling abs() on an unsigned integer scalar / vector is a no-op.
+using Builtin_Builder_Abs_Uint_Test = BuiltinBuilderTest;
+TEST_F(Builtin_Builder_Abs_Uint_Test, Call_Scalar) {
+    auto* scalar = Var("scalar", nullptr, Expr(1_u));
+    auto* expr = Call("abs", scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 0
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%11 = OpLoad %5 %7
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(Builtin_Builder_Abs_Uint_Test, Call_Vector) {
+    auto* scalar = Var("scalar", nullptr, vec2<u32>(1_u, 1_u));
+    auto* expr = Call("abs", scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(OpName %3 "a_func"
+OpName %9 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%13 = OpLoad %5 %9
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+using Builtin_Builder_DualParam_SInt_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_DualParam_SInt_Test, Call_Scalar) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_i));
+    auto* expr = Call(param.name, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 1
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_DualParam_SInt_Test, Call_Vector) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
+    auto* expr = Call(param.name, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 1
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_DualParam_SInt_Test,
+                         testing::Values(BuiltinData{"max", "SMax"}, BuiltinData{"min", "SMin"}));
+
+using Builtin_Builder_DualParam_UInt_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_DualParam_UInt_Test, Call_Scalar) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_u));
+    auto* expr = Call(param.name, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 0
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_DualParam_UInt_Test, Call_Vector) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<u32>(1_u, 1_u));
+    auto* expr = Call(param.name, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_DualParam_UInt_Test,
+                         testing::Values(BuiltinData{"max", "UMax"}, BuiltinData{"min", "UMin"}));
+
+using Builtin_Builder_ThreeParam_Sint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_ThreeParam_Sint_Test, Call_Scalar) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_i));
+    auto* expr = Call(param.name, scalar, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 1
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%14 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13 %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_ThreeParam_Sint_Test, Call_Vector) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<i32>(1_i, 1_i));
+    auto* expr = Call(param.name, vec, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 1
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%16 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15 %16
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_ThreeParam_Sint_Test,
+                         testing::Values(BuiltinData{"clamp", "SClamp"}));
+
+using Builtin_Builder_ThreeParam_Uint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_ThreeParam_Uint_Test, Call_Scalar) {
+    auto param = GetParam();
+    auto* scalar = Var("scalar", nullptr, Expr(1_u));
+    auto* expr = Call(param.name, scalar, scalar, scalar);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(scalar),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %7 "scalar"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 0
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%7 = OpVariable %8 Function %9
+OpStore %7 %6
+%12 = OpLoad %5 %7
+%13 = OpLoad %5 %7
+%14 = OpLoad %5 %7
+%10 = OpExtInst %5 %11 )" +
+                  param.op +
+                  R"( %12 %13 %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_P(Builtin_Builder_ThreeParam_Uint_Test, Call_Vector) {
+    auto param = GetParam();
+    auto* vec = Var("vec", nullptr, vec2<u32>(1_u, 1_u));
+    auto* expr = Call(param.name, vec, vec, vec);
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Decl(vec),
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+OpName %9 "vec"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 1
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%9 = OpVariable %10 Function %11
+OpStore %9 %8
+%14 = OpLoad %5 %9
+%15 = OpLoad %5 %9
+%16 = OpLoad %5 %9
+%12 = OpExtInst %5 %13 )" +
+                  param.op +
+                  R"( %14 %15 %16
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_ThreeParam_Uint_Test,
+                         testing::Values(BuiltinData{"clamp", "UClamp"}));
+
 TEST_F(BuiltinBuilderTest, Call_ExtractBits_i32) {
     auto* v = Var("v", ty.i32());
     auto* offset = Var("offset", ty.u32());
@@ -2802,6 +2695,1034 @@
     EXPECT_EQ(got, expect);
 }
 
+}  // namespace integer_builtin_tests
+
+// Tests for Numeric builtins with matrix parameter, i.e. "determinant" and "transpose"
+namespace matrix_builtin_tests {
+
+TEST_F(BuiltinBuilderTest, Call_Determinant_f32) {
+    auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("determinant", "var");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%12 = OpExtInstImport "GLSL.std.450"
+OpName %1 "var"
+OpName %9 "a_func"
+%5 = OpTypeFloat 32
+%4 = OpTypeVector %5 3
+%3 = OpTypeMatrix %4 3
+%2 = OpTypePointer Private %3
+%6 = OpConstantNull %3
+%1 = OpVariable %2 Private %6
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%9 = OpFunction %8 None %7
+%10 = OpLabel
+%13 = OpLoad %3 %1
+%11 = OpExtInst %5 %12 Determinant %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Determinant_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* var = GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("determinant", "var");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(%12 = OpExtInstImport "GLSL.std.450"
+OpName %1 "var"
+OpName %9 "a_func"
+%5 = OpTypeFloat 16
+%4 = OpTypeVector %5 3
+%3 = OpTypeMatrix %4 3
+%2 = OpTypePointer Private %3
+%6 = OpConstantNull %3
+%1 = OpVariable %2 Private %6
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%9 = OpFunction %8 None %7
+%10 = OpLabel
+%13 = OpLoad %3 %1
+%11 = OpExtInst %5 %12 Determinant %13
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Transpose_f32) {
+    auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("transpose", "var");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(OpName %1 "var"
+OpName %9 "a_func"
+%5 = OpTypeFloat 32
+%4 = OpTypeVector %5 3
+%3 = OpTypeMatrix %4 2
+%2 = OpTypePointer Private %3
+%6 = OpConstantNull %3
+%1 = OpVariable %2 Private %6
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%13 = OpTypeVector %5 2
+%12 = OpTypeMatrix %13 3
+%9 = OpFunction %8 None %7
+%10 = OpLabel
+%14 = OpLoad %3 %1
+%11 = OpTranspose %12 %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+TEST_F(BuiltinBuilderTest, Call_Transpose_f16) {
+    Enable(ast::Extension::kF16);
+
+    auto* var = GlobalVar("var", ty.mat2x3<f16>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("transpose", "var");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    auto got = DumpBuilder(b);
+    auto expect = R"(OpName %1 "var"
+OpName %9 "a_func"
+%5 = OpTypeFloat 16
+%4 = OpTypeVector %5 3
+%3 = OpTypeMatrix %4 2
+%2 = OpTypePointer Private %3
+%6 = OpConstantNull %3
+%1 = OpVariable %2 Private %6
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%13 = OpTypeVector %5 2
+%12 = OpTypeMatrix %13 3
+%9 = OpFunction %8 None %7
+%10 = OpLabel
+%14 = OpLoad %3 %1
+%11 = OpTranspose %12 %14
+OpReturn
+OpFunctionEnd
+)";
+    EXPECT_EQ(got, expect);
+}
+
+}  // namespace matrix_builtin_tests
+
+// Tests for Numeric builtins with float and integer vector parameter, i.e. "dot"
+namespace vector_builtin_tests {
+
+TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
+    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("dot", "v", "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+              R"(%11 = OpLoad %3 %1
+%12 = OpLoad %3 %1
+%10 = OpDot %4 %11 %12
+OpReturn
+)");
+}
+
+TEST_F(BuiltinBuilderTest, Call_Dot_F16) {
+    Enable(ast::Extension::kF16);
+
+    auto* var = GlobalVar("v", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("dot", "v", "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+              R"(%11 = OpLoad %3 %1
+%12 = OpLoad %3 %1
+%10 = OpDot %4 %11 %12
+OpReturn
+)");
+}
+
+TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
+    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("dot", "v", "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+              R"(%11 = OpLoad %3 %1
+%12 = OpLoad %3 %1
+%13 = OpCompositeExtract %4 %11 0
+%14 = OpCompositeExtract %4 %12 0
+%15 = OpIMul %4 %13 %14
+%16 = OpCompositeExtract %4 %11 1
+%17 = OpCompositeExtract %4 %12 1
+%18 = OpIMul %4 %16 %17
+%19 = OpIAdd %4 %15 %18
+%20 = OpCompositeExtract %4 %11 2
+%21 = OpCompositeExtract %4 %12 2
+%22 = OpIMul %4 %20 %21
+%10 = OpIAdd %4 %19 %22
+OpReturn
+)");
+}
+
+TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
+    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call("dot", "v", "v");
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Assign(Phony(), expr),
+                      });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+              R"(%11 = OpLoad %3 %1
+%12 = OpLoad %3 %1
+%13 = OpCompositeExtract %4 %11 0
+%14 = OpCompositeExtract %4 %12 0
+%15 = OpIMul %4 %13 %14
+%16 = OpCompositeExtract %4 %11 1
+%17 = OpCompositeExtract %4 %12 1
+%18 = OpIMul %4 %16 %17
+%19 = OpIAdd %4 %15 %18
+%20 = OpCompositeExtract %4 %11 2
+%21 = OpCompositeExtract %4 %12 2
+%22 = OpIMul %4 %20 %21
+%10 = OpIAdd %4 %19 %22
+OpReturn
+)");
+}
+
+}  // namespace vector_builtin_tests
+
+// Tests for Derivative builtins
+namespace derivative_builtin_tests {
+
+using BuiltinDeriveTest = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(BuiltinDeriveTest, Call_Derivative_Scalar) {
+    auto param = GetParam();
+    auto* var = GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate);
+    auto* expr = Call(param.name, "v");
+    auto* func =
+        Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+)");
+
+    auto expected = utils::ReplaceAll(R"(%10 = OpLoad %3 %1
+%9 = ${op} %3 %10
+OpReturn
+)",
+                                      "${op}", param.op);
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+}
+
+TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
+    auto param = GetParam();
+    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* expr = Call(param.name, "v");
+    auto* func =
+        Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    if (param.name != "dpdx" && param.name != "dpdy" && param.name != "fwidth") {
+        EXPECT_EQ(DumpInstructions(b.capabilities()),
+                  R"(OpCapability DerivativeControl
+)");
+    }
+
+    EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+%3 = OpTypeVector %4 3
+%2 = OpTypePointer Private %3
+%5 = OpConstantNull %3
+%1 = OpVariable %2 Private %5
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+)");
+
+    auto expected = utils::ReplaceAll(R"(%11 = OpLoad %3 %1
+%10 = ${op} %3 %11
+OpReturn
+)",
+                                      "${op}", param.op);
+    EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         BuiltinDeriveTest,
+                         testing::Values(BuiltinData{"dpdx", "OpDPdx"},
+                                         BuiltinData{"dpdxFine", "OpDPdxFine"},
+                                         BuiltinData{"dpdxCoarse", "OpDPdxCoarse"},
+                                         BuiltinData{"dpdy", "OpDPdy"},
+                                         BuiltinData{"dpdyFine", "OpDPdyFine"},
+                                         BuiltinData{"dpdyCoarse", "OpDPdyCoarse"},
+                                         BuiltinData{"fwidth", "OpFwidth"},
+                                         BuiltinData{"fwidthFine", "OpFwidthFine"},
+                                         BuiltinData{"fwidthCoarse", "OpFwidthCoarse"}));
+
+}  // namespace derivative_builtin_tests
+
+// Tests for Atomic builtins
+namespace atomic_builtin_tests {
+
+TEST_F(BuiltinBuilderTest, Call_AtomicLoad) {
+    // struct S {
+    //   u : atomic<u32>;
+    //   i : atomic<i32>;
+    // }
+    //
+    // @binding(1) @group(2) var<storage, read_write> b : S;
+    //
+    // fn a_func() {
+    //   let u : u32 = atomicLoad(&b.u);
+    //   let i : i32 = atomicLoad(&b.i);
+    // }
+    auto* s = Structure("S", {
+                                 Member("u", ty.atomic<u32>()),
+                                 Member("i", ty.atomic<i32>()),
+                             });
+    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+              ast::AttributeList{
+                  create<ast::BindingAttribute>(1u),
+                  create<ast::GroupAttribute>(2u),
+              });
+
+    Func("a_func", {}, ty.void_(),
+         ast::StatementList{
+             Decl(Let("u", ty.u32(), Call("atomicLoad", AddressOf(MemberAccessor("b", "u"))))),
+             Decl(Let("i", ty.i32(), Call("atomicLoad", AddressOf(MemberAccessor("b", "i"))))),
+         },
+         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = SanitizeAndBuild();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    auto* expected_types = R"(%4 = OpTypeInt 32 0
+%5 = OpTypeInt 32 1
+%3 = OpTypeStruct %4 %5
+%2 = OpTypePointer StorageBuffer %3
+%1 = OpVariable %2 StorageBuffer
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%11 = OpConstant %4 1
+%12 = OpConstant %4 0
+%14 = OpTypePointer StorageBuffer %4
+%18 = OpTypePointer StorageBuffer %5
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    auto* expected_instructions = R"(%15 = OpAccessChain %14 %1 %12
+%10 = OpAtomicLoad %4 %15 %11 %12
+%19 = OpAccessChain %18 %1 %11
+%16 = OpAtomicLoad %5 %19 %11 %12
+OpReturn
+)";
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+
+TEST_F(BuiltinBuilderTest, Call_AtomicStore) {
+    // struct S {
+    //   u : atomic<u32>;
+    //   i : atomic<i32>;
+    // }
+    //
+    // @binding(1) @group(2) var<storage, read_write> b : S;
+    //
+    // fn a_func() {
+    //   var u = 1_u;
+    //   var i = 2;
+    //   atomicStore(&b.u, u);
+    //   atomicStore(&b.i, i);
+    // }
+    auto* s = Structure("S", {
+                                 Member("u", ty.atomic<u32>()),
+                                 Member("i", ty.atomic<i32>()),
+                             });
+    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+              ast::AttributeList{
+                  create<ast::BindingAttribute>(1u),
+                  create<ast::GroupAttribute>(2u),
+              });
+
+    Func("a_func", {}, ty.void_(),
+         ast::StatementList{
+             Decl(Var("u", nullptr, Expr(1_u))),
+             Decl(Var("i", nullptr, Expr(2_i))),
+             CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "u")), "u")),
+             CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "i")), "i")),
+         },
+         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = SanitizeAndBuild();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    auto* expected_types = R"(%4 = OpTypeInt 32 0
+%5 = OpTypeInt 32 1
+%3 = OpTypeStruct %4 %5
+%2 = OpTypePointer StorageBuffer %3
+%1 = OpVariable %2 StorageBuffer
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%10 = OpConstant %4 1
+%12 = OpTypePointer Function %4
+%13 = OpConstantNull %4
+%14 = OpConstant %5 2
+%16 = OpTypePointer Function %5
+%17 = OpConstantNull %5
+%19 = OpConstant %4 0
+%21 = OpTypePointer StorageBuffer %4
+%26 = OpTypePointer StorageBuffer %5
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    auto* expected_instructions = R"(OpStore %11 %10
+OpStore %15 %14
+%22 = OpAccessChain %21 %1 %19
+%23 = OpLoad %4 %11
+OpAtomicStore %22 %10 %19 %23
+%27 = OpAccessChain %26 %1 %10
+%28 = OpLoad %5 %15
+OpAtomicStore %27 %10 %19 %28
+OpReturn
+)";
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+
+using Builtin_Builder_AtomicRMW_i32 = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_AtomicRMW_i32, Test) {
+    // struct S {
+    //   v : atomic<i32>;
+    // }
+    //
+    // @binding(1) @group(2) var<storage, read_write> b : S;
+    //
+    // fn a_func() {
+    //   var v = 10;
+    //   let x : i32 = atomicOP(&b.v, v);
+    // }
+    auto* s = Structure("S", {
+                                 Member("v", ty.atomic<i32>()),
+                             });
+    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+              ast::AttributeList{
+                  create<ast::BindingAttribute>(1u),
+                  create<ast::GroupAttribute>(2u),
+              });
+
+    Func("a_func", {}, ty.void_(),
+         ast::StatementList{
+             Decl(Var("v", nullptr, Expr(10_i))),
+             Decl(Let("x", ty.i32(),
+                      Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
+         },
+         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = SanitizeAndBuild();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    std::string expected_types = R"(%4 = OpTypeInt 32 1
+%3 = OpTypeStruct %4
+%2 = OpTypePointer StorageBuffer %3
+%1 = OpVariable %2 StorageBuffer
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+%9 = OpConstant %4 10
+%11 = OpTypePointer Function %4
+%12 = OpConstantNull %4
+%14 = OpTypeInt 32 0
+%15 = OpConstant %14 1
+%16 = OpConstant %14 0
+%18 = OpTypePointer StorageBuffer %4
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    std::string expected_instructions = R"(OpStore %10 %9
+%19 = OpAccessChain %18 %1 %16
+%20 = OpLoad %4 %10
+)";
+    expected_instructions += "%13 = " + GetParam().op + " %4 %19 %15 %16 %20\n";
+    expected_instructions += "OpReturn\n";
+
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_AtomicRMW_i32,
+                         testing::Values(BuiltinData{"atomicAdd", "OpAtomicIAdd"},
+                                         BuiltinData{"atomicMax", "OpAtomicSMax"},
+                                         BuiltinData{"atomicMin", "OpAtomicSMin"},
+                                         BuiltinData{"atomicAnd", "OpAtomicAnd"},
+                                         BuiltinData{"atomicOr", "OpAtomicOr"},
+                                         BuiltinData{"atomicXor", "OpAtomicXor"}));
+
+using Builtin_Builder_AtomicRMW_u32 = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_AtomicRMW_u32, Test) {
+    // struct S {
+    //   v : atomic<u32>;
+    // }
+    //
+    // @binding(1) @group(2) var<storage, read_write> b : S;
+    //
+    // fn a_func() {
+    //   var v = 10u;
+    //   let x : u32 = atomicOP(&b.v, v);
+    // }
+    auto* s = Structure("S", {
+                                 Member("v", ty.atomic<u32>()),
+                             });
+    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+              ast::AttributeList{
+                  create<ast::BindingAttribute>(1u),
+                  create<ast::GroupAttribute>(2u),
+              });
+
+    Func("a_func", {}, ty.void_(),
+         ast::StatementList{
+             Decl(Var("v", nullptr, Expr(10_u))),
+             Decl(Let("x", ty.u32(),
+                      Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
+         },
+         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = SanitizeAndBuild();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    std::string expected_types = R"(%4 = OpTypeInt 32 0
+%3 = OpTypeStruct %4
+%2 = OpTypePointer StorageBuffer %3
+%1 = OpVariable %2 StorageBuffer
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+%9 = OpConstant %4 10
+%11 = OpTypePointer Function %4
+%12 = OpConstantNull %4
+%14 = OpConstant %4 1
+%15 = OpConstant %4 0
+%17 = OpTypePointer StorageBuffer %4
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    std::string expected_instructions = R"(OpStore %10 %9
+%18 = OpAccessChain %17 %1 %15
+%19 = OpLoad %4 %10
+)";
+    expected_instructions += "%13 = " + GetParam().op + " %4 %18 %14 %15 %19\n";
+    expected_instructions += "OpReturn\n";
+
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_AtomicRMW_u32,
+                         testing::Values(BuiltinData{"atomicAdd", "OpAtomicIAdd"},
+                                         BuiltinData{"atomicMax", "OpAtomicUMax"},
+                                         BuiltinData{"atomicMin", "OpAtomicUMin"},
+                                         BuiltinData{"atomicAnd", "OpAtomicAnd"},
+                                         BuiltinData{"atomicOr", "OpAtomicOr"},
+                                         BuiltinData{"atomicXor", "OpAtomicXor"}));
+
+TEST_F(BuiltinBuilderTest, Call_AtomicExchange) {
+    // struct S {
+    //   u : atomic<u32>;
+    //   i : atomic<i32>;
+    // }
+    //
+    // @binding(1) @group(2) var<storage, read_write> b : S;
+    //
+    // fn a_func() {
+    //   var u = 10u;
+    //   var i = 10i;
+    //   let r : u32 = atomicExchange(&b.u, u);
+    //   let s : i32 = atomicExchange(&b.i, i);
+    // }
+    auto* s = Structure("S", {
+                                 Member("u", ty.atomic<u32>()),
+                                 Member("i", ty.atomic<i32>()),
+                             });
+    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+              ast::AttributeList{
+                  create<ast::BindingAttribute>(1u),
+                  create<ast::GroupAttribute>(2u),
+              });
+
+    Func("a_func", {}, ty.void_(),
+         ast::StatementList{
+             Decl(Var("u", nullptr, Expr(10_u))),
+             Decl(Var("i", nullptr, Expr(10_i))),
+             Decl(Let("r", ty.u32(),
+                      Call("atomicExchange", AddressOf(MemberAccessor("b", "u")), "u"))),
+             Decl(Let("s", ty.i32(),
+                      Call("atomicExchange", AddressOf(MemberAccessor("b", "i")), "i"))),
+         },
+         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = SanitizeAndBuild();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    auto* expected_types = R"(%4 = OpTypeInt 32 0
+%5 = OpTypeInt 32 1
+%3 = OpTypeStruct %4 %5
+%2 = OpTypePointer StorageBuffer %3
+%1 = OpVariable %2 StorageBuffer
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%10 = OpConstant %4 10
+%12 = OpTypePointer Function %4
+%13 = OpConstantNull %4
+%14 = OpConstant %5 10
+%16 = OpTypePointer Function %5
+%17 = OpConstantNull %5
+%19 = OpConstant %4 1
+%20 = OpConstant %4 0
+%22 = OpTypePointer StorageBuffer %4
+%27 = OpTypePointer StorageBuffer %5
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    auto* expected_instructions = R"(OpStore %11 %10
+OpStore %15 %14
+%23 = OpAccessChain %22 %1 %20
+%24 = OpLoad %4 %11
+%18 = OpAtomicExchange %4 %23 %19 %20 %24
+%28 = OpAccessChain %27 %1 %19
+%29 = OpLoad %5 %15
+%25 = OpAtomicExchange %5 %28 %19 %20 %29
+OpReturn
+)";
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+
+TEST_F(BuiltinBuilderTest, Call_AtomicCompareExchangeWeak) {
+    // struct S {
+    //   u : atomic<u32>,
+    //   i : atomic<i32>,
+    // }
+    //
+    // @binding(1) @group(2) var<storage, read_write> b : S;
+    //
+    // fn a_func() {
+    //   let u = atomicCompareExchangeWeak(&b.u, 10u, 20u);
+    //   let i = atomicCompareExchangeWeak(&b.i, 10, 10);
+    // }
+    auto* s = Structure("S", {
+                                 Member("u", ty.atomic<u32>()),
+                                 Member("i", ty.atomic<i32>()),
+                             });
+    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+              ast::AttributeList{
+                  create<ast::BindingAttribute>(1u),
+                  create<ast::GroupAttribute>(2u),
+              });
+
+    Func("a_func", {}, ty.void_(),
+         ast::StatementList{
+             Decl(Let("u", nullptr,
+                      Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "u")), 10_u,
+                           20_u))),
+             Decl(Let("i", nullptr,
+                      Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "i")), 10_i,
+                           20_i))),
+         },
+         ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
+
+    spirv::Builder& b = SanitizeAndBuild();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    auto* expected_types = R"(%4 = OpTypeInt 32 0
+%5 = OpTypeInt 32 1
+%3 = OpTypeStruct %4 %5
+%2 = OpTypePointer StorageBuffer %3
+%1 = OpVariable %2 StorageBuffer
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%12 = OpTypeBool
+%11 = OpTypeStruct %4 %12
+%13 = OpConstant %4 1
+%14 = OpConstant %4 0
+%16 = OpTypePointer StorageBuffer %4
+%18 = OpConstant %4 20
+%19 = OpConstant %4 10
+%23 = OpTypeStruct %5 %12
+%25 = OpTypePointer StorageBuffer %5
+%27 = OpConstant %5 20
+%28 = OpConstant %5 10
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    auto* expected_instructions = R"(%17 = OpAccessChain %16 %1 %14
+%20 = OpAtomicCompareExchange %4 %17 %13 %14 %14 %18 %19
+%21 = OpIEqual %12 %20 %18
+%10 = OpCompositeConstruct %11 %20 %21
+%26 = OpAccessChain %25 %1 %13
+%29 = OpAtomicCompareExchange %5 %26 %13 %14 %14 %27 %28
+%30 = OpIEqual %12 %29 %27
+%22 = OpCompositeConstruct %23 %29 %30
+OpReturn
+)";
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+
+}  // namespace atomic_builtin_tests
+
+// Tests for Data Packing builtins
+namespace data_packing_builtin_tests {
+
+using Builtin_Builder_DataPacking_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_DataPacking_Test, Binary) {
+    auto param = GetParam();
+
+    bool pack4 = param.name == "pack4x8snorm" || param.name == "pack4x8unorm";
+    auto* call = pack4 ? Call(param.name, vec4<f32>(1_f, 1_f, 1_f, 1_f))
+                       : Call(param.name, vec2<f32>(1_f, 1_f));
+    auto* func = Func("a_func", {}, ty.void_(), {CallStmt(call)});
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    if (pack4) {
+        auto got = DumpBuilder(b);
+        auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 4
+%10 = OpConstant %9 1
+%11 = OpConstantComposite %8 %10 %10 %10 %10
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%5 = OpExtInst %6 %7 )" +
+                      param.op +
+                      R"( %11
+OpReturn
+OpFunctionEnd
+)";
+        EXPECT_EQ(got, expect);
+    } else {
+        auto got = DumpBuilder(b);
+        auto expect = R"(%7 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 2
+%10 = OpConstant %9 1
+%11 = OpConstantComposite %8 %10 %10
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%5 = OpExtInst %6 %7 )" +
+                      param.op +
+                      R"( %11
+OpReturn
+OpFunctionEnd
+)";
+        EXPECT_EQ(got, expect);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_DataPacking_Test,
+                         testing::Values(BuiltinData{"pack4x8snorm", "PackSnorm4x8"},
+                                         BuiltinData{"pack4x8unorm", "PackUnorm4x8"},
+                                         BuiltinData{"pack2x16snorm", "PackSnorm2x16"},
+                                         BuiltinData{"pack2x16unorm", "PackUnorm2x16"},
+                                         BuiltinData{"pack2x16float", "PackHalf2x16"}));
+
+}  // namespace data_packing_builtin_tests
+
+// Tests for Data Unpacking builtins
+namespace data_unpacking_builtin_tests {
+
+using Builtin_Builder_DataUnpacking_Test = BuiltinBuilderTestWithParam<BuiltinData>;
+TEST_P(Builtin_Builder_DataUnpacking_Test, Binary) {
+    auto param = GetParam();
+
+    bool pack4 = param.name == "unpack4x8snorm" || param.name == "unpack4x8unorm";
+    auto* func = Func("a_func", {}, ty.void_(), {CallStmt(Call(param.name, 1_u))});
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+    if (pack4) {
+        auto got = DumpBuilder(b);
+        auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeVector %7 4
+%9 = OpTypeInt 32 0
+%10 = OpConstant %9 1
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%5 = OpExtInst %6 %8 )" +
+                      param.op +
+                      R"( %10
+OpReturn
+OpFunctionEnd
+)";
+        EXPECT_EQ(got, expect);
+    } else {
+        auto got = DumpBuilder(b);
+        auto expect = R"(%8 = OpExtInstImport "GLSL.std.450"
+OpName %3 "a_func"
+%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeVector %7 2
+%9 = OpTypeInt 32 0
+%10 = OpConstant %9 1
+%3 = OpFunction %2 None %1
+%4 = OpLabel
+%5 = OpExtInst %6 %8 )" +
+                      param.op +
+                      R"( %10
+OpReturn
+OpFunctionEnd
+)";
+        EXPECT_EQ(got, expect);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
+                         Builtin_Builder_DataUnpacking_Test,
+                         testing::Values(BuiltinData{"unpack4x8snorm", "UnpackSnorm4x8"},
+                                         BuiltinData{"unpack4x8unorm", "UnpackUnorm4x8"},
+                                         BuiltinData{"unpack2x16snorm", "UnpackSnorm2x16"},
+                                         BuiltinData{"unpack2x16unorm", "UnpackUnorm2x16"},
+                                         BuiltinData{"unpack2x16float", "UnpackHalf2x16"}));
+
+}  // namespace data_unpacking_builtin_tests
+
+// Tests for Synchronization builtins
+namespace synchronization_builtin_tests {
+
+TEST_F(BuiltinBuilderTest, Call_WorkgroupBarrier) {
+    Func("f", {}, ty.void_(),
+         ast::StatementList{
+             CallStmt(Call("workgroupBarrier")),
+         },
+         ast::AttributeList{
+             Stage(ast::PipelineStage::kCompute),
+             WorkgroupSize(1_i),
+         });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    auto* expected_types = R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%7 = OpConstant %6 2
+%8 = OpConstant %6 264
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
+OpReturn
+)";
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+
+TEST_F(BuiltinBuilderTest, Call_StorageBarrier) {
+    Func("f", {}, ty.void_(),
+         ast::StatementList{
+             CallStmt(Call("storageBarrier")),
+         },
+         ast::AttributeList{
+             Stage(ast::PipelineStage::kCompute),
+             WorkgroupSize(1_i),
+         });
+
+    spirv::Builder& b = Build();
+
+    ASSERT_TRUE(b.Build()) << b.error();
+
+    ASSERT_EQ(b.functions().size(), 1_u);
+
+    auto* expected_types = R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%7 = OpConstant %6 2
+%8 = OpConstant %6 72
+)";
+    auto got_types = DumpInstructions(b.types());
+    EXPECT_EQ(expected_types, got_types);
+
+    auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
+OpReturn
+)";
+    auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+    EXPECT_EQ(expected_instructions, got_instructions);
+
+    Validate(b);
+}
+
+}  // namespace synchronization_builtin_tests
+
+// Tests for DP4A builtins, tint:1497
+namespace DP4A_builtin_tests {
+
 TEST_F(BuiltinBuilderTest, Call_Dot4I8Packed) {
     auto* ext =
         create<ast::Enable>(Source{Source::Range{Source::Location{10, 2}, Source::Location{10, 5}}},
@@ -2881,5 +3802,7 @@
     EXPECT_EQ(got, expect);
 }
 
+}  // namespace DP4A_builtin_tests
+
 }  // namespace
 }  // namespace tint::writer::spirv