[tint] Add subgroup builtin inputs

Adds parsing and SPIR-V codegen for subgroup_invocation_id and
subgroup_size.

Bug: tint:2000
Change-Id: Idcb9e2011c8c6129c5a0e5f0564048c14f8625a6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/143835
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 05ecb45..0774687 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -37,6 +37,8 @@
   num_workgroups
   sample_index
   sample_mask
+  subgroup_invocation_id
+  subgroup_size
   __point_size
 }
 
diff --git a/src/tint/lang/core/builtin/builtin_value.cc b/src/tint/lang/core/builtin/builtin_value.cc
index 644a217..f11b797 100644
--- a/src/tint/lang/core/builtin/builtin_value.cc
+++ b/src/tint/lang/core/builtin/builtin_value.cc
@@ -61,6 +61,12 @@
     if (str == "sample_mask") {
         return BuiltinValue::kSampleMask;
     }
+    if (str == "subgroup_invocation_id") {
+        return BuiltinValue::kSubgroupInvocationId;
+    }
+    if (str == "subgroup_size") {
+        return BuiltinValue::kSubgroupSize;
+    }
     if (str == "vertex_index") {
         return BuiltinValue::kVertexIndex;
     }
@@ -96,6 +102,10 @@
             return "sample_index";
         case BuiltinValue::kSampleMask:
             return "sample_mask";
+        case BuiltinValue::kSubgroupInvocationId:
+            return "subgroup_invocation_id";
+        case BuiltinValue::kSubgroupSize:
+            return "subgroup_size";
         case BuiltinValue::kVertexIndex:
             return "vertex_index";
         case BuiltinValue::kWorkgroupId:
diff --git a/src/tint/lang/core/builtin/builtin_value.h b/src/tint/lang/core/builtin/builtin_value.h
index ef527f3..96c91b0 100644
--- a/src/tint/lang/core/builtin/builtin_value.h
+++ b/src/tint/lang/core/builtin/builtin_value.h
@@ -41,6 +41,8 @@
     kPosition,
     kSampleIndex,
     kSampleMask,
+    kSubgroupInvocationId,
+    kSubgroupSize,
     kVertexIndex,
     kWorkgroupId,
 };
@@ -66,8 +68,8 @@
     "__point_size",           "frag_depth",     "front_facing",
     "global_invocation_id",   "instance_index", "local_invocation_id",
     "local_invocation_index", "num_workgroups", "position",
-    "sample_index",           "sample_mask",    "vertex_index",
-    "workgroup_id",
+    "sample_index",           "sample_mask",    "subgroup_invocation_id",
+    "subgroup_size",          "vertex_index",   "workgroup_id",
 };
 
 }  // namespace tint::builtin
diff --git a/src/tint/lang/core/builtin/builtin_value_bench.cc b/src/tint/lang/core/builtin/builtin_value_bench.cc
index 35f68fd..f7b8d3f 100644
--- a/src/tint/lang/core/builtin/builtin_value_bench.cc
+++ b/src/tint/lang/core/builtin/builtin_value_bench.cc
@@ -108,20 +108,34 @@
         "33amOe_mas66",
         "samoott6QQmask",
         "66mple_mask",
-        "verzzx_in6Oxx",
-        "vertex_yyndex",
-        "vetxHHZnZex",
+        "subroup_invoOaxion_i6zz",
+        "subgroup_inyyocation_id",
+        "subgrup_invcatiZHH_id",
+        "subgroup_invocation_id",
+        "subgroqp_inWWoat44on_id",
+        "subgrou_inOOocation_id",
+        "suhgrup_invoYation_id",
+        "subroup_si",
+        "suFgoup_size",
+        "subgowp_size",
+        "subgroup_size",
+        "suffgKup_sie",
+        "KKubgroqp_size",
+        "subFroup3mmize",
+        "ertex_index",
+        "verteq_inex",
+        "verbx_indbbx",
         "vertex_index",
-        "vWWteq_in44ex",
-        "vrtex_OOndex",
-        "hrteYooindx",
-        "wogroup_i",
-        "wokgrouF_id",
-        "worgrwup_id",
+        "iertex_indx",
+        "veOOtexqidex",
+        "vertexvvindTTx",
+        "workFFroup_id",
+        "workgPfpQ00d",
+        "woPkgroup_id",
         "workgroup_id",
-        "workGKou_if",
-        "worKKgrouq_id",
-        "w3rkgrommp_id",
+        "wosskgrup_i77",
+        "workgroup_bbRC",
+        "workgroup_iXX",
     };
     for (auto _ : state) {
         for (auto* str : kStrings) {
diff --git a/src/tint/lang/core/builtin/builtin_value_test.cc b/src/tint/lang/core/builtin/builtin_value_test.cc
index dc2c26f..ca74e72 100644
--- a/src/tint/lang/core/builtin/builtin_value_test.cc
+++ b/src/tint/lang/core/builtin/builtin_value_test.cc
@@ -54,6 +54,8 @@
     {"position", BuiltinValue::kPosition},
     {"sample_index", BuiltinValue::kSampleIndex},
     {"sample_mask", BuiltinValue::kSampleMask},
+    {"subgroup_invocation_id", BuiltinValue::kSubgroupInvocationId},
+    {"subgroup_size", BuiltinValue::kSubgroupSize},
     {"vertex_index", BuiltinValue::kVertexIndex},
     {"workgroup_id", BuiltinValue::kWorkgroupId},
 };
@@ -92,12 +94,18 @@
     {"sample_XXask", BuiltinValue::kUndefined},
     {"samII99l55_mask", BuiltinValue::kUndefined},
     {"samaale_SSrHHYk", BuiltinValue::kUndefined},
-    {"verkkeH_de", BuiltinValue::kUndefined},
-    {"verRg_injex", BuiltinValue::kUndefined},
-    {"vrtexinbex", BuiltinValue::kUndefined},
-    {"workjroup_id", BuiltinValue::kUndefined},
-    {"wrkgroup_id", BuiltinValue::kUndefined},
-    {"qorkgro_id", BuiltinValue::kUndefined},
+    {"skkgroup_Hnvocatio_d", BuiltinValue::kUndefined},
+    {"gRbgroup_invocajionid", BuiltinValue::kUndefined},
+    {"sbgroup_nbocation_id", BuiltinValue::kUndefined},
+    {"subgroupjsize", BuiltinValue::kUndefined},
+    {"subgroup_sie", BuiltinValue::kUndefined},
+    {"sgroupqsize", BuiltinValue::kUndefined},
+    {"vertx_NNndex", BuiltinValue::kUndefined},
+    {"vvertex_dex", BuiltinValue::kUndefined},
+    {"ertex_inQQex", BuiltinValue::kUndefined},
+    {"wrkgrup_irf", BuiltinValue::kUndefined},
+    {"workgroup_jd", BuiltinValue::kUndefined},
+    {"w82wNNgrou_id", BuiltinValue::kUndefined},
 };
 
 using BuiltinValueParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index 1457e51..a147279 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -4005,6 +4005,12 @@
             return SpvBuiltInSampleId;
         case builtin::BuiltinValue::kSampleMask:
             return SpvBuiltInSampleMask;
+        case builtin::BuiltinValue::kSubgroupInvocationId:
+            module_.PushCapability(SpvCapabilityGroupNonUniform);
+            return SpvBuiltInSubgroupLocalInvocationId;
+        case builtin::BuiltinValue::kSubgroupSize:
+            module_.PushCapability(SpvCapabilityGroupNonUniform);
+            return SpvBuiltInSubgroupSize;
         case builtin::BuiltinValue::kUndefined:
             break;
     }
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index f500bae..ea54789 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -232,6 +232,12 @@
             return SpvBuiltInSampleId;
         case builtin::BuiltinValue::kSampleMask:
             return SpvBuiltInSampleMask;
+        case builtin::BuiltinValue::kSubgroupInvocationId:
+            module_.PushCapability(SpvCapabilityGroupNonUniform);
+            return SpvBuiltInSubgroupLocalInvocationId;
+        case builtin::BuiltinValue::kSubgroupSize:
+            module_.PushCapability(SpvCapabilityGroupNonUniform);
+            return SpvBuiltInSubgroupSize;
         case builtin::BuiltinValue::kVertexIndex:
             return SpvBuiltInVertexIndex;
         case builtin::BuiltinValue::kWorkgroupId:
diff --git a/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc b/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
index 4564d4b..e3036e5 100644
--- a/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
+++ b/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
@@ -46,7 +46,7 @@
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(12:34 error: unresolved builtin value 'positon'
 12:34 note: Did you mean 'position'?
-Possible values: 'frag_depth', 'front_facing', 'global_invocation_id', 'instance_index', 'local_invocation_id', 'local_invocation_index', 'num_workgroups', 'position', 'sample_index', 'sample_mask', 'vertex_index', 'workgroup_id')");
+Possible values: 'frag_depth', 'front_facing', 'global_invocation_id', 'instance_index', 'local_invocation_id', 'local_invocation_index', 'num_workgroups', 'position', 'sample_index', 'sample_mask', 'subgroup_invocation_id', 'subgroup_size', 'vertex_index', 'workgroup_id')");
 }
 
 TEST_F(ResolverUnresolvedIdentifierSuggestions, TexelFormat) {